Tworząc aplikację WPF czasami zachodzi potrzeba napisania własnej metody Main(). Przeglądając pliki znajdujące się w solucji można natknąć się pliki *.xaml i powiązanie z nimi *.xaml.cs oraz pliki kodu *.cs. Dopóki nie trzeba zrobić czegoś nie standardowego to często nie ma potrzeby, aby zagłębiać się w różnego rodzaju mechanizmy. Takim mechanizmem może być start aplikacji WPF.

Ostatnio potrzebowałem dodać własną metodę Main(). Sądziłem, że będzie to proste – nowa klasa i odpowiedni kod. Oczywiście wcześniej sprawdziłem, czy nie ma tej metody już zdefiniowanej w plikach solucji.

Kompilując program otrzymałem następujący błąd:

Error 1 Program …\WpfApplication1\WpfApplication1\obj\x86\Debug\WpfApplication1.exe’ has more than one entry point defined: ‚WpfApplication1.Program.Main()’.  Compile with /main to specify the type that contains the entry point.    …\WpfApplication1\WpfApplication1\Program.cs 15 28 WpfApplication1

Error 2 Program …\WpfApplication1\WpfApplication1\obj\x86\Debug\WpfApplication1.exe’ has more than one entry point defined: ‚WpfApplication1.App.Main()’.  Compile with /main to specify the type that contains the entry point.                …\WpfApplication1\WpfApplication1\obj\x86\Debug\App.g.cs 61 28 WpfApplication1

Podwójne kliknięcie drugiego błędu otworzyło plik App.g.cs, który znajduje się w katalogu obj\x86\Debug:

/// <summary>
/// App
/// </summary>
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "4.0.0.0")]
public partial class App : System.Windows.Application 
{
  /// <summary>
  /// InitializeComponent
  /// </summary>
  [System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public void InitializeComponent() 
  {
    #line 4 "..\..\..\App.xaml"
    this.StartupUri = new System.Uri("MainWindow.xaml", System.UriKind.Relative);

    #line default
    #line hidden
  }

  /// <summary>
  /// Application Entry Point.
  /// </summary>
  [System.STAThreadAttribute()]
  [System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public static void Main() 
  {
    WpfApplication1.App app = new WpfApplication1.App();
    app.InitializeComponent();
    app.Run();
  }
}

I jak się okazało znajduje się w nim metoda public static void Main(). W sytuacji, gdy nie można znaleźć tego pliku należy przebudować solucję ponieważ plik ten jest generowany automatycznie w trakcie kompilacji. Takie zachowanie powoduje, że każda zmiana w tym pliku będzie nadpisywany w trakcie każdorazowej kompilacji kodu.

Przejdźmy do sedna problemu. Aby użyć własnej metody Main() należy wykonać dwie czynności:

  • wskazać miejsce gdzie znajduje się interesująca metoda Main() – należy zmienić parametr Application -> Startup object we właściwościach projektu,
    Wybór Startup Object
  • wyłączyć automatyczne generowanie metody Main() poprzez zmianę właściwości Build Action dla App.xaml z ApplicationDefinition na Page.

    Wybór Build Action

    Wybór Build Action

Po wprowadzeniu tych dwóch zmian aplikacja powinna nam się skompilować bez problemu.