【问题标题】:'Cannot convert the "System.__ComObject" value ...' error in PowerShellPowerShell 中的“无法转换“System.__ComObject”值...”错误
【发布时间】:2016-03-07 11:30:48
【问题描述】:

我正在尝试将以下 C# 代码转换为 PowerShell(我忽略了我认为不相关的代码部分):

C#

System.Type t = System.Type.GetTypeFromProgID("VisualStudio.DTE.10.0", true);
object obj = System.Activator.CreateInstance(t, true);
EnvDTE80.DTE2 dte = (EnvDTE80.DTE2)obj;

dte.MainWindow.Activate();

dynamic solution = dte.Solution;
solution.Create(solution_folder_path, solution_name);
solution.SaveAs(solution_file_path);

dynamic project = solution.AddFromTemplate(template_path, project_folder_path, project_name);

TCatSysManagerLib.ITcSysManager system_manager = project.Object;

PowerShell

[System.Reflection.Assembly]::LoadFrom("C:\Windows\assembly\GAC_MSIL\TCatSysManagerLib\2.1.0.0__180016cd49e5e8c3\TCatSysManagerLib.dll");

$dte = New-Object -ComObject VisualStudio.DTE.10.0

$dte.SuppressUI = $false
$dte.MainWindow | %{$_.GetType().InvokeMember("Visible", "SetProperty", $null, $_, $true)}

$solution = $dte.Solution

$project = $solution.AddFromTemplate($template_path, $project_folder_path, $project_name)

[TCatSysManagerLib.ITcSysManager] $system_manager = [TCatSysManagerLib.ITcSysManager] $project.Object

我遇到的问题是 PowerShell 中的最后一行返回了以下形式的错误:

无法转换类型的“System.__ComObject”值 “System.__ComObject#{3b56a5ce-0c02-440b-8ced-f1f3e83f66ed}”键入 "TCatSysManagerLib.ITcSysManager"。

添加细节:

我可以在 PowerShell 代码中省略 [TCatSysManagerLib.ITcSysManager] 类型。我在稍后转换此 C# 代码时遇到了同样的问题:

TCatSysManagerLib.ITcSmTreeItem gvl = system_manager.LookupTreeItem("TIPC^PLC1^PLC1 Project^GVLs^GVL");
TCatSysManagerLib.ITcPlcDeclaration gvl_declaration = (TCatSysManagerLib.ITcPlcDeclaration)gvl;
string gvl_declaration_text = System.IO.File.ReadAllText(gvl_declaration_text_file_path);
gvl_declaration.DeclarationText = gvl_declaration_text;

在这种情况下,我必须强制转换为TCatSysManagerLib.ITcPlcDeclaration 类型才能访问gvl_declarationDeclarationText 属性。

C#代码修改自:http://infosys.beckhoff.com/english.php?content=../content/1033/tc3_automationinterface/108086391299624331.html&id=

我是 C# 和 PowerShell 的新手,并且已经从示例中修改了这些内容。任何建议将不胜感激。

【问题讨论】:

标签: c# powershell com


【解决方案1】:

这里有几个想法。

  1. 在使用 COM 类时,建议使用主互操作程序集 (PIA)(如果可用)。 VS有一个。我通过在注册表中查找VisualStudio.DTE 找到它,然后找到typelib GUID,然后转到TypeLib 键以查看EnvDTE 被列为PIA。回想起来,谷歌搜索也会找到它。使用[reflection.assembly]::loadwithpartialname("EnvDTE") 加载PIA。不幸的是,我无法通过 PIA 实例化对象。不过,您可以在 VS Powershell 控制台中访问 $DTA 变量。
  2. 如果您使用#1,可能没有必要,但您可以通过在接口而不是类上执行GetMethod 来为COM coclass 获得MethodInfos。然后,您可以对 MethodInfo 使用 .Invoke()。
  3. 查看EnvDTE 及相关文档。
  4. 您可能还想查看“StudioShell”。

【讨论】:

  • 感谢您的回复。不幸的是,我对这些术语中的很多都不熟悉。我想我将不得不做一些背景阅读。
  • 如果你想稍微简化一下,我建议:1)确定你的解决方案是否可以在VS中运行。如果可以,那么您可以使用 $DTA 变量,并希望您现有的代码 wirjs 没有太多的 mods。无论如何,您可能都想这样做,即使您的解决方案必须在 VS 之外,只是为了证明您的 PS 脚本。 2) 决定是否可以使用 StudioShell 之类的工具。顺便说一句,据我所知,PS 中的类型转换与 C# 中的工作方式不同,所以我不确定我是否希望演员能够像你想要的那样工作。 MethodInfo 是 .NET 类型:System.Reflection.MethodInfo。 GetMethod 是一个 System.Type 方法
猜你喜欢
  • 2016-02-02
  • 1970-01-01
  • 1970-01-01
  • 2018-06-20
  • 1970-01-01
  • 2018-06-05
  • 2018-08-08
  • 1970-01-01
相关资源
最近更新 更多