Skip to content

Latest commit

 

History

History
148 lines (106 loc) · 4.69 KB

File metadata and controls

148 lines (106 loc) · 4.69 KB

Meziantou.Framework.Win32.RestartManager

A .NET library that wraps the Windows Restart Manager API to detect which processes are locking files and manage application restarts.

Usage

This library provides functionality to interact with the Windows Restart Manager (RM) API, which helps identify processes that have locks on files and manage graceful shutdown and restart of applications.

Check if a File is Locked

The simplest way to check if a file is currently locked by any process:

using Meziantou.Framework.Win32;

var path = @"C:\path\to\file.txt";
if (RestartManager.IsFileLocked(path))
{
    Console.WriteLine("File is locked by one or more processes");
}

Find Processes Locking a File

Get a list of all processes that have locks on a specific file:

The caller owns the returned Process instances and should dispose them.

using Meziantou.Framework.Win32;

var path = @"C:\path\to\file.txt";
var processes = RestartManager.GetProcessesLockingFile(path);

foreach (var process in processes)
{
    Console.WriteLine($"Process {process.ProcessName} (PID: {process.Id}) is locking the file");
    process.Dispose();
}

Find Processes Locking Several Files

Registering resources performs relatively expensive write operations, so checking many files with one session is significantly cheaper than calling GetProcessesLockingFile in a loop:

Registrations are persisted to the registry, so one session can only hold a bounded number of paths. A very large set fails with ERROR_WRITE_FAULT (29) and should be split across several sessions.

using Meziantou.Framework.Win32;

var processes = RestartManager.GetProcessesLockingFiles(
[
    @"C:\path\to\file1.txt",
    @"C:\path\to\file2.txt",
]);

foreach (var process in processes)
{
    Console.WriteLine($"Process {process.ProcessName} (PID: {process.Id}) is locking at least one of the files");
    process.Dispose();
}

Manual Session Management

For more control, you can create and manage a Restart Manager session manually:

using Meziantou.Framework.Win32;

// Create a new session
using var session = RestartManager.CreateSession();

// Register one or more files to monitor
session.RegisterFile(@"C:\path\to\file.txt");
session.RegisterFiles(new[] { @"C:\path\to\file1.txt", @"C:\path\to\file2.txt" });

// Check if any registered resources are locked
if (session.IsResourcesLocked())
{
    // Get the processes locking the resources
    var processes = session.GetProcessesLockingResources();
    foreach (var process in processes)
    {
        Console.WriteLine($"Locked by: {process.ProcessName}");
        process.Dispose();
    }
}

Join an Existing Session

You can join an existing Restart Manager session using its session key:

var sessionKey = "existing-session-key";
using var session = RestartManager.JoinSession(sessionKey);

Shutdown and Restart Applications

The Restart Manager can shut down and restart applications that are locking resources:

using var session = RestartManager.CreateSession();
session.RegisterFile(@"C:\path\to\file.txt");

// A non-zero reboot reason means shutting applications down cannot free the resources,
// and that a system restart is required instead. Check it before shutting anything down.
if (session.IsResourcesLocked() && session.RebootReason != RestartManagerRebootReason.None)
{
    Console.WriteLine($"A system restart is required: {session.RebootReason}");
    return;
}

// Shutdown applications with options
session.Shutdown(RestartManagerShutdownType.ForceShutdown);

// Or with progress callback
session.Shutdown(RestartManagerShutdownType.ForceShutdown, percentComplete =>
{
    Console.WriteLine($"Shutdown progress: {percentComplete}%");
});

// Restart applications after shutdown
session.Restart(percentComplete =>
{
    Console.WriteLine($"Restart progress: {percentComplete}%");
});

Shutdown Types

The RestartManagerShutdownType enum provides options for how applications should be shut down:

  • ForceShutdown - Forces unresponsive applications and services to shut down after a timeout period (30 seconds for applications, 20 seconds for services)
  • ShutdownOnlyRegistered - Only shuts down applications that have been registered for restart using RegisterApplicationRestart. If any processes cannot be restarted, no shutdown occurs

Platform Support

This library is Windows-only and requires Windows Vista or later (Windows 6.0+).

Additional Resources