我正在尝试使用PowerShell自动化基于种子(想想EDMX文件或DbContext)配置创建n层解决方案的过程。我希望能够打开骨架解决方案,获取活动实例,并使用自动生成的代码填充项目文件。
我试图将提供here的示例转码为powershell,但是,我收到了错误。
以下是我正在测试的PowerShell代码:
首先,我执行一个小函数来引用DTE程序集。
$libs = "envdte.dll", "envdte80.dll", "envdte90.dll", "envdte100.dll"
function LoadDTELibs {
param(
$path = "\Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies"
)
Process {
$libs |
ForEach {
$dll = Join-Path "$env:ProgramFiles\$path" $_
if(-not (Test-Path $dll)) {
$dll = Join-Path "${env:ProgramFiles(x86)}\$path" $_
}
Add-Type -Path $dll -PassThru | Where {$_.IsPublic -and $_.BaseType} | Sort Name
}
}
}
LoadDTELibs
然后,我尝试创建一个对象来引用调用[System.Runtime.InteropServices.Marshal]::GetActiveObject("VisualStudio.DTE.11.0")
PS> $dte = New-Object -ComObject EnvDTE80.DTE2
New-Object : Retrieving the COM class factory for component with CLSID {00000000-0000-0000-0000-000000000000} failed due to the following error: 80040154
Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)).
At line:1 char:8
+ $dte = New-Object -ComObject EnvDTE80.DTE2
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ResourceUnavailable: (:) [New-Object], COMException
+ FullyQualifiedErrorId : NoCOMClassIdentified,Microsoft.PowerShell.Commands.NewObjectCommand
或:
PS> $dte = New-Object EnvDTE80.DTE2
New-Object : Constructor not found. Cannot find an appropriate constructor for type EnvDTE80.DTE2.
At line:1 char:8
+ $dte = New-Object EnvDTE80.DTE2
+ ~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (:) [New-Object], PSArgumentException
+ FullyQualifiedErrorId : CannotFindAppropriateCtor,Microsoft.PowerShell.Commands.NewObjectCommand
最后,这也不起作用:
PS> [EnvDTE80.DTE2]$dte = [System.Runtime.InteropServices.Marshal]::GetActiveObject("VisualStudio.DTE.11.0")
Cannot convert the "System.__ComObject" value of type "System.__ComObject#{04a72314-32e9-48e2-9b87-a63603454f3e}" to type "EnvDTE80.DTE2".
At line:1 char:1
+ [EnvDTE80.DTE2]$dte = [System.Runtime.InteropServices.Marshal]::GetActiveObject( ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : MetadataError: (:) [], ArgumentTransformationMetadataException
+ FullyQualifiedErrorId : RuntimeException
所以,我的问题是,你如何使用PowerShell的DTE?更具体地说,如何将调用GetActiveObject的结果转换为输入EnvDTE.DTE2?
答案 0 :(得分:15)
我通过在ISE中玩这个想法找到了一个简单的答案。
基本上,对GetActiveObject的调用返回一个COM对象,可以直接在PowerShell中使用。执行LoadDTELibs后,您可以通过调用GetActiveObject获取DTE实例,然后直接引用结果。
因此...
PS> $dte = [System.Runtime.InteropServices.Marshal]::GetActiveObject("VisualStudio.DTE.11.0")
然后:
PS> $dte.solution.Create("D:\Testing", "Acme.sln")
PS> $dte.solution.SaveAs("D:\Testing\Acme.sln")
我不是百分百肯定,因为我不太了解PowerShell或COM,但我认为你不必担心发布COM实例。
答案 1 :(得分:1)
对于VS 2017,它如下:
$dte = [System.Runtime.InteropServices.Marshal]::GetActiveObject("VisualStudio.DTE.15.0")
答案 2 :(得分:1)
运行Visual Studio 2019,我已经能够使用VisualStudio.DTE COM接口启动调试器(无版本):
#Get the ProcessID from an AppPool's worker process:
[int] $ProcessId = ([xml] (& "$env:SystemRoot\system32\inetsrv\appcmd.exe" list wp /xml /apppool.name:"DefaultAppPool")).appcmd.WP."WP.NAME"
# Start the debugger, attached to that ProcessID
[Runtime.InteropServices.Marshal]::GetActiveObject('VisualStudio.DTE').Debugger.LocalProcesses |
? {$_.ProcessID -eq $ProcessId} | %{$_.Attach()}
以前必须指定版本。