WIX Toolset integrated into VS 2012 beginner problems - visual-studio-2012

My company recently forced us to use Wix Toolset (v.4.0.12), because we upgraded to Visual Studio 2012 which unfortunately no longer contains installer projects.
My problems are the following. I have a big solution with many projects which all in all result in an exe file, and several dlls.
I then create a Wix setup project in the solution, and add a reference to the project that produces the exe file. In the properties of that project reference I set Harvest: true and Project Output Groups: Binaries.
I would expect a build of my WiX project to harvest the dependencies from the referenced project, so that I do not need to manually add the references, as that would give me more maintenance.
Moreover, if I run heat.exe on the referenced project file, I only get the exe output of the file, and not the dlls which the project depends on.
I assume that the above is quite standard, and wix tools should be able to gather that information for me. And I really wonder why after an extensive search on the net, cannot find anyone with similar issues.
If anyone knows why the above, please try to send me a basic tutorial of how to do stuff with WiX. It seems impossible for me find an appropriate one.

WiX v3.6 and later support VS2012. WiX v4.0 is barely even started and not recommended for use at this time. Lots of breaking changes coming in v4.0 so stick with the v3.x line for now.
The auto-harvesting feature in Votive is not fully functional. That is why it is disabled by default. Found many project types were breaking it. As you found, the harvesting does not walk through multiple project references. All things that need more work before they work properly.
In the meantime, you can list the File elements in Component elements.

Not sure how you are using v4.0.12 when it's not even out yet! :) Wix v3.8 is the latest version: http://wixtoolset.org/releases.
There are plenty of guides in the official documentation and you can also find quite a lot of information in the tutorial.
However for your specific case you will need to manually include the outputs of each project and their dependancies into the installer as automatic harvesting isn't supported yet:
<Component>
<File Id="ProjectA.Output"
Name="$(var.ProjectA.TargetFileName)"
Source="$(var.ProjectA.TargetPath)"
KeyPath="yes" />
</Component>
<Component>
<File Id="ProjectA.NlogDependancy"
Name="NLog.dll"
Source="$(var.ProjectA.TargetDir)\Nlog.dll"
KeyPath="yes" />
</Component>
<Component>
<File Id="ProjectB.Output"
Name="$(var.ProjectB.TargetFileName)"
Source="$(var.ProjectB.TargetPath)"
KeyPath="yes" />
</Component>
<Component>
<File Id="ProjectB.AutofacDependancy"
Name="Autofac.dll"
Source="$(var.ProjectB.TargetDir)\Autofac.dll"
KeyPath="yes" />
</Component>
This isn't really that hard to do and unless you have several hundred binaries won't take you too long.

I had a similar issue when i tried to create a .msi installation of my solution.
To overcome this problem and to make it long lasting over time even when I insert new .dll and other dependencies to my project and to make it automatic I did the following.
In my Product.wxs I have this "Directory"
<!--Here We Install Our Main App-->
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="MyAppDir"/>
</Directory>
...
</Directory>
and in my Wix project-> properties -> Build events -> Pre build event command line, I added this command:
"%wix%\bin\heat" dir "$(SolutionDir)MainProject\bin\Debug" -dr INSTALLFOLDER -scom -frag -srd -sreg -gg -cg Components -var var.MainProject.TargetDir -o $(SolutionDir)MainProject\Includedheat.wxs
Once I build my wix project it will create a Includedheat.wxs file in my MainProject directory that lists all the files from my MainProject\bin\Debug directory.
Next step - add the Includedheat.wxs into the wix project , than in my feature section I added:
<!--Add Component-->
<Feature Id="MainApplication" Title="Main Application" Level="1">
...
<ComponentGroupRef Id="Components" />
</Feature>
now once I rebuild and install the .msi all of the content that resided in my MainProject\bin\Debug directory will also be included in the MyAppDir dir on the target location.
For some more information:
I followed this guides :
Create a working Wix project.
Easy way heat.exe.
Also recomending to read for detrming what flags to use in your command.

Related

WebStorm has marked all files in a directory as non-project files

WebStorm has marked all files in a subdirectory of my project (the server portion of the root) as non-project files.
It happened sometime during my conversion to Babel and then again to TypeScript. I've removed the TypeScript stuff, wondering if it's something to do with that configuration. I believe it's just a WebStorm setting somewhere - because my tests run, builds work, all that.
Whenever I refactor or rename a file it says:
"Selected element is used from non-project files. These usages won't be renamed. Proceed anyway?"
It also highlights the code in these files differently.
Each of these file's icons has a small x in the top corner.
In their docs it says that these are " non-project files (e.g, library sources, external sources etc." This makes me think at some point I just marked a whole folder external at some point, thought I don't know where that could be.
Update I've tried deleting .idea folder and then running invalidate cache and restart. This didn't fix it either.
The myProject.iml file looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
Close all Webstorm windows and from project folder in terminal run:
rm -rf .idea
Note: deleting from within Webstorm is not enough.
I had the same problem and none of these solutions didn't work.
Just right-click on the folder that has been marked as none-project, then click on Mark directory as, then click on Cancel Exclusion or Not Excluded and enjoy features of project-files :'))
screenshot of: how to mark none-project folder, as project folder

