How to upgrade a Visual Studio project from within a GitHub action? - visual-studio

A Visual Studio project can be upgraded from the command line using the devenv.exe command as follows:
devenv.exe SOLUTION_PATH /Upgrade
Where SOLUTION_PATH is a path to a Visual Studio solution (or project) file.
What is the most direct way to perform this step as part of a GitHub action?
What I Have Tried
So far I have failed to find a way to get devenv.exe into the path of the GitHub Action. There does not appear to be a prebuilt action step for this (setup-msbuild step does not make devenv available). Even hardcoding a path such as
MSDEVENV_PATH: ${{'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\devenv.com'}}
... then later ...
run: ${{env.MSDEVENV_PATH}} ${{env.SOLUTION_FILE_PATH}} /Upgrade
fails because the path contains spaces, and I can find no way to add quotation marks.
I am aware of a way to find devenv using powershell and extra downloadable packages however this will require writing a PowerShell script, and presumably signing it, and I have no idea whether this will even work in a GitHub Action. Perhaps there is a much simpler approach, hence my question: what is the most direct way to upgrade a solution?

You need a Windows-based runner. vswhere is the tool to get path to various components of the Visual Studio installation and its folder is in the path (source).
run: |
$devenv = & vswhere.exe '-property' productPath
Start-Process -FilePath $devenv -ArgumentList '${{env.SOLUTION_FILE_PATH}} /Upgrade' -Wait

Thanks to #riQQ's partial answer I currently have the following, which waits for the output to be done using both a pipe to Out-Null suggested in this answer and also waits for the generated files to appear. Note that I am using a path to the project not to the solution. (I could not get solution upgrading to work correctly, although I never worked out why.)
run: |
$devenv = & vswhere.exe '-property' productPath
Write-Output "$devenv"
& $devenv "${{env.VCPROJ_FILE_PATH}}" /Upgrade /NoSplash | Out-Null
Write-Output "devenv launched"
while (!(Test-Path "${{env.VCXPROJ_FILE_PATH}}")) { Start-Sleep -Seconds 10 }
Write-Output "vcxproj found"
while (!(Test-Path "${{env.VCXPROJ_FILTERS_FILE_PATH}}")) { Start-Sleep -Seconds 10 }
Write-Output "vcxproj.filters found"
Start-Sleep -Seconds 10
Write-Output "done."
For some reason this step is taking over 5 minutes to complete when run as part of a GitHub Action. It takes only a few seconds on my local machine. Because of the nasty file polling I don't consider this an ideal solution, but I am posting it here for reference.

Related

Delete files from Windows 2008 file explorer using PowerShell

I'd like to delete log files using a task scheduler from a 2008 Windows server that'll be run using a task scheduler. I've created my own and used online scripts but nothing has worked. After running the the script manually on the server a prompt appears that halts this process (which seems to be the issue). Below is a script that I've run on my pc that worked and the OS is Windows 1903 and it worked. The only discrepancy that I could this of is that the PowerShell versions are different. Could someone provide advice as to why is doesn't delete files on a Windows 2008 OS?
Skeleton Script:
Get-ChildItem –Path "C:\path\to\folder" -Recurse |
Where-Object {($_.LastWriteTime -lt
(Get-Date).AddDays(-60))} | Remove-Item
Aaron,
Change remove-item to remove-item -Confirm:$false -force It will stop asking you to confirm the deleting of files. – Aaron
This solved the issue.

How can I open a solution file from powershell?

