From wpf-dev-pack
Manages WPF application lifecycle events including Startup, Exit, SessionEnding, and single instance detection. Use for app initialization, shutdown handling, and multi-instance prevention.
npx claudepluginhub christian289/dotnet-with-claudecode --plugin wpf-dev-packThis skill uses the workspace's default tool permissions.
> **MVVM Framework Rule**: `.claude/rules/dotnet/wpf/mvvm-framework.md` 설정에 따라 코드 스타일이 결정됩니다.
Generates design tokens/docs from CSS/Tailwind/styled-components codebases, audits visual consistency across 10 dimensions, detects AI slop in UI.
Records polished WebM UI demo videos of web apps using Playwright with cursor overlay, natural pacing, and three-phase scripting. Activates for demo, walkthrough, screen recording, or tutorial requests.
Delivers idiomatic Kotlin patterns for null safety, immutability, sealed classes, coroutines, Flows, extensions, DSL builders, and Gradle DSL. Use when writing, reviewing, refactoring, or designing Kotlin code.
MVVM Framework Rule:
.claude/rules/dotnet/wpf/mvvm-framework.md설정에 따라 코드 스타일이 결정됩니다. Prism 9 사용 시 → PRISM.md 참조
Managing application startup, shutdown, and runtime behavior.
Advanced Patterns: See ADVANCED.md for single instance, settings, and activation handling.
Application Start
│
├─ App Constructor
├─ App.OnStartup() / Startup event
├─ MainWindow Constructor
├─ MainWindow.Loaded event
│
▼
Running State
│
├─ Activated / Deactivated events
├─ SessionEnding event (logoff/shutdown)
│
▼
Shutdown Initiated
│
├─ Window.Closing event (can cancel)
├─ Window.Closed event
├─ App.OnExit() / Exit event
│
▼
Application End
<Application x:Class="MyApp.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml"
Startup="Application_Startup"
Exit="Application_Exit"
SessionEnding="Application_SessionEnding">
<Application.Resources>
<!-- Resources -->
</Application.Resources>
</Application>
namespace MyApp;
using System.Windows;
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
// Process command line arguments
ProcessCommandLineArgs(e.Args);
// Initialize services
InitializeServices();
// Create and show main window manually (if StartupUri not set)
var mainWindow = new MainWindow();
mainWindow.Show();
}
private void ProcessCommandLineArgs(string[] args)
{
foreach (var arg in args)
{
if (arg.Equals("--debug", StringComparison.OrdinalIgnoreCase))
{
// Enable debug mode
}
else if (arg.StartsWith("--file=", StringComparison.OrdinalIgnoreCase))
{
var filePath = arg[7..];
// Process file
}
}
}
private void InitializeServices()
{
// DI container setup, logging, etc.
}
}
<!-- Default: When last window closes -->
<Application ShutdownMode="OnLastWindowClose">
<!-- When main window closes -->
<Application ShutdownMode="OnMainWindowClose">
<!-- Only when Shutdown() is called explicitly -->
<Application ShutdownMode="OnExplicitShutdown">
protected override void OnExit(ExitEventArgs e)
{
// Save settings
SaveUserSettings();
// Cleanup resources
DisposeServices();
// Set exit code
e.ApplicationExitCode = 0;
base.OnExit(e);
}
// MainWindow.xaml.cs
private void Window_Closing(object sender, CancelEventArgs e)
{
// Check for unsaved changes
if (HasUnsavedChanges)
{
var result = MessageBox.Show(
"You have unsaved changes. Do you want to save before closing?",
"Unsaved Changes",
MessageBoxButton.YesNoCancel,
MessageBoxImage.Warning);
switch (result)
{
case MessageBoxResult.Yes:
SaveChanges();
break;
case MessageBoxResult.Cancel:
e.Cancel = true; // Prevent closing
return;
}
}
}
private void Application_SessionEnding(object sender, SessionEndingCancelEventArgs e)
{
// e.ReasonSessionEnding: Logoff or Shutdown
if (HasCriticalOperation)
{
var result = MessageBox.Show(
"A critical operation is in progress. Are you sure you want to close?",
"Session Ending",
MessageBoxButton.YesNo,
MessageBoxImage.Warning);
if (result == MessageBoxResult.No)
{
e.Cancel = true; // Try to prevent session end
return;
}
}
// Perform emergency save
EmergencySave();
}
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
// Handle UI thread exceptions
DispatcherUnhandledException += OnDispatcherUnhandledException;
}
private void OnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
// Log the exception
LogException(e.Exception);
// Show error dialog
MessageBox.Show(
$"An unexpected error occurred:\n{e.Exception.Message}",
"Error",
MessageBoxButton.OK,
MessageBoxImage.Error);
// Prevent application crash (handle the exception)
e.Handled = true;
}
}
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
// Handle non-UI thread exceptions
AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
// Handle Task exceptions
TaskScheduler.UnobservedTaskException += OnUnobservedTaskException;
}
private void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
var exception = e.ExceptionObject as Exception;
LogException(exception);
if (e.IsTerminating)
{
EmergencySave();
}
}
private void OnUnobservedTaskException(object? sender, UnobservedTaskExceptionEventArgs e)
{
LogException(e.Exception);
e.SetObserved(); // Prevent crash
}