我想为我的应用程序文件类型添加自定义属性,就像Microsoft Word文件一样.docx在vista和窗口7中的Details Pane上有属性,显示作者属性等等,试图为我的应用程序执行相同操作但没有线索呢。在.net2.0工作。我不知道我做错了什么,
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
}
}
我是否也需要实例化属性处理程序类。如果是,我应该怎么做,任何想法有人,我已经被困在这里3天了。 当我注册这个DLL时,属性处理程序被注册,但.test文件中没有自定义属性。
答案 0 :(得分:2)
我已经设法注册我的属性处理程序作为COM和资源管理器调用我的代码时,我点击文件tyep(.test)对我想要自定义添加属性。下面是代码,现在唯一剩下的就是以某种方式创建新属性,我不知道如何创建新属性,任何帮助表示赞赏
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
}
}
他的代码很多来自msdn link d,除了代码处理器没有注册的错误,在InProc32注册表项中,值应该是mscoree.dll的路径,当我添加了应用程序开始工作。
我知道很多自定义属性将使用2种方式添加。只是一个猜测 1 - IPropertyStrore.SetValue 2 - 将注册表项条目添加到注册表中的F29F85E0-4FF9-1068-AB91-08002B27B3D9键
答案 1 :(得分:1)
正如Jakob所提到的,请查看Windows API Code Pack(旧链接已弃用)。 这是一个使用它的简单代码片段:
public static void PreventPinning(Window window)
{
var preventPinningProperty = new PropertyKey(new Guid("9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3"), 9);
WindowProperties.SetWindowProperty(window, preventPinningProperty, "1");
}
上面的示例是设置由其Guid和PropertyId定义的System.AppUserModel.PreventPinning。
答案 2 :(得分:0)
你看过Windows API Code Pack了吗?我不确定Code Pack是否可以向文件类型添加属性,但我知道它可以用于编辑现有属性,因此值得一看。
答案 3 :(得分:0)
替代:
如果我正确理解您的问题,this可能就是您要找的
How to set custom attributes / file properties on a file in C# .Net - by Rod Howarth
保存文件时,您只需在其上设置自定义属性即可。