I wrote a custom MSBuild task which calls SubWCRev.exe, an executable which (typically) resides in C:\Program Files\TortoiseSVN\bin, whether it's 32 or 64 bits, since TortoiseSVN provides both versions.
The problem is, Visual Studio 2010 only has a 32 bit version. So when my colleagues with a 64 bit box try to build using my shiny new task, $(ProgramFiles) resolves to C:\Program Files(x86) and it explodes saying that SubWCRev.exe cannot be found. Because they have the 64 bit version of TortoiseSVN, which lives in C:\Program Files!
Is there a better solution than hardcoding C:\Program Files in my msbuild script, or having everyone use the 32 bit version of TortoiseSVN? (Actually it's a C# project, I tinkered with the MSBuild code a bit)
Take a look it this:
<Project ToolsVersion="4.0" DefaultTargets="PrintValues" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="PrintValues">
<PropertyGroup>
<MyProgramFiles>$(ProgramW6432)</MyProgramFiles>
<MyProgramFiles Condition="$(MyProgramFiles) == ''">$(ProgramFiles)</MyProgramFiles>
</PropertyGroup>
<Message Text="MyProgramFiles: $(MyProgramFiles)"/>
</Target>
</Project>
This lets MyProgramFiles resolve to "C:\Program Files" for both 32 and 64 bit Windows (The ProgramW6432 environment variable is empty on non-64 bit versions of Windows).
Use MSBuildExtensionsPath property instead of hardcoding the path.
Per MSDN:
The MSBuild subfolder under the \Program Files\ or \Program Files
(x86) folder. This path always points to the Program Files of the same
bitness as the window you are currently running in. For example, for a
32-bit window on a 64-bit machine, the path is to the Program Files
(x86) folder. For a 64-bit window on a 64-bit machine, the path is to
the Program Files folder. See also MSBuildExtensionsPath32 and
MSBuildExtensionsPath64.
Edit: To get to the 64 bit SVN folder, use :
<PropertyGroup>
<TortoiseSVNPath>$(MSBuildExtensionsPath64)\..\TortoiseSVN\bin</TortoiseSVNPath>
</PropertyGroup>
Another way is to check for existence of folders:
<PropertyGroup>
<TortoiseSVNPath Condition="Exists('$(PROGRAMFILES) (x86)')">$(PROGRAMFILES) (x86)\TortoiseSVN\bin</TortoiseSVNPath>
<TortoiseSVNPath Condition="$(TortoiseSVNPath) == ''">$(PROGRAMFILES)\TortoiseSVN\bin</TortoiseSVNPath>
</PropertyGroup>
Related
I have a VS 2012 web project /sln that I am trying to build in TeamCity. it uses .NET 4.5 which is installed on TeamCity.
The TeamCity server has VS 2010 installed only.
I get this error when the build runs:
C:\BuildAgent\work\d5bc4e1b8005d077\CUSAAdmin.Web\CUSAAdmin.Web.csproj(799, 3):
error MSB4019:
The imported project
"C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\WebApplications\Microsoft.WebApplication.targets" was not found.
Confirm that the path in the <Import> declaration is correct, and that the file exists on disk. Project CUSAAdmin.Web\CUSAAdmin.Web.csproj failed.
Project CUSAAdmin.sln failed.
It is trying to use Visual Studio 2012 (v11.0) to build.
I have set the VisualStudioVersion to be 10 in the build.xml though??
<Target Name="BuildPackage">
<MSBuild Projects="CUSAAdmin.sln" ContinueOnError="false"
Targets="Rebuild"
Properties="Configuration=$(Configuration); VisualStudioVersion=10.0" />
As well inside the project it is defaulting to VS2010
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath
Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
Actually, you don't need to install Visual Studio on your CI server. You only need to copy a few folders from a development machine to the same location on the CI server.
VS 2015:
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\Web
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\WebApplications
VS 2013:
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v12.0\Web
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v12.0\WebApplications
VS 2012:
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\Web
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\WebApplications
VS 2010:
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\Web
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\WebApplications
.NET 4.6:
C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6
.NET 4.5.2:
C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.2
.NET 4.5.1:
C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1
.NET 4.5:
C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5
.NET 4.0.1:
C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0.1
.NET 4.0:
C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0
Or, as Matt suggested, you could copy them into a subdirectory of your project and alter the <MSBuildExtensionsPath32> location in your MSBuild (typically .csproj or .vbproj) file.
Once you have done this, your project will compile. You should still set the VisualStudioVersion explicitly to the one you are using just to be sure it is set right.
NOTE: This solution works for all project types (including web projects). For a web site (that has no project file), I ended up installing the Windows SDK matching the .NET SDK version I am using, because there were missing registry keys that were causing it not to build.
Turns out it's really simple. To make MSBuild run VS2010 as the builder on a solution made by VS2012 in TeamCity, simply set the environment variable for the build configuration like this:
Name: env.VisualStudioVersion
Value: 10.0
Note TeamCity does not need VS2012 installed.
Alternatively, you can copy the build targets you need from the c:\Program Files (x86)\MSBuild to a subdirectory of your project (for example .\Build) making sure to preserve structure and add the following to your csproj:
<!-- redirect msbuild path so targets can be added to source control -->
<PropertyGroup>
<MSBuildExtensionsPath32>..\Build\</MSBuildExtensionsPath32>
</PropertyGroup>
For example, if my project root is C:\Dev\MyProjSln\MyProj
Create Folder C:\Dev\MyProjSln\Build\Microsoft\VisualStudio\version\WebApplications\
Copy Contents of C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\version>\WebApplications\ to created folder
Add MSBuildExtensionsPath32 element to Property Group under Project node in csproj
Profit!
Personally, I prefer this method of tracking build target dependencies, as it prevents build server from being dependent on having undocumented folder structure requirements, and gets your dependencies into source control
As described here:
Install nuget MSBuild.Microsoft.VisualStudio.Web.targets
Edit the .csproj file
Replace:
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
with:
<Import Project="..\packages\MSBuild.Microsoft.VisualStudio.Web.targets.11.0.2.1\tools\VSToolsPath\WebApplications\Microsoft.WebApplication.targets" Condition="true" />
Obviously you have to make sure versions match your case both on the nuget installed and path in <Import>
I totally disagree with changing the project files because that might affect other developers. This is what worked for me since the v11.0 folder was missing on MS build folder:
1)Create v111.
Create v11.0 folder on C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio
Copy Web and WebApplications folders from my development box "C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0"
Booom! work like a charm\
Note: I installed "Microsoft Visual Studio 2012 Shell (Isolated) Redistributable Package"
Firstly, TeamCity does not require presence of Visual Studio of any version to build. When a build step in the project is configured with MSBuild runner TeamCity needs to know which version of MSBuild to use. This is a setting of a build step. Proper MSBuild version must be selected in a build step configuration according to the .NET tools installed on a build machine. TeamCity will use that value to determine the location path and will set an environment variable when invokes MSBuild.
The problem with the Visual Studio 2012/2013 is that it's only supported by TeamCity starting 8.1.0. So if your TeamCity version is before 8.1. you need to upgrade to the latest 8.1.x to see a setting for MSBuild Tools 2013. Once you select a proper MSBuild version in the build step settings the problem will disappear. For more information read here: http://blog.turlov.com/2014/07/upgrade-teamcity-to-enable-support-for.html
VS 2010 Premium :
I have a project which targets x86 platforms and I need to make it target x64 platforms.
I went to the Configuration Manager and from there to the Active Solution Platform, chose "new",added an 'x64' option and copied the settings from a Win32 platform (It's the only option I had).
So now the project should be targeting x64 platforms, if I'm not mistaken.
I have a code line in my project which asks for the file with this path :
Common Files\Microsoft Shared\OFFICE14\ACEDAO.dll
Yet it seems that during compilation, this file is being requested from the "Common Files" directory within the Program Files(x86) directory (the one for 32-bit). Naturally the compilation fails, since no such file exists in this path.
How can I make it to navigate to the (Program Files\Common Files ..) directory ?
The project should be targeting 64-bit after all and I require the 64-bit version of this dll.
The binary produced by the compiler and linker is indeed a 64-bit image. The compiler however is not, that's the one that reads the file so it is subject to file system redirection. The default 64-bit compiler is the one in the vc\bin\x86_amd64 directory. It is a 32-bit compiler that produces 64-bit code. You could select vc\bin\amd64 in the project's VC++ Directories setting to select the 64-bit compiler.
Something wrong with your machine setup though, I have this file present in c:\program files (x86). Windows 7 x64, Office 2010, VS2010. I have no clue why you don't have it, you could ask at superuser.com. Just copying the file is a simple workaround. Also beware that the 64-bit version of the ACE provider is not distributable.
I added the bin directory of the VS2010 (not SP1) C++ compiler to my PATH variable on Windows XP. When i try to run it, it tells me that a DLL was not found.
I added this line to my PATH:
C:\Program Files\Microsoft Visual Studio 10.0\VC\bin;
Update: it still fails when I cd to the bin directory above, and then run the compiler
Can you help me out?
Run the VS command prompt shortcut or the batch file it points to, such as:
"C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x86
to set up an appropriate environment including the path.
By the way, mspdb100.dll lives in C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE. But run the shortcut/batch file anyway - it does more than set up the correct path.
add Microsoft Visual Studio 10.0\Common7\IDE to your Path variable, than close cmd prompt and open it. now it will work.
Running the VS command prompt takes care of setting up the environment. Also, ensure that you are running the command prompt as an admin.
Installing Visual Studio 2010 SP1 C++ Compiler Setup fixed this issue for me. Visual Studio 2010 SP1 C++ Compiler install
I faced the same issue when I tried to run a 32 bit exe I built, on a 64 bit machine.
"mspdb100.dll couldn't be found by cl.exe "
Visual Studio 2010(the version I currently use) builds a 32 bit exe by Default.To create a 64 bit executable, just change the setting from Win32 to x64 in the dropdown box at the top of VS and build.This will build for you a 64 bit executable and solve your problem.
Does anyone know if windows 7 will somehow defer back to the "ProgramFiles(X86)" environmental variable when the "ProgramFiles" variable is used?
We have a situation where a developer is using visual studio and the proj file references assemblies using "$(ProgramFiles)". The machine is 64-bit and the "ProgramFiles" variable points to "C:\Program Files", however the assemblies are in "C:\Program Files (X86)" yet the project builds. It does not build if the literal "C:\Program Files" path is used. The compiler says it cannot find the assemblies
Yes, Windows automatically maps folder and file access to c:\program files for 32-bit programs to c:\program files (x86). Visual Studio as well as MSBuild are 32-bit programs. Same is true for c:\windows\system32 vs c:\windows\syswow64.
For reference, I'm using Visual Studio 2010.
I have a custom build step defined as follows:
if exist "$(TargetDir)"server.dll copy "$(TargetDir)"server.dll "c:\program files (x86)\myapp\server.dll"
This works great on my desktop, which is running 64-bit Windows. However, when I build on my laptop, c:\Program Files (x86)\ doesn't exist because it's running 32-bit Windows. I'd like to put in something that will work between both editions of Windows, since the project files are under version control and it's a real pain to change the paths every time I work on my laptop.
If this were a *nix environment I'd just create a symlink and be done with it. Any ideas?
You can put this in your project file:
<PropertyGroup>
<ProgramFiles32 Condition="Exists('$(PROGRAMFILES) (x86)')">$(PROGRAMFILES) (x86)</ProgramFiles32>
<ProgramFiles32 Condition="$(ProgramFiles32) == ''">$(PROGRAMFILES)</ProgramFiles32>
</PropertyGroup>
And then you can use $(ProgramFiles32) in your post build event.
For more information check this stackoverflow question.