【问题标题】:Calling COM object from c#从 C# 调用 COM 对象
【发布时间】:2014-03-05 04:53:01
【问题描述】:

我目前正在使用 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# 代码时,我没有收到任何错误。

【问题讨论】:

    标签: c# powershell


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      我不熟悉那个 COM 对象,但一般来说,COM 组件是通过在你的 c# 项目中添加它们作为引用来访问的(在添加引用对话框中选择 com 选项卡)并使用类他们提供。

      Best way to access COM objects from C#

      【讨论】:

      • 是的,我尝试这样做,但无法找到保存 COM 对象的 DLL。我可以在注册表中看到该对象,但它没有给出文件位置。
      【解决方案3】:

      根据 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,我也尝试了您的方法,结果与我的第一次测试相同,没有错误,但函数没有按预期运行。

      【讨论】:

        猜你喜欢
        • 2012-01-26
        • 1970-01-01
        • 2011-05-16
        • 2021-09-14
        • 2014-02-05
        • 2011-06-20
        • 1970-01-01
        • 1970-01-01
        • 2010-11-14
        相关资源
        最近更新 更多