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

bsh*_*ett 3 c# com pinvoke shell32

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

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

我已尝试从COM选项卡添加对Shell32.dll的引用,但该FolderShortcut对象未显示在Intellisense中(可能它不在typelib中?).我也考虑过做一个DLLImport,但是,当然,这只能让我访问函数,而不是对象.

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

Car*_*ten 7

如果您不想在编译期间导入类,正如Simon Mourier所描述的那样,也可以使用对COM对象进行后期绑定Activator.

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

Type comType = Type.GetTypeFromProgID("MyProg.ProgId");
Run Code Online (Sandbox Code Playgroud)

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

Type comType = 
    Type.GetTypeFromCLSID(new Guid("0AFACED1-E828-11D1-9187-B532F1E9575D"));
Run Code Online (Sandbox Code Playgroud)

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

var instance = Activator.CreateInstance(comType);
Run Code Online (Sandbox Code Playgroud)

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

但是,对于您的特定示例,您应该能够将实例强制转换为System.Runtime.InteropServices.ComTypes.IPersistFile,从而调用QueryInterfaceCOM对象.使用此界面,您可以轻松访问成员IPersistFile.

您可以继续在这里进一步阅读.


Sim*_*ier 5

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

用法:

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

码:

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);
}
Run Code Online (Sandbox Code Playgroud)