How to stop generating wixpdb file in wix setup project? - wix

Is there any configuration available to stop generation of wixpdb file.
Since we do not require that file during deployment.

Just add as per below in your .wixproj file.
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<OutputPath>bin\$(Configuration)\</OutputPath>
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
<-- Just Add below line to avoid generation of wixpdb file -->
<SuppressPdbOutput>true</SuppressPdbOutput>
</PropertyGroup>

See the SuppressPdbOutput setting in the light build task:
Optional boolean parameter.
Specifies that the linker should suppress outputting .wixpdb files. This is
equivalent to the -spdb switch in light.exe.

Right click Wix Project and go to Properties,
Build → Output → (Check) Suppress output of the wixpdb files

Related

msbuild Directory.build.props cascade per project?

Executive Summary: I want to set properties in property groups based on conditions that are present only late in the build pipeline and am looking for a way to solve this earlier.
I have a fairly simple Directory.build.props file
<Project>
<PropertyGroup>
<MyMode>Default</MyMode>
</PropertyGroup>
<!-- This one overrides the default group above -->
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<MyMode>Changed to Debug</MyMode>
</PropertyGroup>
<!-- This one is not applied -->
<PropertyGroup Condition=" '$(TargetFrameworkVersion)' == 'v4.7.2' ">
<MyMode>Framework</MyMode>
</PropertyGroup>
<Target Name="Stats" AfterTargets="Build">
<Message Importance="High" Text="::::: Mode set to $(MyMode)" />
<Message Importance="High" Text="::::: Target Framework set to $(TargetFrameworkVersion)" />
</Target>
</Project>
And a simple project structure
E:.
│ Directory.build.props
│ MSBuild_Test.sln
│
├───ConsoleAppNet
│ App.config
│ ConsoleAppNet.csproj
│ Program.cs
│
└───MSBuild_Test
Class1.cs
LibStandard.csproj
LibStandard is a .net standard library, ConsoleAppNet is a .net framework project which also has a build dependency to LibStandard
When I execute the msbuild script above I get this output
LibStandard -> E:\temp\MSBuild_Test\MSBuild_Test\bin\Debug\netstandard2.0\LibStandard.dll
::::: Mode set to Changed to Debug
::::: Target Framework set to v2.0
ConsoleAppNet -> E:\temp\MSBuild_Test\ConsoleAppNet\bin\Debug\ConsoleAppNet.exe
::::: Mode set to Changed to Debug
::::: Target Framework set to v4.7.2
As you can see, the console output should have triggered the property group with the condition resulting in MyMode being Framework, but it did not work out. This one was never matched:
<PropertyGroup Condition=" '$(TargetFrameworkVersion)' == 'v4.7.2' ">
<MyMode>Framework</MyMode>
</PropertyGroup>
Is there a good way to apply PropertyGroups during load based on the condition above?
I am aware that I can place PropertyGroup overrides in a Target, e.g.:
<Target Name="TooLate" BeforeTargets="BeforeBuild" Condition=" '$(TargetFrameworkVersion' == 'v4.7.2' ">
<PropertyGroup >
<MyMode>Framework</MyMode>
</PropertyGroup>
</Target>
and it also gets executed correctly but at this point in time I cannot set important other variables.
My intention is to redirect output directories based on different conditions. When I set $(OutputPath) in a target, it is already too late. The project ignores this output for the entire build of this project:
<Target Name="TooLate" BeforeTargets="BeforeBuild" Condition=" '$(TargetFrameworkVersion)' == 'v4.7.2' ">
<PropertyGroup >
<OutputPath>New_Output_Directory</OutputPath>
</PropertyGroup>
</Target>
I can even echo the OutputPath variable and it points to the correct value but the build uses the old value and not redirecting the output.
High five me, I found the solution for all the coming up Samuels asking about the same issue.
Quick answer
At the time of import of the Directory.build.props no other properties (e.g TargetFramework) are already imported and will default to empty. This is why the checks on them fail. Use Directory.build.targets instead!
Directory.build.props imported very early, allowing you to set properties at the beginning
Directory.build.targets imported very late, allowing you to customize the build chain
Resources
Here are some very useful pages regarding msbuild
Explanation of available targets
How to customize your build
Explanation
Here is a quote from the paragraph on the customization page (so long the current documents are alive ...)
Import order
Directory.Build.props is imported very early in
Microsoft.Common.props, and properties defined later are unavailable
to it. So, avoid referring to properties that are not yet defined (and
will evaluate to empty).
Directory.Build.targets is imported from Microsoft.Common.targets
after importing .targets files from NuGet packages. So, it can
override properties and targets defined in most of the build logic,
but sometimes you may need to customize the project file after the
final import.
By reading this the implication is somewhat fuzzy about the targets but Directory.Build.targets is the best place to override properties and use conditional checks.

