如何使用DTE在PowerShell中?(How to use DTE in PowerShell?

2019-08-17 07:09发布

我试图使用PowerShell来自动创建基于种子的n层解决方案的过程中(想想EDMX文件或的DbContext)配置。 我希望能够打开一个骨架的解决方案,得到了积极的实例,并填充项目文件自动生成的代码。

我想转码所提供的例子这里到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的结果呢?

Answer 1:

我通过与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")

我不是100%肯定,因为我不知道的PowerShell或COM那么好,但我觉得你真的不担心释放COM实例。



Answer 2:

对于2017年VS是如下:

$dte = [System.Runtime.InteropServices.Marshal]::GetActiveObject("VisualStudio.DTE.15.0")


文章来源: How to use DTE in PowerShell?