Retargeting whole solution to another SDK using pre-build events - msbuild

I have a solution that needs to be built by msbuild.exe, but I'm calling the msbuild.exe as a pre-build event of another soultion:
msbuild.exe $(ProjectDir)dependencies\submodule.sln /t:Build /p:Configuration=$(Configuration);Platform=$(Platform)
However, all 24 projects of the solution are targeting 8.1 SDK where I need them to target one of the Win10 SDK, so I need a way to retarget all of the project as a pre-build event.
Is that achievable is any way?

Figured it out. Any property can be changed. Just use the macro.
This line will target the same SDK as the solution from which this is ran as an event:
msbuild.exe "$(ProjectDir)dependencies\submodule\submodule.sln" /t:Build /p:Configuration=$(Configuration);Platform=$(Platform);WindowsTargetPlatformVersion=$(WindowsTargetPlatformVersion)
P.S. What the hell with the down votes, come on...

Related

Is it possible to build a project with a com reference with the dotnet CLI? [duplicate]

I have made a project in VS2019. I have the same project in .NET Core and .NET Framework. I use a COM reference in my project. I would like to migrate these projects to Pi4.
A simple Hello World project (.NET Core) is running successfully on the Pi4 machine. However, when I try to run my project (.NET core or .NET Framework) it does not run on the Pi4. It says COM is not supported.
I tried to build the project using MSBuild in my Windows environment after looking for solutions in Google. I also see a similar error here. The error is: error : MSB4803: The task "ResolveComReference" is not supported on the .NET Core version of MSBuild. Please use the .NET Framework version of MSBuild.
The .NET Framework project also gives a similar error.
error MSB4028: The "ResolveComReference" task's outputs could not be retrieved from the "ResolvedFiles" parameter. Object does not match target type.
Does anyone have similar issues?
https://github.com/microsoft/msbuild/issues/3986
According to the above link. The employee of Microsoft is saying they can not give solution in the near future.
Set the Projects to x86 for them to build the Interop, the Interop created still could not be used in x64 runtimes.
Add the COM Reference to the Core project, Build it and you will get an Interop.YourCom in the bin/x86/core/debug folder.
Remove the COM reference, and re-add the Interop, it will be put into the Assemblies Dependencies, and MSBuild will work.
My MSB4803 was from a WIXInstaller project, for ADOX, and Microsoft.Office.Interop.Access.Dao
I stumbled upon this question many times and I experienced the same several times in different projects. It doesn't matter if it is Visual Studio 2019 or 2022 and the version of the build, unless you are working with the old MSBuild in a legacy environment, the COM Reference doesn't work. It is always safe to build it in the command line to understand if anything in the VS environment works. I don't truly understand why Microsoft let you make those references in the Visual Studio environment when they will not work nearly anywhere else.
There are some workarounds that might or might not work but if your code is already pointing at a COM library there is no much to do. You can install the NuGet package which is going to pass the build stage and remove the COM reference.
Install-Package Microsoft.Office.Interop.Excel -Version 15.0.4795.1001
The NuGet package has some differences at the types level that you will need to fix (the COM reference allows you to get specific types instead of objects from the cells values)
In any case, you will need the COM installed in the server, there is no workaround that issue.
I wouldn't say I like this error message or the link it shows on how to fix it, to be polite.... ;-);
I figured it out and thought as there are a lot of answers that are not helpful to share mine. What I did is update your command to force the use of msbuild.
dotnet msbuild -v:normal "FullOrRelativePathTo\MyProject.csproj" -p:Configuration=RELEASE
If that fails, try:
"C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Current\Bin\msbuild.exe" "PathTo\Project.csproj" /p:Configuration=RELEASE
I know I'm late to the party, but here is a workaround working for me when I want to use Office Interop in .NET (Core):
Create an empty .net Console app (I'm using Rider and .NET 7)
Build it with the default MSBuild (17.0 in my case at the time of writing)
Add Interop references to the project file (I don't use Nuget, only generate these in a dummy .NET Framework project while adding COM references to Office libraries), eg.
<ItemGroup>
<COMReference Include="Excel">
<Guid>{00020813-0000-0000-C000-000000000046}</Guid>
<VersionMajor>1</VersionMajor>
<VersionMinor>9</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>tlbimp</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
</ItemGroup>
Change the solution MSBuild version to 4.0
Try to build the solution, but the project will not even load properly due to an outdated MSBuild version
Revert the MSBuild version to the default one
Build the project - success! (this is the magic part, I can't explain it :P)

Wrong package.appxmanifest picked by msbuild when packaging in command line

I have a C# solution with VS 2017, containing an app project, a desktop extension project, and a packaging project. As I mentioned in the answer of this question, I finally get msbuild to create a single bundle with both x86 and x64 for me. However, after I tried to install from that bundle, I found that msbuild actually picked up the wrong package.appxmanifest because they have different version numbers.
So... I have two package.appxmanifest, one in packaging project, and one in my main app project. When I build from the wizard in VS 2017, the one in packaging project will be used, which is correct. When I use msbuild to build with just one platform, it will pick the right one as well, like this:
msbuild .\MyApp.sln /p:Configuration=Release /p:Platform=x86
Only when I use msbuild to build two platforms together, it will use the one in my main app project:
msbuild .\MyApp.sln /p:Configuration=Release /p:AppxBundlePlatforms="x86|x64" /p:UapAppxPackageBuildMode=StoreUpload
I also tried to build the packaging project instead of the solution, but because our desktop extension project is only x86, I will get errors about configurations when building x64.
Questions:
Does anyone know why this is happening?
I am also very confused about how to build multi-platform using AppxBundlePlatforms in the command line. Since I cannot specify the platform, which platform is used to build?
Should I add <AppxBundle>Always</AppxBundle> or <AppxBundle>Never</AppxBundle> to the packaging project?
Does anyone know why this is happening?
That because you have two Package.appxmanifest files with same ID in the solution. When you create the App Bundle with .sln, MSBuild/Visual Studio could not to know clearly which Package.appxmanifest should be use.
I am also very confused about how to build multi-platform using AppxBundlePlatforms in the command line. Since I cannot specify the
platform, which platform is used to build?
Not sure the reason why you can not specify the platform. To resolve this issue, you can try yo build the project file .csproj instead of the solution file. For example, when you build the app project, you can use the command line:
msbuild .\MyApp.csproj /p:Configuration=Release /p:AppxBundlePlatforms="x86|x64"
And then build the packaging project:
msbuild .\YouPackaging.csproj /p:Configuration=Release /p:AppxBundlePlatforms="x86"
Should I add Always or
Never to the packaging project?
If you build the project, no need to add those two properties to the project file, those two properties are used to the solution level and you have a project that you do not want to add to the bundle:
because at the solution level, it’s not clear which app should appear
in the bundle. To resolve this issue, open each project file and add
the following properties at the end of the first
element
Hope this helps.

Creating Windows store app package from command prompt

How do i create a windows store app package using command prompt?
I have tried devenv, but it just builds the project, it doesn't creates any app packages.
I tried using msbuild, but i have dependencies from other projects which msbuild doesn't recognizes and hence not building.
I tried using MakeAppx.exe, but it is too cumbersome. Can anyone suggest a solution.
Use msbuild with your solution file.
This is how we do it:
msbuild yoursolution.sln /t:Rebuild /p:Configuration=Release;OutDir=..\Release\;Platform="x86"
Your command line parameters will probably have to be tweaked and you will need to do this three times, once for each platform (ARM, x86, x64).

Why does Tfs2010 build my Wix project before anything else?

A similar question was asked and answered about a year ago, but was either a different issue (everything was in beta) or misdiagnosed. It's located here: MSbuild task fails because "Any CPU" solution is built out of order.
My issue is that I have a wix installer project, and after upgrading to Tfs2010 on monday, the build fails on linking because it can't find the build product of the Wpf application in the project. After some digging, it's because it hasn't been built yet. Building in Vs2010 works as normal. The wix project is set to depend on the Wpf project, and when viewing Project Build Order in the IDE, everything looks as normal.
The problem was originally encountered with only two platform definitions in the solution; x86 and x64. There are also two flavors, Debug and Release, and TFSBuild.proj is set to build all four combinations. There was no occurence of AnyCPU anywhere. Per the referenced question above, I tried changing the Wpf project to use AnyCPU so that it would be built first. At this point, the wix project used the exact configuration and the Wpf project used the flavor with AnyCPU. However, doing so didn't seem to change anything.
I'm using the Tfs2010 RTM, Vs2010 RTM, and the most recent version of Wix, which at the time of this writing is 3.5.1602.0, from 2010-04-02. Anyone else running into this?
2010-04-27: After a fair amount of digging, and reproducing on a cloned VM build machine, I believe I know what's going on and also what's failing, but I don't quite know how to fix it.
The situation is that this bug seems to exhibit symptoms based on pure luck-of-the-draw project ordering in the solution file. It appears as if the solution file will just blindly build the projects in the order they appear, relying on its ability to detect unbuilt references and build them on demand when needed.
In my particular solution file, my Wix project was ordered before my Wpf application project. This resulted in the Wix project being built first, and while the dependency on the Wpf project was detected correctly, the actual MSBuild task was skipped because of the undefined $(BuildProjectReferences) variable I mention a couple of comments down from the main post in this thread. With MSBuild verbosity still on diagnostic, BuildProjectReferences can be seen as undefined building the Wix project, and it can be seen defined as true upon building the Wpf project within the task to build the Wix project. Yet, when tested, it evaluates undefined again, the task is skipped, and the Wix build fails because it can't find the build output of the unbuilt Wpf project.
So bottom line: project dependency is skipped because of bad $(BuildProjectReferences) variable. Interestingly, this variable is present only in the Wix2010.targets file, and not in wix.targets; I guess that's why this is just showing up after I installed Tfs2010 and Vs2010.
The solution: How do I make sure that BuildProjectReferences is passed along correctly to the subsequent MSBuild tasks? Is there something special with variable scoping going on?
2010-09-14: A bug was opened for this issue in the WiX toolset: http://sourceforge.net/tracker/?func=detail&atid=642714&aid=2990231&group_id=105970 and fixed a while ago. Hopefully, this is no longer an issue. If so, please do open a new bug.
To address your comment directly, nothing in my solution has an AnyCPU configuration in their build files. I created the AnyCPU configurations only to test the solution suggested by the thread I linked to in my original post. After it didn't work, I removed the AnyCPU configurations again.
Furthermore, the projects are in the same solution file, however in separate solution folders (interface folder, installer folder) if that matters.
Interestingly enough, I was going to make a small sandbox example so that I could illustrate the problem I was having, however after creating my tiny sample solution, I couldn't get the error to reproduce. This makes me think that perhaps this is a result of using a team project that was upgraded from a Tfs2008 team project rather than one that was created fresh in Tfs2010. I may try branching my project into a new one to test this theory if I can't figure out why the test solution works.
p.s. also, I'm new to stackoverflow--why on earth are comments limited in length if the "answer your own question" workflow is intended only to provide concrete answers?
So I threw the build verbosity up to diagnostic and read through it today, and one line in particular stood out to me:
Task "MSBuild" skipped, due to false condition; ('#(_ProjectReferenceWithConfiguration)'!='' and '$(BuildingInsideVisualStudio)' != 'true' and '$(BuildProjectReferences)' == 'true' and '#(_MSBuildProjectReferenceExistent)' != '') was evaluated as ('..\WpfApp\WpfApp.csproj'!='' and '' != 'true' and '' == 'true' and '..\WpfApp\WpfApp.csproj' != '').
This was seen as my installer project was attempting to build my wpf project since the wpf project is referenced. In particular, for some reason $(BuildProjectReferences) is evaluating to '' when I'm fairly sure it should be 'true'.
However earlier in the log, at the beginning of the MSBuild task for the WpfApp project, I saw this:
Task "MSBuild" (TaskId:15)
...
Initial Properties:
...
BuildProjectReferences = true
So the property was indeed correct up until the beginning of the task, but then was apparently overwritten? I'm sort of unclear as to how these properties get set.
Its a bug, a bug, a bug. I don't know, who is responsible, but here's a working dirty filthy hack:
Open your .sln file in notepad.
Find your wix projects in the list of projects.
Cut them out, and paste them back after all other projects are listed.
Cry in the shower as you try to scrub the dirty off, only to emerge hours later, rubbed raw and still with the stench of filth clinging to you like corpse's skin.
Following Rob Mensching's edit of my original post, it seems that this has indeed been fixed in WiX 3.6.0917.0 at the latest.
I was seeing this problem (wix 3.7 not finding the dependent project output) in my local and TFS builds (for both VS2010 and VS2012).
I finally got around it by setting the msbuild property /m:1 to only use a single build process. I set /m to allow msbuild to figure out how many processes it could use to simultaneously build with.
I faced with a same problem today and find a solution like this:
Open your solution file on notepad the find your setup project and change postProject setting. This will tell msbuild this project should wait another project to build. I don't know why but it is not added by default.
Project("{GUID}") = "MyInstaller", "MyInstallerPath", "{Installer Project GUID}"
ProjectSection(ProjectDependencies) = postProject
{Prebuild Project GUID} = {Prebuild Project GUID}
EndProjectSection
EndProject
'Prebuild Project GUID' is the number on the right of the project that you want to install.
TFS uses a set of properties to control the names of the solutions and configurations to build ( iterate through ). For each combination of solution and configuration it then uses the project dependencies / build order to control the order of the projects getting built. It's possible that your EXE/DLL's are AnyCPU and that your WiX is x86 and that although the WiX has a dependency on the EXE/DLL the x86 is built before your AnyCPU. Or maybe they are even in different solutions so it's kind of hard to tell without looking at your source but that's basically how it works.
What we did is to first report the bug to wix and then we found your question.
We solved the problem on our side by saying that, by default, the wix project will build the references. We updated the file C:\Program Files\MSBuild\Microsoft\WiX\v3.5\wix2010.targets by setting <BuildProjectReferences>True</BuildProjectReferences> in the project which set the path. So, yes, we have done this manually ; we have reported the bug as well as our fix.

Is it possible from within the csproj file to know whether devenv or msbuild is used to run it?

Motivation:
I have fxcop integrated in the build process, which makes fxcopcmd.exe run each time the target has changed or as long as there are warnings from the previous run of fxcop.
But when one works in the studio, devenv.exe often decides to compile the project in background for whatever reasons. For example, when I add a new project to the solution I notice that fxcopcmd.exe runs, meaning a background build has started. There are also other times as well.
So, I wish to suppress fxcop when built with devenv. Our CI server builds using msbuild, so no problem there.
BTW, if there is a way to disable the background builds, that could be great.
There is a property BuildingInsideVisualStudio which will tell you this.
For example compare the result when using msbuild.exe and devenv.exe with a .csproj with the following AfterBuild target defined
<Target Name="AfterBuild">
<Message Text="BuildingInsideVisualStudio: $(BuildingInsideVisualStudio)" Importance="high"/>
</Target>
Sayed Ibrahim Hashimi
My Book: Inside the Microsoft Build Engine : Using MSBuild and Team Foundation Build
The only thing I can think of is to either
create a different build type (such as debug_and_rules, release_and_rules, etc). I think ms build could read this.
have your CI server call the fxcop exe separate from building the project. This is what I used to do before fxcop was integrated into VS.
have msbuild set a setting or compiler flag that ms build could read. I'm not sure if this would work.
The background compiler was added in VS 2008 to C#, and as far as I know, is not configurable. VS 2010 is supposed to be ultra configurable so maybe that will change
Edit: formatted my list a little better