I'm new to powershell and I'm looking to create a powershell script to open two different solution files with two different versions of visual studio. I have the commands for opening up the different visual studio versions, but not sure how to open the solutions with each one. Here is what I have so far.
$vs19 = "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\Common7\IDE\devenv.exe"
$vs19WorkDir = "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\Common7\IDE\"
$vs15 = "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\devenv.exe"
$vs15WorkDir = "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\"
Start-Process $vs19 -WorkingDirectory $vs19WorkDir
Start-Process $vs15 -WorkingDirectory $vs15WorkDir
Although not super obvious at first glance, the devenv command line reference mentions:
When specifying a solution or project, the first argument is the name of the solution file or project file, including file path.
With this in mind, I tried the following against Visual Studio 16 (2019):
& "path\to\devenv.exe" "path\to\a\solution.sln"
and it opened the solution in question, so you should be able to do it with:
Start-Process $vs19 -WorkingDirectory $vs19WorkDir -ArgumentList "c:\path\to\solution.sln"
I wrote a Powershell script to solve this problem. It was inspired by #Mathias R. Jessen's answer. You can find it on this Github gist
EDIT:
I shared the gist on Reddit as well and it turns out that there are much cooler and intuitive ways of achieving this on PowerShell. Check them out as well.
PS: `The fastest method I've seen so far is by typing *.sln, then hitting Tab and Enter

Installshield Silent Uninstall not working at Command Line

We have an older app from 2006 we'd like to uninstall at the command line using group policy, but I can't get a silent uninstall to work.
This works. Of course I need to click Next to uninstall:
"C:\App\Setup.exe" /uninst
But this does not. I see an hourglass for a couple seconds but the app is not uninstalled.
"C:\App\Setup.exe" /uninst /s
I also unsuccessfully tried some VBScripts. They find the app listed but the uninstall fails. I'm not too familiar with how this process is supposed to work.
You need to create first an ISS response file to silently remove your application,
Create response file :
C:\App\Setup.exe /r /f1c:\app\uninstall1.iss
you will be asked to uninstall, .... and perhaps reply the others windows.
Then your application would be uninstalled and you get a new response file c:\app\uninstall1.iss
Next, if you want to remove silently this application on another computer :
launch : C:\App\Setup.exe" /s /f1c:\app\uninstall1.iss
For more information see:
http://www.itninja.com/blog/view/installshield-setup-silent-installation-switches
Best Regards,
Stéphane
Try this, with the original setup.exe version that was used to install
"C:\App\Setup.exe" /x /s /v/qn
I've been struggling with the silent uninstaller for a while, and finally came to a solution that works for me in most cases, both for InstallShield v6 and v7.
1. First (as it was mentioned above), you have to generate an InstallShield Response file (e.g. uninstall.iss). In order to do that you have to launch your setup.exe with parameters:
> setup.exe -x -r -f1"C:\Your\Installer\Location\uninstall.iss"
This will go through the normal uninstall wizard and generate a Response file for you: uninstall.iss
2. Then, before trying your silent uninstaller, I guess, you should re-install the software.
3. And finally, run your silent uninstaller playing back the recently generated Response file:
> setup.exe -x -s -l0x9 -ARP -f1"C:\Your\Installer\Location\uninstall.iss"
That's it.
Now, a few important notes:
Note 1: I'm working with a 3-rd party installation package that I didn't build myself.
Note 2: I use dashes (-) instead of slashes (/) to define parameters. For some reason it doesn't work with slashes for me. Weird but true.
Note 3: The -ARP and -l switches are required for some installation packages to manage the software removal from the Add/Remove Programs list and to preset the default input language accordingly.
Successful silent uninstallation is all about the correct parameters!
So keep exploring, the correct parameters vary depending on a specific package and installer version.
I hope my input was helpful.
Try
Format: Setup.exe M{Your Product GUID} /s /f1[Full path]\*.iss for creating the ISS file for uninstallation.
From Stephanie's sample, I think it's missing the GUID.
There's a good link at the developer's site # Creating the Response File.
Try it out n tell us,
Tommy Kwee
I struggled with this for a long time so posting it here in case anybody else stumbles upon it.
If you happen to have an installer which uses the legacy Package-For-The-Web format then you need to use the parameter -a to pass additional parameters to the extracted setup file.
Record (un)installation files (click through the installer manually):
.\DWG2PDF2019.exe -a /r /f1"c:\app\dwg2019_install.iss"
.\DWG2PDF2019.exe -a /r /f1"c:\app\dwg2019_uninstall.iss"
Silently (un)install:
.\DWG2PDF2019.exe -s -a /s /f1"c:\app\dwg2019_install.iss"
.\DWG2PDF2019.exe -s -a /s /f1"c:\app\dwg2019_uninstall.iss"
Source: https://help.hcltechsw.com/caa/3.0/topics/appacc_silent_install_t.html
There's another way to uninstall an app by searching for it in the Registry, and using the UninstallString (this sample code uses powershell on windows 10):
# Get all installed apps from Registry
$Apps = #()
$Apps += Get-ItemProperty "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*" # 32 Bit
$Apps += Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*" # 64 Bit
# Uninstall My App
$my_app = $Apps | Where-Object{$_.DisplayName -eq "The Name Of My App"}
$uninstall_string = " /C " + $my_app.UninstallString+' /S'
Start-Process -FilePath "cmd.exe" -ArgumentList $uninstall_string -Wait
if you don't know the exact full display name of your app, you can print the "Apps" array to a file, and search there:
$Apps | Out-File C:\filename.txt
I was working on a silent uninstall of an InstallShield installer and was running into similar issues. What was posted here did not work or help. After lots and lots of trial and error I did find that for some reason when I used the -uninst option for both the creating the response file and running the silent uninstall I had success. In case anyone runs into a similiar issue and stumbles upon this thread I wanted to share. I am not sure why but adding -uninst did change the contents of the response file.
In my example creating response file: "C:\Program Files (x86)\InstallShield Installation Information\{0D20ACF2-CEE1-4523-BFCF-389BC4CC81FB}\setup.exe" -runfromtemp -l0x0409 -removeonly -uninst -r -f1"c:\uninstall.iss"
Then I could finally get the silent uninstall to function as expected: "C:\Program Files (x86)\InstallShield Installation Information\{0D20ACF2-CEE1-4523-BFCF-389BC4CC81FB}\setup.exe" -runfromtemp -l0x0409 -removeonly -uninst -s -f1"c:\uninstall.iss"

How do I instruct MSTest to remove all testing artifacts after a test run?

I am running MSTest against our test assembly from the command line:
mstest /testcontainer:C:\dev\UnitTests\bin\Debug\UnitTests.dll
This works fine, except I do not want the artifacts from this run to remain. Seems that MSTest leaves a copy around. For me, they're in the C:\dev\TestResults\ directory.
I have investigated a few things:
Configuration in a .testsettings file. Couldn't find anything there.
Running a cleanup script, specified in a .testsettings file. This would work, but how can I find the output location MSTest uses for the artifacts?
Using Visual Studio to limit the number of old test results in Tools > Options > Test Tools > Test Execution. This doesn't work when using mstest.exe - and it wouldn't work anyway, as I want to script this for other developers on our team.
How can I remove test run artifacts after the run is completed?
Edit: also, I would accept an answer that will run our MSTest tests using an open source test running tool. I just want to script this, man.
MSTest creates the TestResults directory in $pwd.
function global:runtests()
{
$mstest = Join-Path $env:VS100COMNTOOLS "..\IDE\mstest.exe" -Resolve
$resultsDir = Join-Path $pwd "TestResults"
$testDll = Join-Path $solutionScriptsContainer "..\UnitTests\bin\Debug\UnitTests.dll" -Resolve
$output = & $mstest /testcontainer:$testDll
$o = [regex]::match($output, "^.*(Summary.*)Results file.*$")
$mstflag = "MSTest:"
$op = $mstflag += $o.groups[1].value
Write-Host $op
Write-Host "Deleting $resultsDir"
remove-item $resultsDir -force -recurse
}

Use PowerShell for Visual Studio Command Prompt

In a serious intiative to migrate all my command line operations to PowerShell, I would like to avoid using the old fashioned command console for anything. However, the Visual Studio Command prompt has various environment variables and path settings not found in the default command prompt. How could I create a 'Visual Studio PowerShell' with those same settings?
You can use for example this script to import Visual Studio command prompt environment, see the examples in the script documentation comments, e.g. for Visual Studio 2010:
Invoke-Environment '"%VS100COMNTOOLS%\vsvars32.bat"'
Having done that in the beginning of a PowerShell session (from your profile or manually), you get what you ask for in this PowerShell session.
Or you can use the solution provided by Keith Hill in this answer.
have a look at PowerConsole
PowerConsole has been incorporated into NuGet http://nuget.codeplex.com/. You get PowerShell inside Visual Studio and a package management system.
I use this script that I call Initialize-VisualStudio.ps1, i call it in my profile with dot source, to set the environment variables need it, in my actual session:
param([switch]$ArquitectureX86)
if($ArquitectureX86)
{ $arq= "x86"}
else
{ $arq="x64"}
pushd 'c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC'
cmd /c "vcvarsall.bat $arq&set" |
foreach {
if ($_ -match "=") {
$v = $_.split("="); set-item -force -path "ENV:\$($v[0])" -value "$($v[1])";
}
}
popd
What I do is create a simple cmd batch command script that looks like this:
call "%VS80COMNTOOLS%vsvars32.bat"
powershell
Then I create a shortcut that invokes this through cmd. The shortcut target looks like:
%windir%\System32\cmd.exe /k "SetupPSBuildEnvironment.cmd"
If you want the console to look like the powershell console, just modify the Layout to your liking in the shortcut properties.
First, check the contents of this folder:
C:/ProgramData/Microsoft/VisualStudio/Packages/_Instances/
There'll be another folder in it with a name consisting of hex digits (e.g. 2a7a9ed6, but that will vary for different MSVC versions). I'll refer to it as <instance_id>.
Then run from PS:
Import-Module 'C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\Common7\Tools\Microsoft.VisualStudio.DevShell.dll'; Enter-VsDevShell <instance_id> -DevCmdArguments '-arch=x64'
Or you can create a shortcut with the following target:
<path to your powershell.exe> -noe -c "&{Import-Module """C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\Common7\Tools\Microsoft.VisualStudio.DevShell.dll"""; Enter-VsDevShell <instance_id> -DevCmdArguments '-arch=x64'}"
Obviously, drop -arch=x64 if you need x86 toolset.
Works for me on Windows 10 with MS Build Tools 16.9.5 and PowerShell 5.1.19041,7.1.3

Resources