WinUI 3.0

From bibbleWiki
Jump to navigation Jump to search

Introduction

Well it has been a while since I have done desktop apps and WinUI 3.0 seems to be the way ahead.

VS Code

So I don't want to remember another set of keyboard shortcuts. I know VS Code is not the most liked out there but I know it better than other options and therefore wanted to use it with this. The approach I took was to build an empty app in the Visual Studio Community Edition and switch to VS Code. Then a truple of bits to make it build. First .vscode/launch.json

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": ".NET Launch (PlaylistFixer)",
      "type": "coreclr",
      "request": "launch",
      "preLaunchTask": "build",
      "program": "${workspaceFolder}/bin/x64/Debug/net8.0-windows10.0.19041.0/win-x64/PlaylistFixer.exe",
      "args": [],
      "cwd": "${workspaceFolder}",
      "console": "internalConsole",
      "stopAtEntry": false
    }
  ]
}

Next .vscode/tasks.json

{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "build",
      "command": "dotnet",
      "type": "process",
      "args": [
        "build",
        "${workspaceFolder}/PlaylistFixer.csproj",
        "/property:GenerateFullPaths=true",
        "/consoleloggerparameters:NoSummary",
        "-p:Platform=x64" 
      ],
      "problemMatcher": "$msCompile"
    }
  ]
}

If you press F5 at this point you will get in the debug window the following

Exception thrown: 'System.Runtime.InteropServices.COMException' in System.Private.CoreLib.dll
The program '[30344] PlaylistFixer.exe' has exited with code -532462766 (0xe0434352).

This was the step which took a bit of time and was solved by robot after few googles (around 2 hours). Disappointed in my own robots not getting this. Anyway this was what did it for me and hope someone finds it.

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
    <TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
    <RootNamespace>PlaylistFixer</RootNamespace>
    <ApplicationManifest>app.manifest</ApplicationManifest>
    <Platforms>x86;x64;ARM64</Platforms>
    <WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>
    <RuntimeIdentifiers>win-x86;win-x64;win-arm64</RuntimeIdentifiers>
    <RuntimeIdentifier Condition="'$(RuntimeIdentifier)' == ''">win-x64</RuntimeIdentifier>
    <PublishProfile>win-$(Platform).pubxml</PublishProfile>
    <UseWinUI>true</UseWinUI>
    <WinUISDKReferences>false</WinUISDKReferences>
    <EnableMsixTooling>true</EnableMsixTooling>
    <Nullable>enable</Nullable>
  </PropertyGroup>
  <ItemGroup>
    <None Remove="CacheSearchControl.xaml" />
    <None Remove="SettingsControl.xaml" />
  </ItemGroup>

  <ItemGroup>
    <Content Include="Assets\SplashScreen.scale-200.png" />
    <Content Include="Assets\LockScreenLogo.scale-200.png" />
    <Content Include="Assets\Square150x150Logo.scale-200.png" />
    <Content Include="Assets\Square44x44Logo.scale-200.png" />
    <Content Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png" />
    <Content Include="Assets\StoreLogo.png" />
    <Content Include="Assets\Wide310x150Logo.scale-200.png" />
  </ItemGroup>

  <ItemGroup>
    <Manifest Include="$(ApplicationManifest)" />
  </ItemGroup>

  <ItemGroup Condition="'$(DisableMsixProjectCapabilityAddedByProject)'!='true' and '$(EnableMsixTooling)'=='true'">
    <ProjectCapability Include="Msix" />
  </ItemGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.7463" />
    <PackageReference Include="Microsoft.WindowsAppSDK" Version="1.8.260101001" />
  </ItemGroup>
  <ItemGroup>
    <Page Update="SettingsControl.xaml">
      <Generator>MSBuild:Compile</Generator>
    </Page>
  </ItemGroup>
  <ItemGroup>
    <Page Update="CacheSearchControl.xaml">
      <Generator>MSBuild:Compile</Generator>
    </Page>
  </ItemGroup>

  <PropertyGroup Condition="'$(DisableHasPackageAndPublishMenuAddedByProject)'!='true' and '$(EnableMsixTooling)'=='true'">
    <HasPackageAndPublishMenu>true</HasPackageAndPublishMenu>
  </PropertyGroup>

  <!-- Publish Properties -->
  <PropertyGroup>
    <PublishReadyToRun Condition="'$(Configuration)' == 'Debug'">False</PublishReadyToRun>
    <PublishReadyToRun Condition="'$(Configuration)' != 'Debug'">True</PublishReadyToRun>
    <PublishTrimmed Condition="'$(Configuration)' == 'Debug'">False</PublishTrimmed>
    <PublishTrimmed Condition="'$(Configuration)' != 'Debug'">True</PublishTrimmed>
  </PropertyGroup>
</Project>

Lastly had issue with the intellisence find the code. This is because the files and now where C# Dev Kit expects. To fix this you need to generate the code. The first attempt from https://stackoverflow.com/questions/79573403/vs-code-c-sharp-dev-kit-shows-cs0103-errors-for-wpf-initializecomponent-despit did work but gave warnings of duplicates so I asked the robot for a better approach. After much discussion and the treat of ChatGPT it came up with adding

  <ItemGroup Condition="'$(DesignTimeBuild)' == 'true'">
    <Compile Include="obj/x64/Debug/net8.0-windows10.0.19041.0/win-x64/*.cs">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon></DependentUpon>
    </Compile>
  </ItemGroup>

Using it

Well not impressed. You cannot browse for a file from a predefined existing folder. This is not good. Instead I had to make my own control which used the native, and from many years in my past, "comdlg32.dll". I would put a large amount of money this is born out security issues and the filesystem.

Errors in Xaml

I could not find a reasonable approach to get the errors from the xamlcompiler. I tried using the build log with no joy

dotnet build -bl

Tried running the command on the command line with no output

"C:\Users\iwise\.nuget\packages\microsoft.windowsappsdk.winui\1.8.251222000\buildTransitive\..\tools\net6.0\..\net472\XamlCompiler.exe" "C:\dev\projects\PlaylistFixer\Build\obj\PlaylistFixerApp\debug_win-x64\\input.json" "C:\dev\projects\PlaylistFixer\Build\obj\PlaylistFixerApp\debug_win-x64\\output.json"

Visual Studio does this perfectly though but I wanted to avoid using Visual Studio where possible.