Creating a Visual Studio Solution using Powershell

I’ve been working on migrating a bunch of projects to .NET Core. Wanted to create a single solution with all of the projects added to it.

This is how you can do it.


I’m using a Windows 10 machine with Visual Studio 2017 installed.

Initialise

Create and initialise Visual Studio Development Tools Environment, set our solution path and create or open the existing solution.

$startLocation = $PSScriptRoot
$newLocation = "c:\source"

$sln = ($startLocation + "\MyAllProjectSolution.sln")
$dteObj = New-Object -ComObject "VisualStudio.DTE"
$sol = $dteObj.Solution;
if(-not (Test-Path $sln)){
	$sol.Create("MyAllProjectSolution.sln", "MyAllProjectSolution");
}else{
	$sol.Open($sln);
}

Find the projects, add the projects

In my use I had a directory ($newLocation) that had sub folders which had the projects in, I had to do some other operations which is why I get the children from $newLocation and then find in that, the csproj file.

get-childitem $newLocation  | Foreach-Object {
    $csproj = get-childitem ($_.FullName) | where {$_.extension -eq ".csproj"}
    $createSln = $TRUE
        $count = 0
    Do {
        Try {
            $sol.AddFromFile($csproj[0].FullName) | Out-Null
            $createSln = $FALSE
        }Catch {
            $e = $_.Exception
            $msg = $e.Message
            $msg | Write-Host
            "Solution generation failed, will retry" | Write-Host
            if($count -gt 10){
                $createSln = $FALSE
            }
            $count = $count+1
            Start-Sleep -m 30000
        }
    }While($createSln -eq $TRUE )
}

Exceptions.

You will notice that I have loop that will “retry” the call AddFromFile if an exception is thrown. I am not sure why, but it does throw an exception sometimes so I give the script the opportunity to retry the add method. Often if the first call fails, the second one succeeds.

The exception will look like this:

Call was rejected by callee. (Exception from HRESULT: 0x80010001 (RPC_E_CALL_REJECTED))

It doesn’t really explain why it was rejected and I cannot find where it will explain, but my guess is DTE or RPC is still busy.

Clean up

Now we save our solution and shut the DTE

$sol.SaveAs($sln);
$dteObj.Quit();

This is not by any means fast so don’t except to be able to add 50 projects in 50ms, it can take a few seconds per project.

Comments