2010-10-19 38 views
1

我想添加自定義屬性爲我的應用程序文件類型,就像.DOCX在Vista和視窗7中顯示作者在詳細信息窗格性能Microsoft Word文件tyep財產等試圖爲我的應用程序做同樣的事情,但還沒有線索。在.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 
    } 
} 

我是否需要instatiate屬性處理器類。如果是,我應該怎麼做,任何想法的人,我一直在這裏呆了3天。 當我註冊這個DLL屬性處理程序獲取註冊但沒有自定義屬性出現在.test文件。

+0

P.S:我從msdn論壇取得這段代碼,並在我的應用程序中執行,顯然沒有成功。 – PUG 2010-10-19 10:19:20

+0

嗯;這是一個非常具體的情況;你可以參考MSDN源碼嗎? – 2010-10-19 10:31:09

+0

msdn.microsoft.com/en-us/library/bb776861(VS.85).aspx,這篇文章我使用,我真的不知道很多關於這一點,我已經預覽處理程序,我的文件,但從來沒有財產處理 – PUG 2010-10-19 11:08:11

回答

2

我已成功地註冊我的財產處理程序,COM和探險家在呼喚我的代碼,當我在文件tyep(。測試)點擊針對whcih我試圖添加自定義屬性。下面是代碼,現在剩下的唯一的事情就是以某種方式創建新的屬性,我不知道如何創建新的屬性,任何幫助表示讚賞

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 
    } 
} 

他的代碼是prety多從MSDN鏈接d除了有在處理程序沒有被註冊的代碼因爲錯誤,InProc32註冊表項中的值應該是mscoree.dll的路徑,當我添加該應用程序開始工作。

我更知道這個自定義屬性將採用兩種方式來添加。只是猜測 1 - IPropertyStrore.SetValue 2 - 添加註冊表項條目F29F85E0-4FF9-1068-AB91-08002B27B3D9鍵在註冊表

0

你是否曾經看看​​?我不確定代碼包是否可以向文件類型添加屬性,但我知道它可以用於編輯現有屬性,因此可能值得一看。

+0

雅各布謝謝你的答案,是的,我會研究這個,但乍一看這個代碼包是win7我已經使用它的win7任務欄功能。我正在嘗試做的甚至是在Windows Vista中通過諸如MS WORD之類的所有程序完成,它顯示了諸如作者和docx文件頁面之類的自定義屬性。 – PUG 2010-10-27 05:35:58

1

至於雅各布提到,看看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和屬性ID定義System.AppUserModel.PreventPinning

相關問題