2013-03-04 12 views
9

Bir tohum (düşün EDMX dosyası veya DbContext) yapılandırmasına dayalı bir n katmanlı bir çözüm oluşturma işlemini otomatikleştirmek için PowerShell'i kullanmaya çalışıyorum. Ben bir iskelet çözümü açmak, aktif örneği almak ve proje dosyalarını otomatik olarak oluşturulmuş kod ile doldurmak istiyorum.DTE, PowerShell'de nasıl kullanılır?

Sağlanan örneğin here kodunu powershell'e dönüştürmeye çalışıyorum, ancak hata alıyorum. Ben DTE derlemeleri başvurmak için biraz işlevini yürütmek,

İlk:

Burada test ediyorum PowerShell kodudur.

$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 

Sonra ben [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 

veya çağrısının sonucunu başvurmak için bir nesne oluşturmak için deneyin:

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 

Son olarak, bu işe ya değildir:

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 

Yani, Benim sorum, DTE'yi PowerShell'den nasıl kullanıyorsunuz? Daha spesifik olarak, EnvDTE.DTE2 yazmak için GetActiveObject çağrısı sonucunu nasıl yaparsınız?

+0

NuGet'in [TypeWrapper] (http://nuget.codeplex.com/SourceControl/changeset/view/46278ab10d9a#src/VsConsole/PowerShellHost/Utils/TypeWrapper.cs) sınıfının da aynı sorun üzerinde çalıştığına inanıyorum. (** Dikkat: ** Outercurve Vakfı'nın sahip olduğu Apache lisanslı kod) – bricelam

+0

Bu harika bir öneridir ve bu kodu gözden geçirerek çok sayıda içgörü sağlanmıştır. Ancak, basit bir alternatif bulmuşum gibi görünüyor. Takip cevabımda göreceğiniz gibi, PowerShell işlemi biraz daha farklı bir şekilde ele alır, bu nedenle MSDN'de açıklandığı gibi yayınlama gerekmez. –

+0

VS'de paket yöneticisi konsolunu kullanıyorsanız, geçerli örneğin EnvDTE öğesi zaten "$ dte" değişkeni tarafından sağlanır. – StingyJack

cevap

13

Kısa bir süre için İMKB'deki fikirle oynayarak basit bir cevap buldum.

Temel olarak, GetActiveObject çağrısı, doğrudan PowerShell'de kullanılabilen bir COM nesnesi döndürür. LoadDTELibs'i çalıştırdıktan sonra, GetActiveObject öğesini arayarak bir DTE örneği alabilir ve ardından doğrudan sonuca başvurabilirsiniz.

Yani ... Sonra

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

: Ben PowerShell veya COM o kadar da iyi, ama sana düşünüyorum don bilmiyorum çünkü

PS> $dte.solution.Create("D:\Testing", "Acme.sln") 
PS> $dte.solution.SaveAs("D:\Testing\Acme.sln") 

ben% 100 emin değilim COM örneğini bırakma konusunda gerçekten endişelenmeliyim.

+0

[Bu] (http://www.computerperformance.co.uk/powershell/powershell_com.htm) makalesi, cevabı bulmakta yardımcı olan ipuçları sağladı. –

+0

"LoadDTELibs'i çalıştırdıktan sonra" - Bunu nasıl uyguladınız? – Rhyous