我想为我的应用程序文件类型添加自定义属性,就像微软的Word文件tyep .DOCX在Vista和视窗7,显示作者属性等试图做同样的我的应用程序,但对详细信息窗格性能没有线索呢。在.net2.0工作。我不知道我在做什么错了,
I wanted to add custom properties for my application file type, just like Microsoft Word file tyep .docx has properties on Details Pane in vista and window 7 that show author property and e.t.c trying to do the same for my application but have no clue yet. working in .net2.0 .i dont know what i am doing wrong,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices.ComTypes;
using Microsoft.Win32;
namespace TestShell
{
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("b7d14566-0509-4cce-a71f-0a554233bd9b")]
interface IInitializeWithFile
{
[PreserveSig]
int Initialize([MarshalAs(UnmanagedType.LPWStr)] string pszFilePath, uint grfMode);
}
[StructLayout(LayoutKind.Sequential)]
public struct PROPERTYKEY
{
public Guid fmtid;
public UIntPtr pid;
}
[ComImport]
[Guid("c8e2d566-186e-4d49-bf41-6909ead56acc")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IPropertyStoreCapabilities
{
[PreserveSig]
int IsPropertyWritable([In] ref PROPERTYKEY key);
}
[ComImport]
[Guid("886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IPropertyStore
{
[PreserveSig]
int GetCount([Out] out uint cProps);
[PreserveSig]
int GetAt([In] uint iProp, out PROPERTYKEY pkey);
[PreserveSig]
int GetValue([In] ref PROPERTYKEY key, out PropVariant pv);
[PreserveSig]
int SetValue([In] ref PROPERTYKEY key, [In] ref object pv);
[PreserveSig]
int Commit();
}
[StructLayout(LayoutKind.Sequential)]
public struct PropVariant
{
public short variantType;
public short Reserved1, Reserved2, Reserved3;
public IntPtr pointerValue;
}
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("TestShell.PropertyHandler")]
[Guid("9BC59AF4-41E3-49B1-9A62-17F4C92D081F")]
public class PropertyHandler : IInitializeWithFile, IPropertyStore, IPropertyStoreCapabilities
{
private const int S_OK = 0, S_FALSE = 1;
private string path = null;
public int Initialize(string pszFilePath, uint grfMode)
{
System.Windows.Forms.MessageBox.Show(pszFilePath);
path = pszFilePath;
return S_OK;
}
public int IsPropertyWritable(ref PROPERTYKEY key)
{
System.Windows.Forms.MessageBox.Show("Writable");
return S_OK;
}
public int GetCount(out uint cProps)
{
System.Windows.Forms.MessageBox.Show("GetCount");
cProps = 1;
return S_OK;
}
public int GetAt(uint iProp, out PROPERTYKEY pkey)
{
System.Windows.Forms.MessageBox.Show(iProp.ToString());
pkey = new PROPERTYKEY();
pkey.fmtid = PKEY_Title;
pkey.pid = (UIntPtr)0x2;
return S_OK;
}
private Guid PKEY_Title = new Guid("F29F85E0-4FF9-1068-AB91-08002B27B3D9");
public int GetValue(ref PROPERTYKEY key, out PropVariant pv)
{
System.Windows.Forms.MessageBox.Show(key.fmtid.ToString());
pv = new PropVariant();
if (key.fmtid == PKEY_Title) {
pv.variantType = 31;
pv.pointerValue = Marshal.StringToHGlobalUni("Test");
return S_OK;
} else {
pv.variantType = 0; //VT_EMPTY
pv.pointerValue = IntPtr.Zero;
return S_OK;
}
}
public int SetValue(ref PROPERTYKEY key, ref object pv)
{
return S_OK;
}
public int Commit()
{
return S_OK;
}
[ComRegisterFunctionAttribute]
public static void RegisterFunction(Type t)
{
try {
RegistryKey regHKCR = Registry.ClassesRoot;
regHKCR = regHKCR.CreateSubKey(".test");
regHKCR.SetValue(null, "TestShell.PropertyHandler");
regHKCR = Registry.ClassesRoot;
regHKCR = regHKCR.CreateSubKey("CLSID\\{9BC59AF4-41E3-49B1-9A62-17F4C92D081F}");
regHKCR.SetValue(null, "Test Property");
regHKCR.SetValue("ManualSafeSave", 1);
regHKCR = regHKCR.CreateSubKey("InProcServer32");
regHKCR.SetValue(null, System.Reflection.Assembly.GetExecutingAssembly().Location);
regHKCR.SetValue("ThreadingModel", "Apartment");
RegistryKey regHKLM;
regHKLM = Registry.LocalMachine.CreateSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\PropertySystem\\PropertyHandlers\\.test");
regHKLM.SetValue(null, "{9BC59AF4-41E3-49B1-9A62-17F4C92D081F}");
regHKLM = Registry.LocalMachine.CreateSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved");
regHKLM.SetValue("{9BC59AF4-41E3-49B1-9A62-17F4C92D081F}", "Test Property");
} catch (Exception ex) {
#if DEBUG
System.Windows.Forms.MessageBox.Show(ex.Message + System.Environment.NewLine + ex.StackTrace);
#endif
}
#if DEBUG
//SHShellRestart();
#endif
}
[ComUnregisterFunctionAttribute]
public static void UnRegisterFunction(Type t)
{
try {
RegistryKey regHKCR = Registry.ClassesRoot;
regHKCR.DeleteSubKey(".test");
regHKCR.DeleteSubKeyTree("CLSID\\{9BC59AF4-41E3-49B1-9A62-17F4C92D081F}");
RegistryKey regHKLM = Registry.LocalMachine;
regHKLM.DeleteSubKeyTree("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\PropertySystem\\PropertyHandlers\\.test");
regHKLM = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved", true);
regHKLM.DeleteValue("{9BC59AF4-41E3-49B1-9A62-17F4C92D081F}");
} catch (Exception ex) {
#if DEBUG
System.Windows.Forms.MessageBox.Show(ex.Message + System.Environment.NewLine + ex.StackTrace);
#endif
}
#if DEBUG
//SHShellRestart();
#endif
}
#if DEBUG
[DllImport("user32.dll")]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
[DllImport("shell32.dll")]
static extern IntPtr ShellExecute(
IntPtr hwnd, string lpOperation, string lpFile,
string lpParameters, string lpDirectory, int nShowCmd);
private static void SHShellRestart()
{
PostMessage(FindWindow("Progman", null), 0x0012, IntPtr.Zero, IntPtr.Zero);
ShellExecute(IntPtr.Zero, null, "explorer.exe", null, null, 5);
return;
}
#endif
}
}
我需要instatiate的PROPERT处理程序类了。如果是比我应该怎么做,任何想法的人,我一直在这里停留了3天了。 当我注册这个DLL的财产处理程序被注册,但没有自定义属性出现在.TEST文件。
do i need to instatiate the propert handler class too. if yes than how should i do it, any ideas someone, i have been stuck here for 3 days now. when i register this dll the property handler gets registered but no custom property appears on the .test file.
我已成功地登记自己的财产处理程序,COM和探险家在呼唤我的code当我点击文件tyep(.TEST)对whcih我是想自定义添加属性。下面是code,现在唯一剩下的事情就是以某种方式创造新的属性,我不知道如何创建新的属性,任何帮助是pciated AP $ P $
i have managed to register my property handler as COM and explorer is calling my code when i click on file tyep (.test) against whcih i am trying to custom add properties. Below is the code, now the only thing left is to somehow create new properties, i have no idea how to create new properties, any help is appreciated
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices.ComTypes;
using Microsoft.Win32;
using System.Windows.Forms;
namespace TestShell
{
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("b7d14566-0509-4cce-a71f-0a554233bd9b")]
interface IInitializeWithFile
{
[PreserveSig]
int Initialize([MarshalAs(UnmanagedType.LPWStr)] string pszFilePath, uint grfMode);
}
[StructLayout(LayoutKind.Sequential)]
public struct PROPERTYKEY
{
public Guid fmtid;
public UIntPtr pid;
}
[ComImport]
[Guid("c8e2d566-186e-4d49-bf41-6909ead56acc")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IPropertyStoreCapabilities
{
[PreserveSig]
int IsPropertyWritable([In] ref PROPERTYKEY key);
}
[ComImport]
[Guid("886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IPropertyStore
{
[PreserveSig]
int GetCount([Out] out uint cProps);
[PreserveSig]
int GetAt([In] uint iProp, out PROPERTYKEY pkey);
[PreserveSig]
int GetValue([In] ref PROPERTYKEY key, out PropVariant pv);
[PreserveSig]
int SetValue([In] ref PROPERTYKEY key, [In] ref object pv);
[PreserveSig]
int Commit();
}
[StructLayout(LayoutKind.Sequential)]
public struct PropVariant
{
public short variantType;
public short Reserved1, Reserved2, Reserved3;
public IntPtr pointerValue;
}
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("TestShell.PropertyHandler")]
[Guid("9BC59AF4-41E3-49B1-9A62-17F4C92D081F")]
public class PropertyHandler : IInitializeWithFile, IPropertyStore, IPropertyStoreCapabilities
{
private const int S_OK = 0, S_FALSE = 1;
private string path = null;
public int Initialize(string pszFilePath, uint grfMode)
{
//System.Windows.Forms.MessageBox.Show(pszFilePath);
path = pszFilePath;
return S_OK;
}
public int IsPropertyWritable(ref PROPERTYKEY key)
{
//System.Windows.Forms.MessageBox.Show("Writable");
return S_OK;
}
public int GetCount(out uint cProps)
{
//System.Windows.Forms.MessageBox.Show("GetCount");
cProps = 1;
return S_OK;
}
public int GetAt(uint iProp, out PROPERTYKEY pkey)
{
System.Windows.Forms.MessageBox.Show(iProp.ToString());
pkey = new PROPERTYKEY();
pkey.fmtid = PKEY_Title;
pkey.pid = (UIntPtr)0x2;
return S_OK;
}
private Guid PKEY_Title = new Guid("F29F85E0-4FF9-1068-AB91-08002B27B3D9");
public int GetValue(ref PROPERTYKEY key, out PropVariant pv)
{
System.Windows.Forms.MessageBox.Show(key.fmtid.ToString());
pv = new PropVariant();
if (key.fmtid == PKEY_Title)
{
pv.variantType = 31;
pv.pointerValue = Marshal.StringToHGlobalUni("Test");
return S_OK;
}
else
{
pv.variantType = 0; //VT_EMPTY
pv.pointerValue = IntPtr.Zero;
return S_OK;
}
}
public int SetValue(ref PROPERTYKEY key, ref object pv)
{
return S_OK;
}
public int Commit()
{
return S_OK;
}
[ComRegisterFunctionAttribute]
public static void RegisterFunction(Type t)
{
try
{
RegistryKey regHKCR = Registry.ClassesRoot;
regHKCR = regHKCR.CreateSubKey(".test");
regHKCR.SetValue(null, "TestShell.PropertyHandler");
regHKCR = Registry.ClassesRoot;
regHKCR = regHKCR.CreateSubKey("CLSID\\{9BC59AF4-41E3-49B1-9A62-17F4C92D081F}");
regHKCR.SetValue(null, "Test Property");
regHKCR.SetValue("ManualSafeSave", 1);
regHKCR.SetValue("Title", 2);
regHKCR.SetValue("Whatever", 3);
regHKCR = regHKCR.CreateSubKey("InProcServer32");
regHKCR.SetValue(null, @"C:\Windows\System32\mscoree.dll");
//regHKCR.SetValue(null, System.Reflection.Assembly.GetExecutingAssembly().Location);
regHKCR.SetValue("ThreadingModel", "Apartment");
RegistryKey regHKLM;
regHKLM = Registry.LocalMachine.CreateSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\PropertySystem\\PropertyHandlers\\.test");
regHKLM.SetValue(null, "{9BC59AF4-41E3-49B1-9A62-17F4C92D081F}");
regHKLM = Registry.LocalMachine.CreateSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved");
regHKLM.SetValue("{9BC59AF4-41E3-49B1-9A62-17F4C92D081F}", "Test Property");
//SHShellRestart();---------------------------------------------------------------------------------------------
// string propertyID = "VolumeName";
// //PROPSPEC propSpec = new PROPSPEC();
// //propSpec.ulKind = 0;
//// propSpec.__unnamed.lpwstr = (char*)Marshal.StringToCoTaskMemUni(propertyID);
// PropVariant propVar = new PropVariant();
// propVar.__unnamed.__unnamed.__unnamed.bstrVal = (char*)Marshal.StringToCoTaskMemUni(value);
// //delcare un safe variables
// PROPSPEC[] rgSpecs = new PROPSPEC[1];
// rgSpecs[0] = propSpec;
// PROPVARIANT[] rgVar = new PROPVARIANT[1];
// rgVar[0] = propVar;
// object val = value;
// ppPropStg.WriteMultiple(1, ref propSpec, ref val, 3);
// ppPropStg.Commit(0x8);
// fDataDiscWriter.SetJolietProperties(ppPropStg);
}
catch (Exception ex)//HKEY_CLASSES_ROOT\CLSID\{9BC59AF4-41E3-49B1-9A62-17F4C92D081F}\Implemented Categories\{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}
{
#if DEBUG
System.Windows.Forms.MessageBox.Show(ex.Message + System.Environment.NewLine + ex.StackTrace);
#endif
}
#if DEBUG
//SHShellRestart();
#endif
}
[ComUnregisterFunctionAttribute]
public static void UnRegisterFunction(Type t)
{
try
{
RegistryKey regHKCR = Registry.ClassesRoot;
regHKCR.DeleteSubKey(".test");
regHKCR.DeleteSubKeyTree("CLSID\\{9BC59AF4-41E3-49B1-9A62-17F4C92D081F}");
RegistryKey regHKLM = Registry.LocalMachine;
regHKLM.DeleteSubKeyTree("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\PropertySystem\\PropertyHandlers\\.test");
regHKLM = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved", true);
regHKLM.DeleteValue("{9BC59AF4-41E3-49B1-9A62-17F4C92D081F}");
}
catch (Exception ex)
{
#if DEBUG
System.Windows.Forms.MessageBox.Show(ex.Message + System.Environment.NewLine + ex.StackTrace);
#endif
}
#if DEBUG
//SHShellRestart();
#endif
}
//#if DEBUG
[DllImport("user32.dll")]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
[DllImport("shell32.dll")]
static extern IntPtr ShellExecute(
IntPtr hwnd, string lpOperation, string lpFile,
string lpParameters, string lpDirectory, int nShowCmd);
private static void SHShellRestart()
{
PostMessage(FindWindow("Progman", null), 0x0012, IntPtr.Zero, IntPtr.Zero);
ShellExecute(IntPtr.Zero, null, "explorer.exe", null, null, 5);
return;
}
//#endif
}
}
他的code是preTY多从MSDN路段D,除了有一个在code堂妹的事件处理程序没有被注册,在InProc32注册表全部键的值应该是路径的错误到MSCorEE.dll中,当我补充说,应用程序开始工作。
his code is prety much from msdn link d except there was a mistake in the code coz of which the handler was not being register, In the InProc32 registy key the value should be the path to mscoree.dll, when i added that the application started working.
我知道这么多的自定义属性将采用两种方式来添加。只是一个猜测 1 - IPropertyStrore.SetValue 2 - 添加注册表项条目F29F85E0-4FF9-1068-AB91-08002B27B3D9关键注册表
I know this much the custom properties will be added using 2 ways. just a guess 1 - IPropertyStrore.SetValue 2 - Adding registry key entries to F29F85E0-4FF9-1068-AB91-08002B27B3D9 key in registry