Update: there is an issue related to NuGet packages. I was recommending to run MsBuild with the command line option /t:Restore;Rebuild which should restore packages and rebuild the solution. However, as detailed here, the MSBuild Restore option only restores packages defined in the project PackageReference elements, not the ones in packages.config. In order to restore those, you still need to manually run nuget restore. Where do you get nuget.exe from? Obviously not from the Visual Studio Build Tools... but from the NuGet Gallery.

Now, for the original post.

So I had this medium size Visual Studio solution, in .NET Framework 4.6.1, containing a bunch of projects, including a Wix setup and a web API and I wanted to build it on a machine that did not have Visual Studio, for Continuous Deployment reasons. Since Visual Studio uses MSBuild to compile, I thought it would be a five minute job. Boy, was I wrong!

First of all, the command to build a solution is clear:
MSBuild You.sln
and since it was a .NET 4.0 project, it made sense to use the MSBuild.exe from C:\Windows\Microsoft.NET\Framework64\v4.0.30319. Well, enter the first error: CS1617: Invalid option 'latest' for /langversion; must be ISO-1, ISO-2, 3, 4, 5 or Default. This is caused by the project using C# version 7 which is NOT supported by the MSBuild version in the .NET Framework, you need MSBuild version 15, which comes with Visual Studio. I didn't want to install Visual Studio.

The solution is to install Visual Studio Build Tools, preferably using the Visual Studio Installer. Now, the correct MSBuild version is found at C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\MSBuild\15.0\Bin\MSBuild.exe. Note that it is in located in a Visual Studio folder, not the MSBuild folder, which is also there.

An issue that occurred here was that previously warning messages saying the framework is 4.6.1 and the installed framework is 4.7.2 now became errors. The solution is to install the .NET Framework SDK 4.6.1 or to upgrade all your projects to 4.7.2. Warning: you need the Developer Pack, not just the Runtime.

Second error: error MSB4036: The "GetReferenceNearestTargetFrameworkTask" task was not found.. The problem? The NuGet package manager and/or the NuGet targets and build tasks are not installed. In order to install them, run Visual Studio Installer and look under the Individual Components tab, in the Code Tools section. See this Stack Overflow question for more details.

Next problem: The type 'IDisposable' is defined in an assembly that is not referenced. You must add a reference to assembly 'netstandard'. This is a weird one, since the compilation in Visual Studio had no issues whatsoever. This is related to the framework version, though, as .NET 4.6 uses netstandard 1.0 and 4.7 uses 2.0. The solution is to add a <Reference Include="netstandard" /> tag in your .csproj (tip: Search and replace <Reference Include="System" /> with <Reference Include="System" /><Reference Include="netstandard" /> in all your .csproj files)

Another problem similar to the one above is Predefined type 'System.ValueTuple´2´ is not defined or imported and that is because ValueTuple is not in .NET Framework 4.6.2 or earlier and you need to install the System.ValueTuple package in your project (using the NuGet package manager, more details here)

For both problems above as well as for the issue with the framework conflict further up a possible solution is to upgrade all projects to .NET 4.7+ or whatever is latest.

Next, targets errors: error MSB4226: The imported project "Microsoft.WebApplication.targets was not found. and error MSB4057: The target "_WPPCopyWebApplication" does not exist in the project. This is because even if Visual Studio Build Tools is installed, the targets for it are not. The solution is to copy the folders Web and WebApplications from C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\Microsoft\VisualStudio\v15.0 to "\\BuildMachine\C$\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\MSBuild\Microsoft\VisualStudio\v15.0". You may need to copy the NuGet targetss as well, I don't remember if that is what I did or the NuGet package manager installation solved it.

Last but not least, Wix errors. Obviously, for the Setup project to compile you need to install the Wix Toolset. However, you may still run into this error: error MSB3073: The command "heat dir ..blah blah blah" exited with code 9009. If you were trying to executing the build from a command prompt and you installed Wix while it was open, you need to open another one in order to refresh the changes the installer did to your environment PATH variable.

Finally, in order to compile for a specific platform and configuration, use the flags: /property:Configuration=Release /property:Platform=x64.

Then just run the line:
nuget restore
"c:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\MSBuild\15.0\Bin\MSBuild.exe" /t:Restore;Rebuild Your.sln /property:Configuration=Release /property:Platform=x64

Hope it helps.

There are two things you need to do. First, set the project as having a neutral language. This is done in Visual Studio 2008 by going to the project's properties, selecting Application, clicking on Assembly information and setting the language. However, it doesn't set an UltimateResourceFallbackLocation. So you have to do it manually, by editing the Properties\AssemblyInfo.cs file and adding
[assembly: NeutralResourcesLanguageAttribute("en-US", UltimateResourceFallbackLocation.Satellite)]


The second thing is rather dumb. I haven't found ANY way to do it from Visual Studio. I just edited the csproj file manually. It needs
<UICulture>en-US</UICulture>
set in (under, actually) every <PropertyGroup> in it.

What that does is create a language folder in the bin directory when compiled with a localizable resource file. Using the locBaml utility in the Windows SDK you can turn a resources.dll in the language folder into a CSV, then back into a dll like this:
LocBaml /parse ProjectName.g.en-US.resources /out:en-US.csv
LocBaml /generate ProjectName.resources.dll /trans:fr-CA.csv /cul:fr-CA
.

You will not find locBaml in the Windows SDK folder except maybe as a sample project. The sample project can be downloaded here. Don't forget to compile it!

Some other useful links:
WPF Localization
Localizing WPF Applications using Locbaml
LocBaml + MsBuild + ClickOnce Deployment

Rick Strahl presents an easier and better alternative by using normal resx files! I don't want to copy (too much) from his post, so just read it:
Resx and BAML Resources in WPF

Among my most disgusting duties is creating setup projects, mostly with Visual Studio. One thing I've stumbled upon is the way to pass arguments to Custom Actions.

Imagine you want to add parameters containing spaces like:
/dir "[ProgramFiles]" /dir2 "[MyDocuments]"
In the custom action arguments box write this:
/dir "[ProgramFiles]\" /dir2 "[MyDocuments]

That's the only way I could make it work. I still don't have any idea why.
So if you want to have a parameter with spaces in it, add a quot in front of it, but don't add one at the end. If you need to have other parameters after this one, end the quot block with backslash+quot.

Update:
Apparently, Windows Vista and its MSI engine doesn't support custom actions anymore. If you want to make your setup projects "worthy" of Vista, you should avoid using custom action.

and has 0 comments
Using Visual Studio .NET 2003 to Redistribute the .NET Framework

It is as easy as downloading the Bootstrapper .MSI file and running it. Next
time you compile a Setup project it will include the dotnetfx.exe file and
the code required to install it on demand.

Another great tool is found here: RyanVM's MSFN Files Page
It is a switchless .NET installer. Just run it (as a custom action, for
example) and it will insure that you have .NET framework installed, no
questions asked.