microsoft / msix-packaging

MSIX SDK
MIT License
963 stars 163 forks source link

[BUG] Build fails trying to create .msixbundle for a .NET 7.0 desktop app #557

Open clovett opened 1 year ago

clovett commented 1 year ago

Project MSIX SDK or Win7Msix

Describe the bug

Cannot create .msixbundle for .NET 7.0 desktop app.

To Reproduce Steps to reproduce the behavior:

  1. load the attached solution: WpfApp1.zip
  2. build it
  3. right click WapProjTemplate1 -> Publish -> Create app packages

Notice that the build for "Configuration: Debug Any CPUis attempting to build with/platform:x86 ` and so the packaging fails with "1>There was a mismatch between the processor architecture of the project being built "MSIL"...

This does not happen when using .NET 4.8. In this case the build does build

Expected behavior

It should "just work".

Screenshots

Platform

Windows 11, VS 2022, .NET 7.0

Additional context

I isolated this from the real app that I'm building where you can see the MyMoneyPackage project working on .NET 4.8:

In the master branch. If you checkout the "net7" branch then you will see this error.

sbanni commented 1 year ago

The packaging project is attempting to create a "SelfContained" application, that is it has everything it needs to run built in. Because of this a platform needs to be specified and we default to x86, to fix the error you need to make sure all the builds are using the same configurations.

lovettchris commented 1 year ago

They all use AnyCPU, see https://github.com/MoneyTools/MyMoney.Net/blob/net7/Source/WPF/MyMoney/MyMoney.csproj.

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
    <NoWarn>1701;1702;1416</NoWarn>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
    <NoWarn>1701;1702;1416</NoWarn>
  </PropertyGroup>

are you saying I have to change all these to be platform specific ? An msix cannot bundle all (x86, x64, arm) platforms?

sbanni commented 1 year ago

MSIX's are platform specific, AnyCPU really doesn't apply here. You are correct in that for every project you want included in the MSIX you will need to define that Platform e.g. x86/x64/ARM.

lovettchris commented 1 year ago

But the non-.NET 7 version in the master branch of https://github.com/MoneyTools/MyMoney.Net also builds AnyCPU for .NET Framework 4.8 and the MyMoneyPackage.sln works fine with that and gives me this option:

image

and I get this bundle: https://github.com/MoneyTools/MyMoney.Net/releases/download/2.0.1.10/MoneyPackage_2.0.1.10_AnyCPU.msixbundle and if I look inside this bundle I see MoneyPackage_2.0.1.10_AnyCPU.msix and if I look inside that I see the AnyCPU built dll's and no full copy of .NET Framework 4.8... ???

sbanni commented 1 year ago

.NET7 is different than .NET Framework. To run a .NET7 app you need to be either self contained or the runtime SDK has to be installed, there is no requirement like this for .NET Framework as .NET Framework is included in Windows and automatically updated machine-wide by Windows Update. .NET is shipped independently.

lovettchris commented 1 year ago

Yes, I'm aware of that difference, but I'd like to still have a package that assumes the user has already installed .NET 7 or better yet pops up a link to the .NET 7 runtime installer...

lovettchris commented 1 year ago

I suppose I could build my own little .NET 4.8 app that does all this, but why should I have to build an installer :-)

sbanni commented 1 year ago

Ok, if you know the risks, you can accomplish what you want it might just be a little clunky.

You will need to create a publish profile (.pubxml) in your .NET7 app, you can do this through the UI by going through the "Publish" option and creating a new Folder publish profile. You will notice this has options for Self contained or framework dependent.

Then in the Windows Application Packaging Project if you select the project reference to your .NET7 application: image

in the property window you will see a property called "Publishing Profile" which you will set to the publish profile you created in the .NET7 app.

image

You will end up with this in the .wapproj file:

<ProjectReference Include="..\ConsoleApp34\ConsoleApp34.csproj">
  <PublishProfile Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">Properties\PublishProfiles\FolderProfile.pubxml</PublishProfile>
</ProjectReference>

You would probably want to remove the Condition or modify it to suit your needs based on the publish profile properties you specified.

Then in the publish dialog, you would still need to select x86/x64/ARM, but your .NET7 app would be built using whatever platform you specified in the publish profile.

lovettchris commented 1 year ago

Thanks, I tried all that but I still get the same error, did it work for you, can you post back the working repro so I can see what you did exactly?

lovettchris commented 1 year ago

One thing I found which is interesting is that this file C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Microsoft\DesktopBridge\Microsoft.DesktopBridge.targets has a "SetPublishProperties" task that outputs ProjectReferenceWithPublishProps that contains "AdditionalProperties" where one of those properties named "Platform" always comes back with x86.

If I add the following hack things seem to get a bit further along:

    <ItemGroup>
      <ProjectReferenceWithPublishProps>
        <AdditionalProperties>$([System.String]::Copy('%(AdditionalProperties)').Replace('x86','x64'))</AdditionalProperties>
      </ProjectReferenceWithPublishProps>
    </ItemGroup>

Any idea why the DesktopBridge might be hard coding an x86 Platform on me like this?

MisinformedDNA commented 1 year ago

I really don't understand this. Why does it have to assume self-contained, when it can work as a framework-dependent app? Can this option be added?

sbanni commented 1 year ago

MSIX Packages are supposed to be installable without anything else being required. If something is required there is a dependency chain that the store uses to install the Framework packages which get re-used by all applications that have the same dependency. There is no netcore framework package so the only way to guarantee that a MSIX package can be run on any machine is to make it SelfContained.

This is configurable, if you know you don't want SelfContained, use the above mentioned workflow to create the publish profile.

W.r.t to the original issue, in your example project of WpfApp1, if I wanted to make it "just work" the easiest thing to do would be to modify the WapProjTemplate1 configurations for AnyCPU to be Platform=x86. This way when the WpfApp1 defaults to x86 when it sees AnyCPU the platforms will match.

lovettchris commented 1 year ago

You are right remapping AnyCPU to x86 works, but then my final installed app really runs as 32 bit: image

If I have to pick a platform I'd prefer x64, but when I try and remap it to x64 I get this error:

Severity    Code    Description Project File    Line    Suppression State
Error       There was a mismatch between the processor architecture of the project being built "AMD64" and the processor architecture of the reference "D:\temp\WpfApp1\WpfApp1\bin\x86\Release\net7.0-windows\win-x86\WpfApp1.dll", "x86". This mismatch may cause runtime failures. Please consider changing the targeted processor architecture of your project through the Configuration Manager so as to align the processor architectures between your project and references, or take a dependency on references with a processor architecture that matches the targeted processor architecture of your project. WapProjTemplate1    C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Current\Bin\amd64\Microsoft.Common.CurrentVersion.targets  2353    

ALso, ClickOnce apps do seem to have a way to bootstrap .NET 7.0 apps. For example, if you try this ClickOnce installerit automatically prompts you to install the .NET 7.0 desktop runtime.

surajraja commented 1 year ago

We are having the same issue , is there an fix for it.

lovettchris commented 1 year ago

I'm still wishing for one... for now I'm using ClickOnce instead, but I would really like to also be able to offer an msix installer so people can install my app again using winget.