VS2012 MSBuild: Publish a Web Application Project with Existing Publish Profile

In the Visual Studio 2012 Build menu, there's a Publish command. In this you can establish profiles which are saved as .pubxml files in the Properties folder of the Project. I have one such profile that's a simple file copy operation - it just compiles the site and dumps it to a folder.
How can I use msbuild at the command line to publish a compiled web application to a folder?
What I've tried
I've tried the example from this question:
After Publish event in Visual Studio
And the changes and examples given here:
http://www.digitallycreated.net/Blog/59/locally-publishing-a-vs2010-asp.net-web-application-using-msbuild
The latter seems to get closest, but it causes every library Project the .csproj I'm attempting to publish from to throw an error:
Project "MainProj.csproj" (1) is building "ReferencedProj.csproj" (2) on node 1 (default targets).
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(609,5): error : The OutputPath property is not set for project 'ReferencedProj.csproj'. Please check to make sure that you have specified a valid combination of Configuration and Platform for this project. Configuration='Staging' Platform='AnyCPU'. You may be seeing this message because you are trying to build a project without a solution file, and have specified a non-default Configuration or Platform that doesn't exist for this project. [ReferencedProj.csproj]
Done Building Project "ReferencedProj.csproj" (default targets) -- FAILED.
This approach is very similar to what's suggested in this answer:
https://stackoverflow.com/a/7077178/176877
The crucial difference may be that I'm in Visual Studio 2012, rather than VS2008 or 2010.
Old question, but in case this helps anyone, this simple, stripped back approach worked fine for me:
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
...
<BuildDependsOn>
$(BuildDependsOn);
PublishOtherProject;
</BuildDependsOn>
</PropertyGroup>
<Target Name="PublishOtherProject">
<MSBuild Projects="pathtomyproject.csproj" Properties="DeployOnBuild=true;PublishProfile=nameOfPublishProfile" />
</Target>
The key line being:
<MSBuild Projects="pathtomyproject.csproj" Properties="DeployOnBuild=true;PublishProfile=nameOfPublishProfile" />

How do I include an XSD file for a configuration section with a NuGet package?

I have a library with a pretty verbose configuration section. I've created an XSD and would like to distribute that with my package so that when a user installs the package, Visual Studio knows about the XSD without the user needing to do anything extra. How do I do this?
You can include any files you want in a nuget package by placing them in the content directory. These will then be installed into the root of your target project when the package is installed. If you're using a nuspec file to build your package you would add the following element under the element.
<files>
<file src="Configuration\MyXsd.xsd" target="content\TargetFolderName" />
</files>
This will create the following file in the target project
\TargetFolderName\MyXsd.xsd
Once the xsd is in the target project visual studio should pick it up automatically for validating your config section.
This has recently become more complicated with SDK style projects and the different ways of referencing nuget packages.
Note the end of this section.
Basically, if a nuget project is referenced by package.config file, the files from the content folder of the nuget package will be copied to the referencing project. If the nuget package is referenced by PackageReference in the project file, the files from the contentFiles folder within the package will be used. It is recommended to include both.
Now if you are using a .nuspec file to configure your nuget package, you can use SynXsiS answer to include the file to both directories:
<files>
<file src="Configuration\MyXsd.xsd" target="content\TargetFolderName" />
<file src="Configuration\MyXsd.xsd" target="contentFiles\any\any\TargetFolderName" />
</files>
However, if you want to configure it in the .csproj file of SDK projects, you have to add the file you want to include in the nuget package into the project file with the following properties:
<ItemGroup>
<None Include="MyXsd.xsd">
<Pack>true</Pack>
<PackagePath>contentFiles\any\any\TargetFolderName;content\TargetFolderName</PackagePath>
</None>
</ItemGroup>
The any\any\ part of the path for the contentFiles specifies for which language (cs, vb, ...) and target framework the file is meant.
Note, that the item not necessarily has to be of type "None" it could also be "Content" and others as described here.
You can find all information for this structure here, general information of the folder structure can be found here and help for the SDK style projects here.

Is NuGet suitable for downloading runtime binaries?

Is NuGet suitable for pulling down assemblies which are not required for compilation, but are at runtime? I have a Visual Studio solution which contains a number of NuGet packages required for compilation - these packages are not kept in source control. At runtime there are a couple of extra dll's which are required. Would it be bad practice to create a VS post-build step which calls NuGet.exe to download these packages and then copies the binaries to the required location? It doesn't look like the intended use of NuGet, but I don't see any obvious flaws with this approach.
I not sure if this would be a good way to do it, but it might solve your problem:
Create a NuGet-package with the DLL's in question as content. You should have the following in your nuspec-file:
<files>
<file src="path\to\dll\one.dll" target="content\dlls\one.dll" />
<file src="path\to\dll\two.dll" target="content\dlls\two.dll" />
</files>
When installing this NuGet package in your project, you'll get a folder dlls added to the project root. You can then go to the property tab of all the included files and set Always for Copy to Output Directory.

