如何使用PowerShell将多个项目添加到解决方案中?(我一定是做错了什么根本性的事情)



我正在学习powershell,同时做这个(我认为会是)一个小而简单的任务。我真的不知道我哪里出错了,所以希望有人能给我指出正确的方向。我只是想添加一些项目到一个名为"All.sln"的解决方案。我有以下代码:

[string]$slnName = "All"
[string]$baseDir = "SOMEDIR_OF_PROJECTS"
[string]$slnPath = (Join-Path $baseDir 'All.sln')
$dteObj = New-Object -ComObject "VisualStudio.DTE.10.0"
$solution = $dteObj.Solution
$solution.Create($baseDir, $slnName)
Write-Output "Solution Path: " $slnPath    
(ls $baseDir -Recurse *.vbproj) | % { 
     Write-Output $_.FullName
     $solution = $dteObj.Solution
     $solution.AddFromFile($_.FullName, $false) 
     $solution.SaveAs( $slnPath ) 
 }
Write-Output ( $slnPath )
$dteObj.Solution.SaveAs( $slnPath ) 
$dteObj.Quit()

我一直得到各种不同的错误,所以我的想法是,我肯定在这里做错了什么,但它不是很明显,我做错了什么。

我有时会得到这个错误(通常在我试图添加的第一个项目文件上):

WARNING: System.Runtime.InteropServices.COMException (0x80010001): Call was rejected by callee. (Exception from HRESULT: 0x80
010001 (RPC_E_CALL_REJECTED))
   at System.Runtime.InteropServices.ComTypes.ITypeInfo.GetTypeAttr(IntPtr& ppTypeAttr)
   at System.Management.Automation.ComTypeInfo.GetTypeAttr(ITypeInfo typeinfo)
   at System.Management.Automation.ComTypeInfo.Initialize()
   at System.Management.Automation.ComTypeInfo.GetDispatchTypeInfo(Object comObject)
   at System.Management.Automation.PSObject.GetMappedAdapter(Object obj, TypeTable typeTable)
   at System.Management.Automation.PSObject.get_InternalAdapterSet()
   at System.Management.Automation.PSObject.get_InternalTypeNames()
   at System.Management.Automation.CmdletParameterBinderController.BindPipelineParametersPrivate(PSObject inputToOperateOn)
   at System.Management.Automation.CmdletParameterBinderController.BindPipelineParameters(PSObject inputToOperateOn)
   at System.Management.Automation.CommandProcessor.Read()
   at System.Management.Automation.CommandProcessor.ProcessRecord()
   at System.Management.Automation.CommandProcessorBase.DoExecute()
   at System.Management.Automation.EnumerableOps.WriteEnumerableToPipe(IEnumerator enumerator, Pipe pipe, ExecutionContext co
ntext, Boolean dispose)
   at System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid3[T0,T1,T2](CallSite site, T0 arg0, T1 arg1, T2 arg2)
   at System.Management.Automation.Interpreter.ActionCallInstruction`5.Invoke(Object arg0, Object arg1, Object arg2, Object a
rg3, Object arg4)
   at System.Management.Automation.Interpreter.CallInstruction.InvokeInstance(Object instance, Object[] args)
   at System.Management.Automation.Interpreter.DynamicInstructionN.Run(InterpretedFrame frame)
   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)

或者有时我得到(Null??):

You cannot call a method on a null-valued expression.
At C:DevHomeTFSVCoreScriptsBuildScriptsCreateMasterSolution.ps1:25 char:32
+                                $solution.AddFromFile($_.FullName)
+                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

或者有时我得到(MethodNotFound??):

Method invocation failed because [System.__ComObject] does not contain a method named 'SaveAs'.
At C:DevHomeVCoreVCoreScriptsBuildScriptsCreateMasterSolution.ps1:27 char:32
+                                $solution.SaveAs( $slnPath )
+                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (SaveAs:String) [], RuntimeException
    + FullyQualifiedErrorId : MethodNotFound

或者有时我得到(MethodNotFound??):

Method invocation failed because [System.__ComObject] does not contain a method named 'AddFromFile'.
At C:DevHomeTFSVCoreScriptsBuildScriptsCreateMasterSolution.ps1:18 char:32
+                                $solution.AddFromFile($_.FullName)
+                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (AddFromFile:String) [], RuntimeException
    + FullyQualifiedErrorId : MethodNotFound

或者有时我得到:

Call was rejected by callee. (Exception from HRESULT: 0x80010001 (RPC_E_CALL_REJECTED))
At C:DevHomeTFSVCoreScriptsBuildScriptsCreateMasterSolution.ps1:18 char:32
+                                $solution.AddFromFile($_.FullName)
+                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (:) [], COMException
    + FullyQualifiedErrorId : System.Runtime.InteropServices.COMException

在不了解更多关于VisualStudio和它的"解决方案"的情况下,我只给你一些一般的PowerShell建议:

  1. 永远不要假设你已经成功地获得了一个对象的句柄——你创建了你的$dteObj,但然后继续,假设实例化成功了。你需要在它周围加上一个try...catch,例如:

    try {
        $dteObj = New-Object -ComObject "VisualStudio.DTE.10.0";
        blah
        blah
    }
    catch [Exception] {
        error handling
    }
    
  2. 不要仅仅因为一个对象有一个属性,就认为它已经设置好了。我建议检查Solution属性是否为空,例如:

    if ( $dteObj.Solution -ne $null ) {
        do something
    } else {
        handle error state
    }
    
  3. 如果一段代码不会引发异常,使用if ($?) {}检查,例如:

    $solution.SaveAs( $slnPath );
    if ( ! $? ) {
        save failed
    } else {
        save ok
    }
    

最新更新