Reputation: 11740
We've been using Jenkins for a while, mostly building VS solutions using the MsBuild plugin.
There's one thing about this that we really don't like - you configure which version of VS you want build with in Jenkins. Which means that if you move a project from one version to another you break the build.
Either you change the Jenkins job to build with the new version of VS, and break building all the old revisions, or you don't change and break all the new revisions, or you create two Jenkins jobs and have to know which to use for which revision.
So we want to take a step back, and adding a compile-project.bat to each project, and having Jenkins simply call the batch file.
But that creates a pathing problem. How does the batch file know where any particular version of VS is installed? We could make a requirement that each version of VS always be installed in a known location, except that we know that isn't going to happen.
If we can assume that every Jenkins master and slave will have its MSBuild installations configured correctly, is there a way to pass those paths to the batch file?
Upvotes: 0
Views: 651
Reputation: 11740
C Johnson suggested I look at VSWhere, and that solves the problem very nicely.
Upvotes: 0
Reputation: 28216
As Baruch said in the comment, most of the time, the higher version of msbuild can build projects from earlier version.
So you can configure the higher version of msbuild in jenkins no matter your project comes from earlier version or not.
And what do you mean "pass the path to the batch file"?
Something like this question?
if so, you can simply use %1
, and %2
in the .bat
file and pass the path or other parameter into it by command-line like xxx.bat para1 para2
.
Upvotes: 1
Reputation: 5841
The common problem is finding the installation location when we know what version we are looking for. Since here you are also asking about different versions, I think you have no right way and you will need to use one of the options.
As Lance Li-MSFT said in his answer, you can create a script that accepts the paths as parameters, and decides which one to use.
I think the disadvantage of this solution is that it is only suitable for the CI process, and it is difficult to run it in the development machine. And you still have to find the path in each machine.
Another option is to save the installation paths to environment variables and use them in the script.
The environment variables must be set once when installing Visual Studio or when creating the VM, and the script will access them as much as it wishes.
We still need to define the paths as environment variables in the development machine. If you have a lot of developers - it means a lot of emails.
Because there will not be an infinite list of installation paths, I would recommend searching for an existing path while running the script.
It does seem a little bad when you look at the file, but remember that the list is final and defined in one place, and there are no disadvantages that we have described in the other options.
Here is an example of finding Developer Command Prompt For VS 17, for development machines (Enterprise
, Professional
) and CI machines (BuildTools
).
By the way, it adds to the environment variables all kinds of important things, such as path to msbuild
and so on.
.bat
:
@echo off
if NOT DEFINED VSINSTALLDIR goto SetVars
echo VSINSTALLDIR already set to %VSINSTALLDIR%
goto :eof
:SetVars
if EXIST "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Enterprise" goto :Enterprise
if EXIST "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Professional" goto :Professional
if EXIST "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\BuildTools" goto :Docker
echo VS2017 is not installed on this machine
goto :eof
:Enterprise
call "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\enterprise\common7\tools\VsDevCmd.bat"
goto :eof
:Docker
call "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\BuildTools\common7\tools\VsDevCmd.bat"
goto :eof
:Professional
call "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Professional\common7\tools\VsDevCmd.bat"
:eof
msbuild
script:
<VsDevCmd Condition="Exists('C:\Program Files (x86)\Microsoft Visual Studio\2017\enterprise\common7\tools\VsDevCmd.bat')">
"C:\Program Files (x86)\Microsoft Visual Studio\2017\enterprise\common7\tools\VsDevCmd.bat"</VsDevCmd>
<VsDevCmd Condition="Exists('C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\common7\tools\VsDevCmd.bat')">
"C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\common7\tools\VsDevCmd.bat"</VsDevCmd>
<VsDevCmd Condition="Exists('C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\common7\tools\VsDevCmd.bat')">
"C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\common7\tools\VsDevCmd.bat"</VsDevCmd>
Upvotes: 1