Include version in filename in WiX project in Visual Studio - visual-studio

I'm using Visual Studio to author my WiX installer. I have it all working, but I need to have the version be a part of the .msi filename. I read that it's a bad idea to rename the msi file. It needs to take the form something like this:
my-product-2-10-23.msi
I have managed to make it work, but it seems really complex.
My question: Is there an easier, or more standard, way of accomplishing this?
Here's what I did:
in my .wixproj file, I created the following:
<PropertyGroup>
<InstallerMajorVersion>2</InstallerMajorVersion>
<InstallerMinorVersion>10</InstallerMinorVersion>
<InstallerBuildVersion>23</InstallerBuildVersion>
</PropertyGroup>
Also in .wixproj, I set the following:
<OutputName>local-services-$(InstallerMajorVersion)-$(InstallerMinorVersion)-$(InstallerBuildVersion)</OutputName>
The problem is that my WiX code can't access those properties. So, I can't set the version in Definitions.wxi. So, in the .wixproj, I did the following:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<OutputPath>bin\$(Configuration)\</OutputPath>
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
<DefineConstants>Debug;MajorVersion=$(InstallerMajorVersion);MinorVersion=$(InstallerMinorVersion);BuildVersion=$(InstallerBuildVersion)</DefineConstants>
</PropertyGroup>
I can access each constant in the .wxs files, so in Definitions.wxi, I have:
<?define Version='$(var.MajorVersion).$(var.MinorVersion).$(var.BuildVersion)'?>
This works, but it's really convoluted. And when I need to change the version, I have to manually modify the .csproj. This will not be intuitive for anyone else who has to update the project.
Is there a better way?

I was able to append version at the end of .msi by changing and in .wixproj file. Check the below section from the .wixproj file
<PropertyGroup <ProductVersion>_MAJORVERSION_._MINORVERSION_._MICROVERSION_._BUILDNUMBER_</ProductVersion> <ProjectGuid>xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</ProjectGuid> <SchemaVersion>2.0</SchemaVersion> <OutputName>ABCSetup_$(ProductVersion)</OutputName> <OutputType>Package</OutputType> </PropertyGroup>

Related

How not to hard code the path of the DocumentationFile path in Visual Studio 2019 .csproj

How to set the DocumentationFile dynamically to reference the current user's home drive? Is there a $ variable to set? I checked in my project to TFS. When another member of my team clones the source code to his workstation, the following node in the .csproj still references to the folder on my hard drive, and fails the compilation. So far we have to manually edit the .csproj file. Thanks.
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DocumentationFile>C:\Users\myName\source\repos\orgName\solutionName\projectName\.xml</DocumentationFile>
</PropertyGroup>
Thanks for your reply. It leads me to find the $(MSBuildProjectDirectory) variable. Here is the PropertyGroup
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DocumentationFile>$(MSBuildProjectDirectory)\.xml</DocumentationFile>
</PropertyGroup>
There is a list of common macros in Visual Studio.
The one you probably want is $(ProjectDir)
You can also use environment variables stored in the registry. See this.
Examples:
<FinalOutput>$(BIN_PATH)\MyAssembly.dll</FinalOutput>
<Project DefaultTargets="FakeBuild">
<PropertyGroup>
<FinalOutput>$(BIN_PATH)\myassembly.dll</FinalOutput>
<ToolsPath Condition=" '$(ToolsPath)' == '' ">
C:\Tools
</ToolsPath>
</PropertyGroup>
<Target Name="FakeBuild">
<Message Text="Building $(FinalOutput) using the tools at $(ToolsPath)..."/>
</Target>
</Project>

Why doesn't Directory.Build.props work when building a solution using Visual Studio 2017?

I have a Directory.Build.props file located in the same directory as the .sln file.
<Project>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DocumentationFile>bin\Debug\$(MSBuildProjectName).xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DocumentationFile>bin\Release\$(MSBuildProjectName).xml</DocumentationFile>
</PropertyGroup>
</Project>
When I build the solution using MSBuild, I am able to generate the XML files properly. However, using a Build -> Rebuild Solution task in Visual Studio doesn't generate the XML file.
Is there a difference in how Visual Studio 2017 builds and uses Directory.Build.props as opposed to MSbuild?
I had added the directory.build.props as a solution item. This somehow prevented Visual Studio from picking it up and using it in the build process. Once I removed it as a solution item, this worked fine.
You also might have to delete your .vs directory (or portion of) as it seems to be cached there as well.
https://developercommunity.visualstudio.com/content/problem/248037/defaultbuildprops-with-langversion-is-not-used-by.html
You need to check that your project file contains next row in the beginning of file
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
Without row Import 'magic' doesn't happen. So, you need to insert this row to all your old projects

