如何通过CLSID在C#中实例化COM对象?

如果我的术语已经关闭,请原谅我,因为这对我来说是一个有点未知的领域。

我有一个程序需要创建FolderShortcut 。 Microsoft有关于如何使用C ++创建它的文档 ,我正在尝试将方向转换为C#。 指令声明需要使用CLSID_FolderShortcut作为参数调用CoCreateInstance函数,我推断它意味着它实例化COM对象。 该对象的CLSID是{0AFACED1-E828-11D1-9187-B532F1E9575D}

我尝试从COM选项卡添加对Shell32.dll的引用,但是FolderShortcut对象没有出现在Intellisense中(也许它不在typelib中?)。 我还想过做一个DLLImport ,但是,当然,这只能让我访问函数,而不是对象。

要在.Net中访问此对象,我需要做什么?

这是一段代码,允许您创建文件夹快捷方式。 CoCreateInstance可以(通常)通过声明一个用Guid属性修饰的简单类来替换,该类具有所需的CLSID和ComImport属性。 new调用将自动执行COM魔术。 使用此代码,您甚至不需要Shell32引用(或者如果您愿意,可以从那里重用IShellLink声明)。

用法:

 static void Main(string[] args) { CreateFolderShortcut(@"c:\temp", Path.GetFullPath("Shortcut to Temp")); } 

码:

 public static void CreateFolderShortcut(string path, string shortcutPath) { CreateFolderShortcut(path, shortcutPath, null); } public static void CreateFolderShortcut(string path, string shortcutPath, string comment) { if (path == null) throw new ArgumentNullException("path"); IShellLink link = (IShellLink)new ShellLinkFolder(); if (comment != null) { link.SetDescription(comment); } link.SetPath(path); IPersistFile file = (IPersistFile)link; file.Save(shortcutPath, false); } [ComImport] [Guid("00021401-0000-0000-C000-000000000046")] private class ShellLink { } [ComImport] [Guid("0AFACED1-E828-11D1-9187-B532F1E9575D")] private class ShellLinkFolder { } [ComImport] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] [Guid("000214F9-0000-0000-C000-000000000046")] private interface IShellLink { void GetPath([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, int cchMaxPath, out IntPtr pfd, int fFlags); void GetIDList(out IntPtr ppidl); void SetIDList(IntPtr pidl); void GetDescription([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszName, int cchMaxName); void SetDescription([MarshalAs(UnmanagedType.LPWStr)] string pszName); void GetWorkingDirectory([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir, int cchMaxPath); void SetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] string pszDir); void GetArguments([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs, int cchMaxPath); void SetArguments([MarshalAs(UnmanagedType.LPWStr)] string pszArgs); void GetHotkey(out short pwHotkey); void SetHotkey(short wHotkey); void GetShowCmd(out int piShowCmd); void SetShowCmd(int iShowCmd); void GetIconLocation([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszIconPath, int cchIconPath, out int piIcon); void SetIconLocation([MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, int iIcon); void SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] string pszPathRel, int dwReserved); void Resolve(IntPtr hwnd, int fFlags); void SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile); } 

如果你不想在编译期间导入类,正如Simon Mourier描述的那样,使用Activator也可以对COM对象做一些后期绑定。

如果你有对象的ProgID ,请使用类型

 Type comType = Type.GetTypeFromProgID("MyProg.ProgId"); 

否则你可以通过它的CLSID得到类型:

 Type comType = Type.GetTypeFromCLSID(new Guid("0AFACED1-E828-11D1-9187-B532F1E9575D")); 

使用此类型,您现在可以使用Activator.CreateInstance创建coclass的实例:

 var instance = Activator.CreateInstance(comType); 

基本上,您现在可以使用Type.InvokeMember调用方法。 这仅在对象实现IDispatch接口时有效。

但是,对于您的特定示例,您应该能够将实例System.Runtime.InteropServices.ComTypes.IPersistFileSystem.Runtime.InteropServices.ComTypes.IPersistFile ,这会导致对COM对象的QueryInterface的调用。 使用此界面,您可以轻松访问IPersistFile的成员。

您可以继续阅读。

您是否尝试添加新参考:

  1. Open Solution Explorer
  2. 展开C#项目
  3. 右键单击引用节点并添加新的COM引用

听起来你已尝试使用“添加新的COM引用”添加COM。 这些是我尝试过的东西:

  1. 我首先要做的是确保您的COM DLL已在您的计算机中注册。 如果没有,则注册它然后尝试使用COM选项卡再次添加它。

  2. 你在64位机器上运行吗? 尝试确保将项目属性设置为AnyCPU,以便能够读取32位COM。

  3. 确保您具有要尝试访问的DLL的互操作等效项。 它通常命名为“Interop.YourDLLName.dll”。 添加对该DLL的引用,这应该有效。