Missing Second-Level Binary References with MSBuild Web Deployment

I am trying to do a Jenkins-based automated build/deployment of a web application (.NET 4.0). The web application project has several project references, which in turn have binary references third party DLLs.
The problem:
The second-level references (references of project references) are not pulled into the bin folder in the obj\<CONFIGURATION>\Package\PackageTmp\bin folder, used for building deployment packages.
When I build in the visual studio, the second level references are pulled into the regular build output directory.
When building with MSBuild, second level dependencies are not pulled into the regular output directory, nor into the PackageTmp\bin directory.
This is confirmed by MS as a Won't-Fix issue here.
Related questions here, here and here either do not match my problem, or offer solutions that don't work. I've reviewed all answers, not just the accepted ones.
My build command looks like this (using MSBuild 4.0):
MSBuild MySolution.sln /p:Configuration=Integration /p:platform="Any
CPU" /t:Clean,Build /p:DeployOnBuild=true /p:DeployTarget=Package
/p:AutoParameterizationWebConfigConnectionStrings=false
I've tried to manually edit Reference elements in project files, adding <Private>True</Private>, with no success.
I am trying to work around this known issue, so that my second-level dependencies are automatically and correctly pulled into the web publishing temp directory.
My current attempt combines the general approach here (customizing the web publishing pipeline by adding a MyProject.wpp.targets file next to the web project file), combined with some MSBuild code for finding DLLs here. So far this has either produced no results or broken the project file. I am new to custom MSBuild code and find it pretty arcane.
My Question: I am looking for a more complete example that works in my specific case. I think the goal is to intervene in the web publishing pipeline that gathers files for copying to the package temp directory, and adding the second-level dependencies to it.
My custom MyWebProj.wpp.targets looks like this:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<BRPathFiles Include="$(SolutionDir)..\Common\**\*.dll;$(SolutionDir)**\*.dll" />
<ConfigPathFiles Include="$(SolutionDir)..\Common\**\*.config;$(SolutionDir)**\*.config" />
</ItemGroup>
<Target Name="CopySecondLevelDependencies" BeforeTargets="CopyAllFilesToSingleFolderForPackage">
<RemoveDuplicates Inputs="#(BRPathFiles->'%(RootDir)%(Directory)')">
<Output TaskParameter="Filtered" ItemName="BRPaths" />
</RemoveDuplicates>
<RemoveDuplicates Inputs="#(ConfigPathFiles->'%(RootDir)%(Directory)')">
<Output TaskParameter="Filtered" ItemName="ConfigPaths" />
</RemoveDuplicates>
<CreateItem Include="%(BRPaths.Identity);%(ConfigPaths.Identity);">
<Output ItemName="FileList" TaskParameter="Include"/>
</CreateItem>
<CreateItem Value="#(BRSearchPath);$(ConfigSearchPath)">
<Output TaskParameter="Value" PropertyName="SecondLevelFiles" />
</CreateItem>
</Target>
<ItemGroup>
<FilesForPackagingFromProject
Include="%(SecondLevelFiles->'$(OutDir)%(FileName)%(Extension)')">
<DestinationRelativePath>$(_PackageTempDir)\bin\%(FileName)%(Extension) </DestinationRelativePath>
<FromTarget>CopySecondLevelDependencies</FromTarget>
<Category>Run</Category>
</FilesForPackagingFromProject>
</ItemGroup>
</Project>
Assuming you have collected all libraries needed at runtime in a folder outside your solution/project, have you tried just using post-build events to copy all these libraries to your main project target directory (bin) and then include that directory in your deployment package using Sayeds method: http://sedodream.com/2010/05/01/WebDeploymentToolMSDeployBuildPackageIncludingExtraFilesOrExcludingSpecificFiles.aspx (also available in this post: How do you include additional files using VS2010 web deployment packages?)?
I have (among others) the following line in my main project's post-build events:
xcopy "$(ProjectDir)..\..\Libraries\*.dll" "$(TargetDir)" /Y /S
In addition to this, I have added the following lines to my .csproj file:
<PropertyGroup>
<CopyAllFilesToSingleFolderForPackageDependsOn>
PostBuildLibraries;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
</PropertyGroup>
<Target Name="PostBuildLibraries">
<ItemGroup>
<_PostBuildLibraries Include="$(TargetDir)**\*" />
<FilesForPackagingFromProject Include="%(_PostBuildLibraries.Identity)">
<DestinationRelativePath>$(OutDir)%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
Be sure to add these lines after the import of the "Microsoft.WebApplication.targets". Check out the links above for more details.
This makes all the desired libraries available after each build (copied to the project's target directory) and each time I create a deployment package (copied to the obj\<CONFIGURATION>\Package\PackageTmp\bin).
Also, since I'm building my main project, not my solution, I'm using the $(ProjectDir) macro instead of the $(SolutionDir).

Resources