2011-07-24 131 views
4

我正在开发需要发送快捷方式到桌面操作的应用程序。我发现只有一个实现它的方式:调用COM wituout COM互操作dll

var shell = new IWshRuntimeLibrary.WshShell(); 
var shortcut = (IWshRuntimeLibrary.IWshShortcut)shell.CreateShortcut(linkFileName); 
shortcut.TargetPath = Application.ExecutablePath; 
shortcut.WorkingDirectory = Application.StartupPath; 
shortcut.Save(); 

它的工作coreect,但需要Interop.IWshRuntimeLibrary.dll。 我的应用程序需要通过一个小的exe文件进行部署,我不能在包中包含任何其他文件。

是否在没有interop dll的情况下调用COM的方法?

回答

15

是的,你可以在没有互操作库的情况下在.NET中创建一个COM对象。只要他们的COM对象实现了IDispatch(其中WScript.Shell),您可以轻松地调用它的方法和属性。

如果您使用的是.NET 4,那么动态类型会非常简单。如果没有,你将不得不使用反射来调用这些方法,这些方法可以工作,但不是很好。

.NET 4与动态

Type shellType = Type.GetTypeFromProgID("WScript.Shell"); 
dynamic shell = Activator.CreateInstance(shellType); 
dynamic shortcut = shell.CreateShortcut(linkFileName); 
shortcut.TargetPath = Application.ExecutablePath; 
shortcut.WorkingDirectory = Application.StartupPath; 
shortcut.Save(); 

.NET 3.5或更低具有反射

Type shellType = Type.GetTypeFromProgID("WScript.Shell"); 
object shell = Activator.CreateInstance(shellType); 
object shortcut = shellType.InvokeMember("CreateShortcut", 
     BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod, 
     null, shell, new object[] { linkFileName }); 
Type shortcutType = shortcut.GetType(); 
shortcutType.InvokeMember("TargetPath", 
     BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetProperty, 
     null, shortcut, new object[] { Application.ExecutablePath }); 
shortcutType.InvokeMember("WorkingDirectory", 
     BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetProperty, 
     null, shortcut, new object[] { Application.StartupPath }); 
shortcutType.InvokeMember("Save", 
     BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod, 
     null, shortcut, null); 
+0

因以下错误而失败:80040154 –

+0

我使用的是DN 3.5,不能使用动态:( –

+0

它工作正常,谢谢。难以置信它太容易了! –

4

您可以使用名为ILMerge的Microsoft实用程序(可从here下载)将DLL合并到您的exe文件中。

有关于如何使用它this article

+0

这不是可接受的解决方案。我不相信这个工具。 –

+0

@Viacheslav你能否详细说明为什么ILMerge不适合你?它被认为是标准的.NET方法来完成你所要求的。 –

3

OK,既然ILMerge是unnaceptable出于某种原因的简要说明。

C#包含与底层COM和Windows DLL进行交互的能力。你可以在EXE中编写自己的COM互操作。

这里是an article描述你如何做到这一点。

+0

请将此添加到您的上一个答案的末尾。 –

+0

@John - 严肃的问题 - 为什么?我仔细考虑过这样做,并选择了一个单独的答案。这是解决问题的完全不同且独立的方法。 – iandotkelly

+0

我会考虑一下。当然,这取决于你。 –