With different configurations in a solution, how can you specify different build types (DLL or Static Lib) for a project in the solution?

I have a VisualStudio solution with multiple projects and configurations.
For one of the projects I want to use different configuration types (DLL or Static Lib) for different configurations.
For example for the configuration "Debug|Win32" I want to build a DLL for that project, and for configuration "Static Release|x64" I want to build a Static Library.
When I try to set the configuration type for one of these configurations, this is the type that then is set for all configurations, so it seems always to be "DLL" for all configs or "Static Lib" for all configs.
I have an example where this can be different and I can't work out how this was achieved. Or do you have to 'hack' the vcxproj file ?
Actually, it turns out that this is possible, but you need to edit the project file.
The project file is in xml format and you should find entries like this
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">...</PropertyGroup>
Within a PropertyGroup with a condition, add the ConfigurationType you require, so for example
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
becomes
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<PlatformToolset>v141</PlatformToolset>
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<PlatformToolset>v141</PlatformToolset>
<ConfigurationType>DynamicLibrary</ConfigurationType>
</PropertyGroup>
I've found that this works, but as usual be careful when editing the xml by hand, make sure you have a backup in case you mess up syntax or xml nesting.

Wix on windows 10 with mvs2013 or mvs2014 is not working (making php executable)

Wix on windows 10 with mvs2013 or mvs2014 is not working.
I am getting the error:
Error The "GenerateCompileWithObjectPath" task could not be loaded from the assembly \WixTasks.dll. Could not load file or assembly 'file:///c:\WixTasks.dll' or one of its dependencies. The system cannot find the file specified. Confirm that the <UsingTask> declaration is correct, that the assembly and all its dependencies are available, and that the task contains a public class that implements Microsoft.Build.Framework.ITask. SetupProject5 C:\Program Files (x86)\MSBuild\Microsoft\WiX\v3.x\wix2010.targets
If i try to include WixTasks.dll to the project, when mvs2013 or mvs2014 crashes during the build. I include \WixTasks.dll to the C:\SourceControl\vs2015\SetupProject1\SetupProject1\SetupProject1.wixproj from the unpacked wix binaries folder:
C:\SourceControl
// C:\SourceControl\vs2015\SetupProject1\SetupProject1\SetupProject1.wixproj
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProductVersion>3.10</ProductVersion>
<ProjectGuid>0adbe89f-e1ce-4345-90e6-64b8304fa42f</ProjectGuid>
<SchemaVersion>2.0</SchemaVersion>
<OutputName>SetupProject1</OutputName>
<OutputType>Package</OutputType>
<WixToolPath>C:\SourceControl</WixToolPath>
<WixTargetsPath>$(WixToolPath)\wix.targets</WixTargetsPath>
<WixTasksPath>$(WixToolPath)\WixTasks.dll</WixTasksPath>
<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' AND '$(MSBuildExtensionsPath32)' != '' ">$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<OutputPath>bin\$(Configuration)\</OutputPath>
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
<DefineConstants>Debug</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<OutputPath>bin\$(Configuration)\</OutputPath>
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
</PropertyGroup>
<ItemGroup>
<Compile Include="Product.wxs" />
</ItemGroup>
<Import Project="$(WixTargetsPath)" />
<!--
To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Wix.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
I was reading different online forums and examples the last two days. Also Pact books on wix by Nick Ramirez. Nothing is working.
Define the following MSBuild variables and everything should work.
<WixRootPath Condition=" '$(WixRootPath)' == '' ">$(MSBuildThisFileDirectory)Tools\wix\$(WixTargetVersion)\</WixRootPath>
<WixToolPath Condition=" '$(WixToolPath)' == '' ">$(WixRootPath)</WixToolPath>
<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' ">$(WixRootPath)Wix.targets</WixTargetsPath>
<WixCATargetsPath Condition=" '$(WixCATargetsPath)' == '' ">$(WixRootPath)sdk\Wix.CA.targets</WixCATargetsPath>
<WixTasksPath Condition=" '$(WixTasksPath)' == '' ">$(WixToolPath)WixTasks.dll</WixTasksPath>
<WixSdkPath Condition=" '$(WixSdkPath)' == '' ">$(WixRootPath)sdk\</WixSdkPath>
Just make sure the paths are right. These paths are for the wix 3.10.2 binaries which I checkout for my builds on the build machine.
I think the build tasks should be looking in the path defined by the WIX environment variable but I'm not 100% sure about that.
I think defining all the variables with the path you set should fix everything since the error mentions looking in C:\WixTasks.dll normally the path it looks for is something like $(WixInstallPath)WixTasks.dll but if $(WixInstallPath) isn't properly defined it will just be empty and default to C:\WixTasks.dll. You do define $(WixTasksPath) but I think it's getting overwritten for somereason...
Regardless, there's something wrong on your system right now but you can work around it this way probably.
EDIT: If the above doesn't work, download the wix binaries from here and extract them into a folder called "Wix" or whatever you want to call it. Then set your WixRootPath to be equal to that location.
I encountered this when using VS2015 and working on git branches that use different versions of Wix. (I'm upgrading to the latest Wix version but not all branches are there yet.)
You must terminate and restart VS if you switch between git branches that use different versions if Wix. VS holds some Wix files open, files that won't work under any other version of Wix. If you forget to do this your VS build will fail with the (quite cryptic) message of "The "GenerateCompileWithObjectPath" task could not be loaded from the assembly C:\Program Files (x86)\WiX Toolset v3.10\bin\WixTasks.dll"
The working solution from WiX Cookbook by Nick Ramirez, 2015, Chapter1 "Building a WiX installer from the command line", Example 4 "BuildMachineInstaller"
Download and unzip wix binaries file, for example from here.
1. Create some folder for your project, for example C:\SourceControl\own\box1 with file Product.wxs
2. Extract binaries to some folder, for example to C:\SourceControl\own\box1\tools\wix
3. start windows command line tool cmd and change to your project folder. Execute candle and light commands as folows:
C:\SourceControl\own\box1>C:\SourceControl\own\box1\tools\wix\candle *.wxs -o obj\
C:\SourceControl\own\box1>C:\SourceControl\own\box1\tools\wix\light obj\*.wixobj -o bin\CommandLineInstaller.msi
Anyway, if somebody could give some working example files and description how to make *.exe or *.msi with MSBuild or Visual Studio Build and wix, i would appreciate a lot. The other examples in Pact books are not working by pure copying, although are very useful for general understanding.
I've just come across this issue and found that at the top of the wix2010.targets file was the following property group.
<PropertyGroup>
<WixInstallPath Condition=" '$(WixInstallPath)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Installer XML\3.11#InstallRoot)</WixInstallPath>
<WixInstallPath Condition=" '$(WixInstallPath)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows Installer XML\3.11#InstallRoot)</WixInstallPath>
When checking the referenced registry path there was no entry for 3.11 but there was one there for 3.10. and the installed version was reported as 3.10. So updating the property group to the following corrected the issue for me.
<PropertyGroup>
<WixInstallPath Condition=" '$(WixInstallPath)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Installer XML\3.10#InstallRoot)</WixInstallPath>
<WixInstallPath Condition=" '$(WixInstallPath)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows Installer XML\3.10#InstallRoot)</WixInstallPath>
Hope this helps.
I solved the problem by following these instructions:
Download WIX311.exe from https://github.com/wixtoolset/wix3/releases/tag/wix3111rtm
Download Votive2017.vsix from https://marketplace.visualstudio.com/items?itemName=RobMensching.WixToolsetVisualStudio2017Extension
Remove any old WiX nuget packets from your solution/project
Follow these instructions (you can omit /quiet).
http://packagingstuffs.blogspot.com/2017/11/wix-toolset-311-silent-install-method.html
Content from the website above;
To Install:
Step1: Download the source from web and get the installer wix311.exe.
Step2: Run following command:wix311.exe /install /quiet /norestart
Step 3: Copy the Votive2017.vsix file (provided by vendor) to the local machine (e.g. %TEMP%)
Step 4: Run VSIXinstaller from its stored location
"%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Professional\Common7\IDE\VSIXInstaller.exe" /quiet
Good luck and best regards

MsBuild not generating PDB files in Release configuration

<MSBuild Projects="$(ProjectFile)" Targets="_WPPCopyWebApplication;"
Properties="OutDir=..\publish;Configuration=Release;Platform=AnyCPU" />
I am using above script to publish Asp.Net project. In the project settings, I have absolutely made sure debug symbols are generated in release mode. Still MsBuild is not generating the pdb files in the output.
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>Full</DebugType>
<DefineDebug>false</DefineDebug>
<DefineTrace>true</DefineTrace>
<Optimize>true</Optimize>
<OutputPath>bin\</OutputPath>
<DocumentationFile>WebProject.xml</DocumentationFile>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
After looking at the Microsoft.Web.Publishing.targets source, I have found a variable (ExcludeGeneratedDebugSymbol) being set to True in Release mode. From the comments, it looks like they wanted to exclude symbols from WebSite project, but the condition is not properly set for WebApplication project.
So, I have decided to override my build scrip from the caller arguments and it worked like a charm. I have not yet ascertained any side affects it may cause or using the undocumented property for future stability, but it works for now.
From the Microsoft.Web.Publishing.target file
<!--For website we will always exclude debug symbols from publishing unless it is set explicitly by user in website publish profile-->
<ExcludeGeneratedDebugSymbol Condition="'$(ExcludeGeneratedDebugSymbol)'=='' And '$(_WebProjectType)' == 'WebSite'">True</ExcludeGeneratedDebugSymbol>
<ExcludeGeneratedDebugSymbol Condition="'$(ExcludeGeneratedDebugSymbol)'=='' And '$(Configuration)' == 'Release'">True</ExcludeGeneratedDebugSymbol>
<ExcludeGeneratedDebugSymbol Condition="'$(ExcludeGeneratedDebugSymbol)'==''">False</ExcludeGeneratedDebugSymbol>
I have updated my script as follows.
<MSBuild Projects="$(ProjectFile)" Targets="_WPPCopyWebApplication;"
Properties="OutDir=..\publish;Configuration=Release;Platform=AnyCPU"; ExcludeGeneratedDebugSymbol=false />
You could also updated your publish profile (.pubxml) file to include that property value. I had to do this today with the new build bits in TFS Build 2015 to have the web publishing include the .pdb files. See example contents of file with property added to bottom.
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
by editing this MSBuild file. In order to learn more about this please visit http://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>FileSystem</WebPublishMethod>
<SiteUrlToLaunchAfterPublish />
<publishUrl>C:\Publish</publishUrl>
<DeleteExistingFiles>True</DeleteExistingFiles>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<ExcludeApp_Data>False</ExcludeApp_Data>
<LaunchSiteAfterPublish>False</LaunchSiteAfterPublish>
<ExcludeGeneratedDebugSymbol>false</ExcludeGeneratedDebugSymbol>
</PropertyGroup>
</Project>
You can put this directly in your *.csproj file, as the last property group section (right before the Import elements):
<PropertyGroup>
<ExcludeGeneratedDebugSymbol Condition="$(DebugSymbols) == true">false</ExcludeGeneratedDebugSymbol>
</PropertyGroup>

Checking if a Property 'Starts/Ends With' in a csproj

I'm setting up some configurations in my csproj files that will target different framework versions. Ideally I want configurations of 'Debug - 3.5', 'Debug - 4.0', 'Release - 3.5' and 'Release - 4.0'.
In my csproj file I want to do something like the following:
<PropertyGroup Condition=" '${Configuration}' ends with '3.5' ">
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
</PropertyGroup
<PropertyGroup Condition=" '${Configuration}' ends with '4.0' ">
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
</PropertyGroup
... check for "starts with Debug" to define Optimize etc.
However, I don't know how to go about checking that ${Configuration} starts/ends with a particular string. Is there an easy way to do this?
Edit: Marked answer below for pointing me in the right direction, which lead me to go with:
<PropertyGroup Condition="$(Configuration.Contains('Debug'))">
... setup pdb, optimize etc.
</PropertyGroup>
<PropertyGroup Condition="$(Configuration.Contains('3.5'))">
... set target framework to 3.5
</PropertyGroup>
... and so on for Release and 4.0 variations
An MSBuild property is just a .NET String and has property functions available.
Condition="$(Configuration.EndsWith('3.5'))"
Should work