-->

我该如何去有关CLSID实例在C#中的COM对象?(How do I go about instan

2019-08-17 15:14发布

原谅我,如果我的术语是关闭的,因为这对我来说是有些未知的领域。

我有一个计划,需要创建一个FolderShortcut 。 微软文档如何在C ++创建它,和我想要的方向C#翻译。 该说明中提到的CoCreateInstance功能需要被称为CLSID_FolderShortcut作为参数,这是我推断的意思,它的实例化一个COM对象。 此对象的CLSID是{0AFACED1-E828-11D1-9187-B532F1E9575D}

我试着将参照从COM选项卡SHELL32.DLL,FolderShortcut对象并不在IntelliSense(也许它不是在类型库?)出现。 我也想过做一个DLLImport ,但是,当然,只给我访问的功能,而不是对象。

我需要什么做的就是访问该对象在.net中?

Answer 1:

下面是一段代码,允许你创建一个文件夹的快捷方式。 所述的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);
}


Answer 2:

如果你不想在编译时导入类, 西门Mourier描述,也可以做一些后期绑定到COM对象,使用Activator

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

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

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

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

使用这种类型的,你现在能够创建组件类的一个实例,使用Activator.CreateInstance

var instance = Activator.CreateInstance(comType);

Basicly你现在可以使用调用方法Type.InvokeMember 。 这只有在对象实现了工作IDispatch接口。

然而,对于您的具体的例子,你应该能够实例转换为System.Runtime.InteropServices.ComTypes.IPersistFile ,这会导致一个调用QueryInterface为COM对象。 使用这个接口,您可以轻松地访问的成员IPersistFile

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



Answer 3:

你尝试添加一个新的参考:

  1. 打开资源管理器解决方案
  2. 展开C#项目
  3. 右键单击引用节点上,添加新的COM参考


Answer 4:

这听起来像你已经尝试添加使用“添加新的COM引用”你的COM。 这些是我想尝试的事情:

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

  2. 你是一个64位的机器上运行? 尝试也确保您的项目属性设置为AnyCPU为它能够读取32位COM。

  3. 请确保您有互操作相当于您试图访问该DLL的。 它通常被命名为如“Interop.YourDLLName.dll”。 添加一个引用到该DLL并应工作。



文章来源: How do I go about instantiating a COM Object in C# by CLSID?