How to get rid of "$(ReplacableToken...)" in web.config completely

I am creating a publishable package and when I navigate to obj\Debug\Package\PackageTmp directory, I am seeing the web.config's connection string is replaced by a replacable token, and I simply don't want that. I won't be using publishing batch files or anything, I'll be copying the files in the directory (I'm using the publishing package system only to get rid of lots of dynamically generated files while I'm testing my project and get the fresh/original file tree of my project) I don't want those web.config tokens and transforms etc, I just want my web.config file to be copied just like any other file. How do I achieve that? I've seen the /p:AutoParameterizationWebConfigConnectionStrings=False method for the commad line but I'm not using the command line, I am using the GUI to create the package. How will I stop web.config from changing the connection string to a token?
And before you say: Yes, I know that I can copy the original web.config from my original directory, but I don't want to deal with this and that, I want to finish it with a single click as I'm testing the publish package and frequently re-creating the package.
You have to edit your .csproj file and in the Debug PropertyGroup you'll have to add the following:
<AutoParameterizationWebConfigConnectionStrings>False</AutoParameterizationWebConfigConnectionStrings>
I have the following on Release and ReleaseCERT Configurations in my Project.csproj (I've only added the AutoParameterizationWebConfigConnectionStrings line):
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == '**Release**|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<!-- add the following line to avoid ConnectionString tokenization -->
<AutoParameterizationWebConfigConnectionStrings>False</AutoParameterizationWebConfigConnectionStrings>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == '**ReleaseCERT**|AnyCPU'">
<OutputPath>bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<!-- add the following line to avoid ConnectionString tokenization -->
<AutoParameterizationWebConfigConnectionStrings>False</AutoParameterizationWebConfigConnectionStrings>
</PropertyGroup>
I had to do what the accepted answer said, but instead in the Properties/PublishProfiles/__THEPROFILE__.pubxml file rather than the .csproj file.
(this may because I'm using VS2012?)
I had a similar issue when I was trying to create a web project package externally for a WiX setup according to the Travis Illig instructions. I solved it by adding the AutoParameterizationWebConfigConnectionStrings=False to the MSBuild/#Properties:
<MSBuild Projects="%(ProjectReference.FullPath)"
Targets="Package"
Properties="Configuration=$(Configuration);Platform=AnyCPU;AutoParameterizationWebConfigConnectionStrings=False"
Condition="'%(ProjectReference.WebProject)'=='True'"
I had to add the following in the Release condition section of my Project.csproj file:
<InsertAdditionalWebCofigConnectionStrings>False</InsertAdditionalWebCofigConnectionStrings>

How do I change the build folders in VS2010?

I'm getting an error in a VS2010 DB project that indicates I have too many charachters in my build path.
How can I change my default build path for all project types?
Something like
c:\build\$(projectname)\......
Thanks!
EDIT:
I've moved my project to the root of the C: drive and I still get the error with my DB project. I get this error when I try to right click the project and select properties
An error occurred trying to load the project properties window. Close the window and try again.
Cannot evaluate the item metadata "%(FullPath)". The item metadata "%(FullPath)" cannot be applied to the path "obj\Debug|Any CPU\TASS.DB.dbschema". Illegal characters in path. C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets
The first thing that jumps out to me here is that your platform and configuration are being fused together to form "Debug|Any CPU" and a string is being made from that--the pipe is the character it's referencing there when it says there are illegal characters. I'm not sure how much your database project really differs with respect to debug/release and for architecture, but you may not even need to include them in the path.
Since you can't open the project property pages, you'll need to edit the msbuild directly by unloading it and selecting "Edit..." from the context menu (sorry if you know this already).
From there, assuming you're realling running up on the windows path length ceiling, you could use some msbuild trickery to maximize your headroom in there. Specifically, doing something similar to what you suggest: use the C:\ drive wherever possible.
To do this, look inside the PropertyGroups with the conditions for your Configuration & Platform configurations, and inside them replace the OutputPath and IntermediateOutputPath properties so that they're as short as possible, for example:
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
<OutputPath>$(SystemDrive)\D\A</OutputPath>
<IntermediateOutputPath>$(SystemDrive)\o\D\A</IntermediateOutputPath>
</PropertyGroup>
This saves some valuable characters in that instead of "Debug" you're using "D", "A" for "AnyCPU" and "o" for "obj".
Probably most importantly you're using C:\o\ for the intermediate build directory instead of C:\whatever-the-whole-path-is-to-your-project-file\obj. As well, this property isn't configurable from the property pages, from what I recall.
Some added flexibility there using SystemDrive instead of a hard-coded C:, not that I would really expect it to be different.
Finally, concerning your property pages load problem, I don't know how the Debug|AnyCPU got in your path (I don't know of any properties that store the concatenated flavor like that), but you should be able to pick it out pretty easily once you open up the file. Hopefully it's similar to load errors in something like the winforms designer where you change one line and suddenly the whole thing works again.
Hope this helps!
I don't think it's possible to set a default build path for all projects, only the standard Debug/Release folders within the project itself. The only suggestion I would have is to simply move the project folder to location with a shorter path.
EDIT: As per the new edit, have a look here:
http://connect.microsoft.com/VisualStudio/feedback/details/594333/database-project-template-files-corrupt
I updated a project from VS 2005 to VS 2010 and got the same error message.
"The item metadata "%(Filename)" cannot be applied to the path "obj\Debug|x86\Debug\DemoCSharp.pdb". Illegal characters in path." The problem is that Visual Studio 2010 fails in converting the csproj file to the new format, but it does not tell us where exactly the error is.
In my VS 2005 csproj file there is the following XML code:
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">Debug|x86</Platform>
<ProductVersion>8.0.50727</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{05F88317-0CA7-4FE5-8520-35422402941A}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>DemoCSharp</RootNamespace>
<AssemblyName>DemoCSharp</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\output32\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<OutputPath>..\output32\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\output64\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
<OutputPath>..\output64\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
Visual Studio does NOT tell us which line produces the problem. But I found it by "try and error".
The cause of the error message is clearly a bug in the Visual Studio conversion wizard because VS 2005 has no problem loading this csproj file while VS 2010 fails to convert it.
So you have to manually edit and fix this file and then load it anew in VS2010.
In my case the line that triggers the bug is the 3. line with <Platform Condition. The bug is that VS tries to take the value ("Debug|x86") of this platform condition XML node and embed it into a path on disk (like "...\obj\Debug|x86\..."). But as pipe characters are illegal in paths, it later complains and aborts the conversion.
So how to solve the problem ?
I simply replaced the third line
<Platform Condition=" '$(Platform)' == '' ">Debug|x86</Platform>
with
<Platform Condition=" '$(Platform)' == '' ">Debug</Platform>
which eliminates the pipe character and the project converted without errors.
NOTE: It is also possible to completely delete this line.
ATTENTION:
It is possible that in YOUR case the same error messages needs another fix than in my case. Please study the csproj file and look for the pipe characters, then find out with try and error how to modify it. This error can even appear in other conditions than converting a project.
But what they all have in common is that this is a Visual Studio bug (or in case of 'littlechris' a software extension bug) that tries to embed a pipe character into the path.
XML node: "Debug|x86" -> path "...\obj\Debug|x86\..."
I received this messeage because the absolute path of one of the files in my project exceeded 260 characters. Once I reduced the path length, I was able to build the project.

How can I use a single Visual Studio solution to build both x86 and x64 at the same time?

I've got an x86 Visual Studio solution with many project files in it. Some of the DLL files are designed to work as plug-ins to other applications on a user's system.
We're expanding some of the DLL files to be able to support 64-bit applications. I'd like to set up the solution/projects so that just hitting "Build" will build both the x86 and x64 versions of those DLL
files. The solution contains both C++ and C# projects.
I realize that "Batch Build" is capable of building both, though it would be more convenient if developers could just click the same button as they have previously and have all of the output DLL files generated.
Here are a couple of the modifications that I've tried to a test project, but that I haven't gotten to work:
I've tried modifying the <Target Name="AfterBuild"> to try:
<Target Name="AfterBuild" Condition=" '$(Platform)' == 'x86' ">
<PropertyGroup>
<Platform>x64</Platform>
<PlatformTarget>x64</PlatformTarget>
</PropertyGroup>
<CallTarget Targets="Build"/>
</Target>
But that results in the following error:
C:\Windows\Microsoft.NET\Framework\v3.5\Microsoft.Common.targets(565,5): error MSB4006: There is a circular dependency in the target dependency graph involving target "Build".
I think my conditions will prevent infinite recursion, but I understand how MSBuild could not see it that way.
I've also tried:
<Project DefaultTargets="MyBuild86;MyBuild64" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
...
<Target Name="MyBuild86">
<PropertyGroup>
<Platform>x86</Platform>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<CallTarget Targets="Build"/>
</Target>
<Target Name="MyBuild64">
<PropertyGroup>
<Platform>x64</Platform>
<PlatformTarget>x64</PlatformTarget>
</PropertyGroup>
<CallTarget Targets="Build"/>
</Target>
But my DefaultTargets appears to be ignored from within the Visual Studio IDE.
Last, I've tried creating a separate project that imports the first project:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform>x64</Platform>
<PlatformTarget>x64</PlatformTarget>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<OutputPath>..\$(Configuration)\x64\</OutputPath>
<ProjectGuid>{A885CAC3-2BBE-4808-B470-5B8D482CFF0A}</ProjectGuid>
</PropertyGroup>
<Import Project="BuildTest.csproj" />
</Project>
And this so far has shown the most promise. However, Visual Studio seems to ignore my OutputPath setting from this new project and instead outputs the EXE/DLL file to the path specified in the original project. There isn't any PropertyGroup block that I can see that is being executed in the original project to override this, so I'm not sure what's happening.
We do something similar to build core assemblies for .NET Compact Framework.
Try this:
<Target Name="AfterBuild">
<MSBuild Condition=" '$(Platform)' == 'x86' " Projects="$(MSBuildProjectFile)" Properties="Platform=x64;PlatFormTarget=x64" RunEachTargetSeparately="true" />
</Target>
Importing a project in such manner works for me in Visual Studio 2010:
TestProject64.vcxproj
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="TestProject.vcxproj" />
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{B7D61F1C-B413-4768-8BDB-31FD464AD053}</ProjectGuid>
</PropertyGroup>
</Project>
TestProject64.vcxproj.filters
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="TestProject.vcxproj.filters" />
</Project>
TestProject.vcxproj has two configurations defined inside: Release|x86 and Release|x64. As you can see, TestProject64.vcxproj has only the Release|x64 configuration. Defining of at least one configuration in TestProject64.vcxproj is necessary, otherwise Visual Studio will not be able to add TestProject64.vcxproj to a solution.
Now it's possible to include both TestProject.vcxproj and TestProject64.vcxproj to the same solution and build Release|x86 and Release|x64 at the same time.
I think the best way of doing this is to invoke MSBuild from the command line. It shouldn't need editing of MSBuild files. Just run
msbuild myproj.sln /p:Configuration="Debug|Win32"
msbuild myproj.sln /p:Configuration="Debug|x64"
I assume that if a developer is using Visual Studio then they'll only be generating the DLL files so they can debug with them, and that you have a separate build process if you're actually deploying the DLL files.
For C++, and if it's a project whose files/settings don't change often, one way to do it is create two projects within the solution, with both projects referring to the same source files. Then, in x64 builds, set one project to build 64-bit and the other 32-bit. (In x86 builds, set one as 32-bit and turn off the other.)
We've been using this for a while and it works fine.
Of course, you have to be careful that any changes you make to one are also made to its copy. i.e. if you add/remove a file or change its build setting, you have to do it in two places. Source-code changes still only need to be done once, because there's still only one copy of each source file.
And, of course, you may decide that doing this is more complex/risky than switching away from using the IDE. In our case it's worked really well, though.
You are not going to be able to do this with the UI of Visual Studio. For this you will need to hack the MSBuild files.
Try this link from MSDN for MSBuild Overview
I would suggest to create a dummy C++ Makefile project and then invoke MSBuild twice from it:
msbuild myproj.sln /p:Configuration="Debug|Win32"
msbuild myproj.sln /p:Configuration="Debug|x64"
Perhaps I've missed the point of this discussion.
Using Visual Studio, go to menu Build → Configuration Manager. In the Active Solution Platform drop down, select "New...", and a New Solution Platform dialog appears. Select x64 and accept the default Copy From. Close the dialog and the Configuration Manager.
Now open menu Build → Batch Build. Check those configurations you want to build and build them. You will find the x64 build executables separate from the Win32 executable files.
You can verify that these are what was intended by right clicking on the executable files, selecting Properties, and select the Compatibility tab. In the dropdown window you can check to see what operating systems the executable file can be run in.
Obviously, there may be some other tweaking you might have to do to get all the output files in their proper places, but this method seem somewhat simpler than fooling with build than those described above.
I ran into this problem with a project running in Visual Studio 2008 (on Windows XP) (32-bit) and also Visual Studio 2010 (on Windows 7) (64-bit).
The solution I used was to use the $(PROGRAMFILES) variable. It resolved correctly on both machines.

Resources