{"id":21974419,"url":"https://github.com/abdes/winui-override-main","last_synced_at":"2026-05-07T13:46:26.122Z","repository":{"id":207356509,"uuid":"719040684","full_name":"abdes/winui-override-main","owner":"abdes","description":"A WinUI 3 visual studio solution for an application that uses a custom `Main` entry point instead of the default XAML entry point.","archived":false,"fork":false,"pushed_at":"2023-11-15T12:30:26.000Z","size":22,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-06-26T16:09:16.035Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/abdes.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-11-15T10:22:19.000Z","updated_at":"2025-06-21T10:11:33.000Z","dependencies_parsed_at":"2024-11-29T15:46:25.223Z","dependency_job_id":"e8e5062e-d6b2-491b-a064-a4a8d8d3daf9","html_url":"https://github.com/abdes/winui-override-main","commit_stats":null,"previous_names":["abdes/winui-override-main"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/abdes/winui-override-main","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abdes%2Fwinui-override-main","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abdes%2Fwinui-override-main/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abdes%2Fwinui-override-main/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abdes%2Fwinui-override-main/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/abdes","download_url":"https://codeload.github.com/abdes/winui-override-main/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abdes%2Fwinui-override-main/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262099728,"owners_count":23258670,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-29T15:45:14.870Z","updated_at":"2026-05-07T13:46:26.085Z","avatar_url":"https://github.com/abdes.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"﻿# Override `Main` in a WinUI Application\n\nI was writing a WinUI 3 application that uses the [Entity\nFramework](https://learn.microsoft.com/en-us/ef/) and the [Microsoft Hosting\nExtensions](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.hosting?view=dotnet-plat-ext-7.0)\nfor IoC.\n\nMy migrations were not working. After a lot of troubleshooting I figured out\nthat the `EF` migrations tool has some specific assumptions on the order of\ninitializing the `Host`, the `Services` and the `Application` itself. Such fine\ngrained control is not possible using the default generated XAML entry point.\n\n➡ How to properly override the default generated XAML entry point?\n\n## The default generated `Main` entry point\n\nIf we check the executable for the application we can see that the `Main` entry\npoint is actually in a class called `Program`. That class is generated by the\nXAML compiler along with the `App` class. If we take a look in the `obj` folder\nof the `App` project, there is a file named `App.g.i.cs` which contains some\npartial code generated for the App class but also code that is conditionally\nincluded based on the presence of the `DISABLE_XAML_GENERATED_MAIN` compilation\nconstant, defining a new class called `Program` with the `Main` entry point\ndefinition.\n\n```csharp\n#if !DISABLE_XAML_GENERATED_MAIN\n    /// \u003csummary\u003e\n    /// Program class\n    /// \u003c/summary\u003e\n    public static class Program\n    {\n        [global::System.Runtime.InteropServices.DllImport(\"Microsoft.ui.xaml.dll\")]\n        private static extern void XamlCheckProcessRequirements();\n\n        [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"Microsoft.UI.Xaml.Markup.Compiler\",\" 3.0.0.2309\")]\n        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\n        [global::System.STAThreadAttribute]\n        static void Main(string[] args)\n        {\n            XamlCheckProcessRequirements();\n            \n            global::WinRT.ComWrappersSupport.InitializeComWrappers();\n            global::Microsoft.UI.Xaml.Application.Start((p) =\u003e {\n                var context = new global::Microsoft.UI.Dispatching.DispatcherQueueSynchronizationContext(global::Microsoft.UI.Dispatching.DispatcherQueue.GetForCurrentThread());\n                global::System.Threading.SynchronizationContext.SetSynchronizationContext(context);\n                new App();\n            });\n        }\n    }\n#endif\n```\n\n## Using our own `Main` entry point\n\nThe easiest way to achieve our goal is obviously to define the\nDISABLE_XAML_GENERATED_MAIN constant, and include your own `Program.cs`.\n\nThe first change to make is to `App.csproj` project definition file.\n\n```xml\n+\t\t\u003c!-- Use our own Main entry point so we can control the HostBuilder --\u003e\n+\t\t\u003cAllowUnsafeBlocks\u003etrue\u003c/AllowUnsafeBlocks\u003e\n+\t\t\u003cDefineConstants\u003eDISABLE_XAML_GENERATED_MAIN\u003c/DefineConstants\u003e\n+\t\t\u003cStartupObject\u003eApp.Program\u003c/StartupObject\u003e\n```\n\nWe define the `DISABLE_XAML_GENERATED_MAIN` compile time constant and provide\nour own `Program.cs`. The majority of the [`Program.cs`](App/Program.cs)\ncontent is copied from the default one, which will ensure that the proper\ninitialization and checks are made as if we were using the default entry point.\nAny additional pre- or post- initialization work needs to be placed\nappropriately.\n\n**ℹ NOTE 1:**\n\u003e `AllowUnsafeBlocks` is not really needed for the custom entry point but is\n\u003e required to use `LibraryImport` which is preferred to `DLLImport`.\n\n**ℹ NOTE 2:**\n\u003e In the recent versions of the `WindowsAppSDK`, both\n\u003e `XamlCheckProcessRequirements()` and `InitializeComWrappers()` don't do\n\u003e anything. It is better however to keep them for maximum compatibility as they\n\u003e are still there in the default generated entry point.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fabdes%2Fwinui-override-main","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fabdes%2Fwinui-override-main","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fabdes%2Fwinui-override-main/lists"}