2015-12-03 2 views
3

Я пытаюсь преобразовать следующий код C# в PowerShell (я не учитывал части кода, которые, как я считаю, не являются релевантными):«Невозможно преобразовать« System.__ ComObject »значение ...» в 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".

Добавлены подробности:

Я мог бы просто оставить из [TCatSysManagerLib.ITcSysManager] типа в коде PowerShell. Я столкнулся с такой же проблемой, однако в преобразовании этого 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 типа для того, чтобы получить доступ к DeclarationText собственности gvl_declaration.

C# код модифицируется из: http://infosys.beckhoff.com/english.php?content=../content/1033/tc3_automationinterface/108086391299624331.html&id=

Я новичок в обоих C# и PowerShell и модифицировали их из примеров. Любой совет будет принят во внимание.

ответ

0

Вот пара идей.

  1. При использовании классов COM, использующих сборку Primary Interop (PIA), рекомендуется, если таковая имеется. Есть один для VS. Я нашел его, посмотрев в реестре VisualStudio.DTE, затем найдя идентификатор GUID типа typelib и перейдя на ключ TypeLib, чтобы увидеть, что EnvDTE указан как PIA. В ретроспективе поисковик Google нашел бы это. Загрузите PIA с помощью [reflection.assembly]::loadwithpartialname("EnvDTE"). К сожалению, я не могу каким-либо образом создать объект через PIA. Однако вы можете получить доступ к переменной $ DTA в консоли VS powershell.
  2. Возможно, не обязательно, если вы используете # 1, но вы можете получить MethodInfo s для COM-класса, выполнив GetMethod на интерфейсе, а не на классе. Затем вы можете использовать .Invoke() против MethodInfo.
  3. Ознакомьтесь с документацией для EnvDTE и связанной с ней информацией.
  4. Также вы можете проверить «StudioShell».
+0

Благодарим за отзыв. К сожалению, я не знаком со многими этими условиями. Я думаю, мне нужно будет кое-что прочитать. – Patrick

+0

Если вы хотите немного упростить, я предлагаю: 1) решить, может ли ваше решение работать в VS. Если это возможно, вы можете использовать переменную $ DTA и, надеюсь, ваш существующий код wirjs без слишком большого количества модов. Возможно, вы захотите сделать это в любом случае, даже если ваше решение должно быть внешним по отношению к VS, просто чтобы продемонстрировать свой PS-скрипт. 2) решите, можете ли вы использовать такой инструмент, как StudioShell.Кстати, из того, что я могу сказать, typecasting в PS не работает так же, как в C#, поэтому я не уверен, что буду надеяться на то, что вы работаете, как хотите. 'MethodInfo' - это тип .NET: System.Reflection.MethodInfo. GetMethod - это метод System.Type –