如果我的术语已经关闭,请原谅我,因为这对我来说是一个未知的领域。
我有一个需要创建FolderShortcut
的程序。 Microsoft has documentation关于如何在C ++中创建它,我正在尝试将方向转换为C#。说明指出需要使用CoCreateInstance
作为参数调用CLSID_FolderShortcut
函数,我推断这意味着它正在实例化COM对象。此对象的CLSID为{0AFACED1-E828-11D1-9187-B532F1E9575D}
。
我已尝试在COM标签中添加对 Shell32.dll 的引用,但FolderShortcut
对象未显示在Intellisense中(可能它不在typelib中?)。我还想过做DLLImport
,但是,当然,这只能让我访问函数,而不是对象。
在.Net中访问此对象需要做什么?
答案 0 :(得分:7)
如果你不想在编译期间导入类,正如 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.IPersistFile
,这会导致对COM对象调用QueryInterface
。使用此界面,您可以轻松访问IPersistFile
的成员。
您可以继续阅读here。
答案 1 :(得分:5)
这是一段允许您创建文件夹快捷方式的代码。 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);
}
答案 2 :(得分:1)
您是否尝试添加新参考:
答案 3 :(得分:0)
听起来您尝试使用“添加新的COM引用”添加COM。 这些是我试过的东西:
我首先要做的是确保您的COM DLL已在您的计算机中注册。如果没有,则注册它,然后尝试使用COM选项卡再次添加它。
你在64位机器上运行吗?尝试确保将项目属性设置为AnyCPU,以便能够读取32位COM。
确保您具有您尝试访问的DLL的互操作等效项。它通常命名为“Interop.YourDLLName.dll”。添加对该DLL的引用,这应该有用。