I have a solution where I have different app.configs, given a different configuration. Drawback is that an installer (created using Wix) is created for a specific configuration. I would like to do this on install time, such that I can start the installer with a command line parameter to do the xml transformation, to be able to use the same installer in different environemnts (development, test, accpetance).
So, currently I have the transform in the csproj file:
<Target Name="AfterBuild">
<TransformXml Source="App.config" Transform="App.$(Configuration).config" Destination="$(OutputPath)\$(AssemblyName).exe.config" />
</Target>
What I want to do is:
msiexec /i installer.msi PROD
such that the transformation in app.PROD.config is executed. Is there a way in Wix to achieve that using the transformations?
Instead of transforming the original file at install time, it is easier to include all transformed app.config files into the MSI package and then choose the appropriate one during at install by passing the property value.
The snippet of the wxs file might look like this:
<Component Id="AppConfigDev" Guid="...">
<Condition>MODE = "DEV"</Condition>
<File Name="app.config" Id="app.dev.config" KeyPath="yes" Source="$(var.Source)\app.DEV.config" />
</Component>
<Component Id="AppConfigTest" Guid="...">
<Condition>MODE = "TEST"</Condition>
<File Name="app.config" Id="app.test.config" KeyPath="yes" Source="$(var.Source)\app.TEST.config" />
</Component>
<Component Id="AppConfigProd" Guid="...">
<Condition>MODE = "PROD"</Condition>
<File Name="app.config" Id="app.prod.config" KeyPath="yes" Source="$(var.Source)\app.PROD.config" />
</Component>
As a result, when you pass in the value of MODE through the command line, only one of the components above will be installed, and it will end up in the target directory as app.config.
Note that Windows Installer will throw a warning saying the conditions must be mutually exclusive in order for this technique to work. As long as MODE property can only have one value at a time, these conditions are mutually exclusive by definition, but the warning is there.
Related
I need to exclude certain dll's from the package which I am building. But I need to include only this dll - System.Threading.Tasks.Extensions. Is there a way I can force this dll in Include which would supersede exclude command.
<files>
<file src="**\*.dll" include ="**\System.Threading.*" exclude="**\System.*;**\Azure.*;**\Microsoft.Bcl.*;**\Microsoft.IdentityModel.*;**\BouncyCastle*.dll;**\GraphQL.*;**\LaunchDarkly.*;**\Oracle.*.dll;**\xunit*.dll;**\*Tests.dll;**\obj\**\*.*;**\itextsharp.dll;**\AjaxControlToolkit.dll;**\Newtonsoft.Json.dll;**\log4net.dll;**\Npgsql.dll" target="lib\net48" />
</files>
Currently I'm working on an UWP NuGet package for making it easier to create great popups and dialogs.
Currently the project is newborn and doesn't have so much controls but I tried to create a NuGet package for it to be a test for making sure it is all good.
Unless I'm using app with the class library referenced to the sample project all things working well but after downloading the library from NuGet I'm getting XamlParseException error.
I searched a bit and find it out that I should add some xaml, xbf or somethings in the output so I tried to add the following lines to my nuspec.
<files>
<!-- XAML controls -->
<file src="Controls\MessageBoxControls\MessageBoxControl.xaml" target="lib\netcore50\Controls\MessageBoxControls"/>
<file src="bin\Debug\UWPPopupToolkit\Controls\MessageBoxControls\MessageBoxControl.xbf" target="lib\netcore50\Controls\MessageBoxControls"/>
<file src="Controls\PopupControlControls\PopupControl.xaml" target="lib\netcore50\Controls\PopupControlControls"/>
<file src="bin\Debug\UWPPopupToolkit\Controls\PopupControlControls\PopupControl.xbf" target="lib\netcore50\Controls\PopupControlControls"/>
<file src="Controls\SlideupPopupControls\SlideupPopup.xaml" target="lib\netcore50\Controls\SlideupPopupControls"/>
<file src="bin\Debug\UWPPopupToolkit\Controls\SlideupPopupControls\SlideupPopup.xbf" target="lib\netcore50\Controls\SlideupPopupControls"/>
</files>
But still I'm getting same error any idea how to solve it?
I should mention that the project is currently available on Github on the following link
https://github.com/NGame1/UWPPopupToolkit
and the NuGet package also is available here
https://www.nuget.org/packages/UWPPopupToolkit
Simply placing the content files in the lib folder of the nuget package will not automatically copy it into the build output folder, only the dll, pdb and xml files will be added into the output projects automatically.
Since your additional files are not the same type, so you cannot get what you want by your method. So I suggest you could try this:
Solution
1) create a folder called build on your root directory of your project and then add a file called <package_id>.props file.
Note: the file must be named the same as your nuget package so that it will work. For an example, if your nuget project named as UWPPopupToolkit.0.0.1-rc.nupkg, the file must be named as UWPPopupToolkit.props.
2) add these content into the UWPPopupToolkit.props file:
<Project>
<Target Name="OutputExtraFiles" BeforeTargets="Build">
<ItemGroup>
<File Include="$(MSBuildThisFileDirectory)..\File\**\*.*"></File>
</ItemGroup>
<Copy SourceFiles="#(File)" DestinationFiles="$(TargetDir)\%(RecursiveDir)%(Filename)%(Extension)"></Copy>
</Target>
</Project>
3) modify your UWPPopupToolkitSDK.nuspec file like this:
<files>
<!-- XAML controls -->
<file src="Controls\MessageBoxControls\MessageBoxControl.xaml" target="File\Controls\MessageBoxControls"/>
<file src="bin\Debug\UWPPopupToolkit\Controls\MessageBoxControls\MessageBoxControl.xbf" target="File\Controls\MessageBoxControls"/>
<file src="Controls\PopupControlControls\PopupControl.xaml" target="File\Controls\PopupControlControls"/>
<file src="bin\Debug\UWPPopupToolkit\Controls\PopupControlControls\PopupControl.xbf" target="File\Controls\PopupControlControls"/>
<file src="Controls\SlideupPopupControls\SlideupPopup.xaml" target="File\Controls\SlideupPopupControls"/>
<file src="bin\Debug\UWPPopupToolkit\Controls\SlideupPopupControls\SlideupPopup.xbf" target="File\Controls\SlideupPopupControls"/>
<file src="build\UWPPopupToolkit.props" target="build" />
</files>
4) then repack your nuget project, before you install the new version of the nuget package, please clean the nuget caches first and also delete the bin, obj or any output folders of your main project.
=================================
Update 1
In my side, clean all nuget caches or delete all cache files under C:\Users\xxx(current user)\.nuget\packages and then install the new version of the nuget package, the target files are output to bin\x86\Debug\Controls,
If I install the new version 0.0.1.5-rc,everything works well. See this:
Not sure if your problem is that the files are missing or you want to put them into bin\x86\Debug\netcore50\Controls.
If your issue is the second, you should modify your UWPPopupToolkit.props,
use this:
<Copy SourceFiles="#(File)" DestinationFiles="$(TargetDir)netcore50\%(RecursiveDir)%(Filename)%(Extension)"></Copy>
After that, delete bin and obj folder and then rebuild your main project again.
Thanks to #Perry Qian-MSFT
Finally, I got able to fix the issue.
adding files like this
<files>
<!-- Dll -->
<file src="bin\Release\UWPPopupToolkit.dll" target="lib\netcore50" />
<!-- Resources -->
<file src="bin\Release\UWPPopupToolkit.pdb" target="lib\netcore50" />
<file src="bin\Release\UWPPopupToolkit.pri" target="lib\netcore50" />
<!-- IntelliSense -->
<file src="bin\Release\UWPPopupToolkit.XML" target="lib\netcore50" />
<!-- XAML control -->
<file src="bin\Release\UWPPopupToolkit\**\*.*" target="lib\netcore50\UWPPopupToolkit" />
<!-- Icon -->
<!--<file src="..\icon.png" target="images\" />-->
</files>
solved the problem.
You can find the result files here: UWPPopupToolkitSDK.nuspec | UWPPopupToolkit.props | UWP Popup Toolkit Github
I am using visual studio 2013 & Fluent Validation 5.6.2
I see that after build in the bin folder it copies all the culture specific FluentValidation.resources.dll which seems to be mentioned it in .nuspec file
> <file src="lib\NET35\de\FluentValidation.resources.dll"
> target="lib\NET35\de\FluentValidation.resources.dll" />
> <file src="lib\NET35\es\FluentValidation.resources.dll" target="lib\NET35\es\FluentValidation.resources.dll" />
> <file src="lib\NET35\fr\FluentValidation.resources.dll" target="lib\NET35\fr\FluentValidation.resources.dll" />
> <file src="lib\NET35\it\FluentValidation.resources.dll" target="lib\NET35\it\FluentValidation.resources.dll" />
> <file src="lib\NET35\nl\FluentValidation.resources.dll" target="lib\NET35\nl\FluentValidation.resources.dll" />
> <file src="lib\NET35\pt\FluentValidation.resources.dll" target="lib\NET35\pt\FluentValidation.resources.dll" />
> <file src="lib\NET35\sv\FluentValidation.resources.dll" target="lib\NET35\sv\FluentValidation.resources.dll" />
But I do not need these in bin folder, because project does not support any culture specific messages.
So how can I tell vs-build to ignore these culture specific dlls?
My solution was to add this target at the end of the .csproj file before the closing project tag.
<Target Name="AfterPackage" AfterTargets="CopyAllFilesToSingleFolderForPackage" />
<ItemGroup>
<FluentValidationExcludedCultures Include="cs;da;de;es;fa;fi;fr;it;ko;mk;nl;pl;pt;ru;sv;tr;zh-CN">
<InProject>false</InProject>
</FluentValidationExcludedCultures>
</ItemGroup>
<Target Name="RemoveTranslationsAfterBuild" AfterTargets="AfterBuild">
<RemoveDir Directories="#(FluentValidationExcludedCultures->'$(OutputPath)%(Filename)')" />
</Target>
<Target Name="RemoveTranslationsAfterPackage" AfterTargets="AfterPackage">
<RemoveDir Directories="#(FluentValidationExcludedCultures->'$(_PackageTempDir)\$(OutputPath)%(Filename)')" />
</Target>
It's not pretty, but it gets the job done. If you need some culture specific resource, just remove the corresponding line from the list. If a future update adds a new culture that you don't want, add it to the list.
The best option would be ask the developer to separate the resources in multiple nugets, this way you could just add the ones needed. I'll stick with this solution, for now, until someone come up with a better one.
Now you can find my solution at the official project wiki: https://github.com/JeremySkinner/FluentValidation/wiki/f.-Localization (at the bottom of the page)
i had same problem with external library, i'm add post-build script in Visual Studio project properties, which delete all folders (for me it`s okay, otherwise set list of dirs) at output directory:
FOR /D %%d IN ($(TargetDir)*) DO RMDIR /S /Q %%d
I have a C# solution with 4 projects there is only a single dll created for 3 of the projects and an exe from the main project. I've never used WIX but followed the simple example and was able to compile my code but only the .exe is deployed. I've tried modifing to add the other projects:
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<Component Id="ProductComponent">
<File Source="$(var.MedusaPerfApp.TargetPath)" />
<File Source="$(var.CustomClassLibrary.TargetPath)" />
<File Source="$(var.CustomControls.TargetPath)" />
<File Source="$(var.MultitaskingFramework.TargetPath)" />
</Component>
</ComponentGroup>
</Fragment>
I get the following error:
Error 3 The Component/#Guid attribute's value '*' is not valid for this component because it does not meet the criteria for having an automatically generated guid. Components with more than one file cannot use an automatically generated guid unless a versioned file is the keypath and the other files are unversioned. This component has a non-keypath file that is versioned. Create multiple components to use automatically generated guids.
As the error message says: Create multiple components to use automatically generated guids. Put each File element in its own Component element.
I came across the same problem and found a solution without having to wrap each file in a component tag. All you have to do is add a Guid to the component.
<Component Id="appComponent" Guid="6263db4e-4c67-4adc-9ef1-e1caef798331">
Here is an example you can follow
I want to create a setup installer for my application. I have downloaded WiX 3.6 and installed it on vs 2012.
Create simple winform application
Add WiX setup project to my solution
Right click on reference and add my winform application to setup's reference
I build solution and go to debug directory in setup project and run SetupProject1.exe.msi it does not work and closes the installer dialog without any error.
Go back to setup project
Right click on setup project and select properties
On installer tab > output type, change it to executablefile.exe
Build it and go to debug and run SetupProject1.exe - still does not work
What is wrong? This is my setup project product.wxs
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="SetupProject1" Language="1033" Version="1.0.0.0" Manufacturer="Natiloos" UpgradeCode="cfc2f4dd-2da5-49e2-9099-96968d75aaa4">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate />
<Feature Id="ProductFeature" Title="SetupProject1" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="SetupProject1" />
</Directory>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. -->
<!-- <Component Id="ProductComponent"> -->
<!-- </Component> -->
</ComponentGroup>
</Fragment>
How can I get the installer to build correctly?
The problem is your installer is not installing anything. Adding your project as a reference to the installer does not mean the installer will include your projects output. In your setup project you have:
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. -->
<!-- <Component Id="ProductComponent"> -->
<!-- </Component> -->
</ComponentGroup>
</Fragment>
You need to add the files...i.e. uncomment the <Component></Component> tags and add your files manually. It's good to have one <Component> tag per file.
Example:
<Component Id="MyProgram.exe" Guid="PUT-GUID-HERE">
<File Id="MyProgram.exe" KeyPath="yes" Source="Path_To_Output_Folder\MyProgram.exe" />
</Component>
WiX projects of the type that you are describing produce MSI files, with the .msi extension. These installers are not run directly, rather then are run using msiexec.exe. Windows explorer does this for you by default when you double click on them, however you can explicitly call msiexec using a command like the following
msiexec MyInstaller.msi
Note that MSI files are completely different from executables - changing the output name of your setup produce to have an .exe extension, or renaming the file to have an .exe extension won't work.
If you want to produce an .exe based installer then what you need is a bootstrapper. WiX has one called Burn, however if I were you I would worry about making an MSI that works first and then worry about creating an executable bootstrapper.