WPF defines its own Main()
method. How should I go about replacing it with my own Main
method that (normally) opens the WPF MainWindow
(e.g. to add a non-WPF scripting mode via command-line arguments)?
Some examples depict changing App.xaml's Build Action from ApplicationDefinition
to Page
and writing your own Main()
that instantiates the App
class and calls its Run()
method, but this can produce some unwanted consequences in the resolution of application-wide resources in App.xaml.
Instead, I suggest making your own Main()
in its own class and setting the Startup Object to that class in the project properties:
public class EntryPoint {
[STAThread]
public static void Main(string[] args) {
if (args != null && args.Length > 0) {
// ...
} else {
var app = new App();
app.InitializeComponent();
app.Run();
}
}
}
I do this to take advantage of some AppDomain
events that must be subscribed to before anything else happens (such as AssemblyResolve
). The unwanted consequences of setting App.xaml to Page
that I experienced included my UserControl
Views (M-V-VM) not resolving resources held in App.xaml during design-time.
Main()
just instantiates App
and calls Run()
. The Startup
event is fired in System.Windows.Application
's constructor. Run()
attaches a Dispatcher
and begins the message pump. InitializeComponent()
should be called in Apps
's constructor. Is it not? –
Ballata App
and call InitializeComponent()
there to avoid App.Main()
. The rest I oversimplified for brevity. Startup
is fired by Application.OnStartup()
and only the derived App
class's constructor can subscribe to Startup
before it is fired. This works because Application
's constructor asynchronously invokes a method that calls OnStartup()
, so it actually runs after base and derived constructors have finished. –
Ballata App.Main()
, you could just add this and set it as the entry point for your project and call App.Main()
directly. –
Hecto Typically I edit App.xaml
to add this support:
<Application x:Class="SomeNamespace.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Startup="Application_Startup">
The relevant part being I changed from StartupUri
to Startup
with an event handler in App.xaml.cs
. Here is an example:
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
private void Application_Startup(object sender, StartupEventArgs e)
{
int verbose = 0;
var optionSet = new OptionSet
{
{ "v|verbose", "verbose output, repeat for more verbosity.",
arg => verbose++ }
};
var extra = optionSet.Parse(e.Args);
var mainWindow = new MainWindow(verbose);
mainWindow.Show();
}
}
Console.*
output. –
Batrachian guys The problem is that your program has two static Main() methods, that will cause the compiler to complain between; To resolve this, try one of the following:
- Tell the compiler that your static Main() method should be the execution entry point—Set your project’s “Startup object” setting to the class containing your static Main() method (right-click on the project in Solution Explorer, choose “Properties,” then look for the “Startup object” setting under the “Application” tab).
- Turn off auto-generation of App.g.cs’s static Main() method—In Solution Explorer, right click on App.xaml, choose “Properties,” then change the “Build Action” from “ApplicationDefinition” to “Page”.
Create new class with your custom static Main method. At the end of this method just call original App.Main() generated by WPF:
public class Program
{
[STAThread]
public static void Main(string[] args)
{
// Your initialization code
App.Main();
}
}
Then set your project’s “Startup object” setting to the class containing your static Main().
Using a custom Main() you might run into problems because StartupUri is not set.
You can use this to set it without headaches in your App class (Don't forget to remove StartupUri from App.xaml and set its Build Action to Page):
[STAThread]
static void Main()
{
App app = new App();
app.InitializeComponent();
app.Run();
}
protected void OnStartup(object sender, StartupEventArgs e)
{
var toUri = new UriTypeConverter();
StartupUri = (Uri)toUri.ConvertFrom("MainWindow.xaml");
...
}
I am posting this answer as none of the above answers work for me. In my case, StartupUri was removed from App.xaml and I was still getting the error. what I end up doing I added the following code to the project file (Foo.csproj) and it solved the issue
<ItemGroup>
<ApplicationDefinition Remove="App.xaml" />
<Page Include="App.xaml" />
</ItemGroup>
© 2022 - 2024 — McMap. All rights reserved.