从c#调用COM对象

时间:2014-02-07 16:55:17

标签: c# powershell

我目前使用Powershell调用以下com对象,但在将代码转换为c#时遇到问题。我知道这应该是非常简单的,可能是一个愚蠢的问题,所以如果我看起来像个白痴,我道歉。

Powershell的:

$nDeviceId=517
$wug = New-Object -ComObject CoreAsp.EventHelper
$wug.SendChangeEvent(2,$nDeviceId,1)

当前C#尝试:

Type type = TypeDelegator.GetTypeFromProgID("CoreAsp.EventHelper");
Object application = Activator.CreateInstance(type);
pplication.GetType().InvokeMember("SendChangeEvent", BindingFlags.InvokeMethod, null, application, new object[]{2,517,1});

我感谢任何帮助!

更新: 当我运行c#代码时,我没有收到任何错误。

3 个答案:

答案 0 :(得分:2)

如果你使用的是.NET 4,并且不介意后期绑定(没有intellisense,...),你可以使用动态对象:

Type type = Type.GetTypeFromProgID("CoreAsp.EventHelper");
dynamic application = Activator.CreateInstance(type);

application.SendChangeEvent(...);

答案 1 :(得分:1)

我不熟悉那个COM对象,但一般来说COM组件是通过在c#项目中添加它们作为参考来访问的(在add reference-dialog中选择com-tab)并使用这些类他们提供。

Best way to access COM objects from C#

答案 2 :(得分:0)

使用Frode的答案,我发现了一个名为CoreASP.dll的DLL并尝试将其导入我的项目,但收到了一个错误,即该库无效。

我能够使用visual studio中的“类型库导入程序”工具将COM类型库转换为等效的定义。

command: tlbimp.exe CoreAsp.dll\1

这创建了另一个DLL“CoreAspiLib.dll”,我可以将其导入到我的Visual Studio项目中。

感谢Frode带领我朝着正确的方向前进。

更新

所以这个方法有点可行,似乎我必须调用命令3-4次才能让它按预期工作。为了避免头痛,我最终从c#调用powershell,确保将运行空间保持打开状态,以便我不必为后续命令重新加载它(我可能每分钟调用此函数50次)。

调用脚本1000次的示例:

Runspace runspace = RunspaceFactory.CreateRunspace();

string scriptText = 
       "$wug = New-Object -ComObject CoreAsp.EventHelper;" +
       "$wug.SendChangeEvent(2,519,1)";

runspace.Open();
for (int x = 0; x < 1000; x++)
    {
            Console.WriteLine("Running Event "+(x+1).ToString());
            Pipeline pipeline = runspace.CreatePipeline();
            pipeline.Commands.AddScript(scriptText);
            pipeline.Commands.Add("Out-String");
            pipeline.Invoke();

            Thread.Sleep(1000);

     }

runspace.Close();

这似乎100%有效。

Joe我也尝试了你的方法并得到了与我的第一次测试相同的结果,没有错误,但函数没有按预期运行。