Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为我的应用程序创建属性处理程序以将自定义属性添加到文件格式_C#_.net_Windows_Shell_Com - Fatal编程技术网

C# 为我的应用程序创建属性处理程序以将自定义属性添加到文件格式

C# 为我的应用程序创建属性处理程序以将自定义属性添加到文件格式,c#,.net,windows,shell,com,C#,.net,Windows,Shell,Com,我想为我的应用程序文件类型添加自定义属性,就像Microsoft Word file tyep.docx在vista和window 7的“详细信息”窗格中具有属性一样,其中显示author属性和e.t.c试图对我的应用程序执行相同操作,但目前还没有线索。在.net2.0中工作。我不知道我做错了什么 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.R

我想为我的应用程序文件类型添加自定义属性,就像Microsoft Word file tyep.docx在vista和window 7的“详细信息”窗格中具有属性一样,其中显示author属性和e.t.c试图对我的应用程序执行相同操作,但目前还没有线索。在.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
    }
}
我是否也需要安装propert处理程序类。如果是的话,我该怎么做呢?有人有什么想法吗?我已经在这里呆了三天了。
注册此dll时,将注册属性处理程序,但.test文件上没有显示自定义属性。

我已成功将属性处理程序注册为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项中

您查看了吗?我不确定代码包是否可以向文件类型添加属性,但我知道它可以用于编辑现有属性,因此值得一看。

备选方案:

如果我正确理解你的问题,可能就是你要找的


保存文件时,您可以在其上设置自定义属性。

如Jakob所述,请查看(旧链接已弃用)。 下面是一个使用它的简单代码段:

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定义的设置。

p.S:我从msdn论坛获取了这段代码,并在我的应用程序中实现,但显然没有成功。Hmm;这是一个非常具体的情景;你能参考MSDN的源代码吗?MSDN.microsoft.com/en us/library/bb776861(VS.85)。aspx,我正在使用的这篇文章,对此我真的不太了解,我已经为我的文件制作了预览处理程序,但就我理解你的问题而言,我从未制作过属性处理程序;您想在windows资源管理器中将具有此外壳属性处理程序的自定义属性添加到文件中,对吗?是的,我确实想要一个自定义属性,并且我已注册了一个COM组件fot,该组件在我的.net应用程序中实现了COM的所有接口,但不知道如何设置新属性Jakob感谢您的回答,是的,我将对此进行研究,但乍一看,此代码包是针对win7的,我已将其用于win7任务栏功能。我想做的是,在WindowsVista中,所有的程序,比如MS WORD,都能显示自定义属性,比如docx文件的作者和页面。