#pragma warning disable IDE1006 // Naming Styles namespace Vanara.PInvoke; /// Functions, structures and constants used by Windows Restart Manager (rstrtmgr.dll) public static class RstrtMgr { /// CCH_RM_MAX_APP_NAME - maximum character count of application friendly name public const int CCH_RM_MAX_APP_NAME = 255; /// CCH_RM_MAX_SVC_NAME - maximum character count of service short name public const int CCH_RM_MAX_SVC_NAME = 63; /// CCH_RM_SESSION_KEY - character count of text-encoded session key public const int CCH_RM_SESSION_KEY = RM_SESSION_KEY_LEN * 2; /// Uninitialized value for Process ID public const int RM_INVALID_PROCESS = -1; /// Uninitialized value for TS Session ID public const int RM_INVALID_TS_SESSION = -1; /// RM_SESSION_KEY_LEN - size in bytes of binary session key public const int RM_SESSION_KEY_LEN = 16; private const string Lib_Rstrtmgr = "rstrtmgr.dll"; /// /// The RM_WRITE_STATUS_CALLBACK function can be implemented by the user interface that controls the Restart Manager. The /// installer that started the Restart Manager session can pass a pointer to this function to the Restart Manager functions to /// receive a percentage of completeness. The percentage of completeness is strictly increasing and describes the current operation /// being performed and the name of the application being affected. /// /// /// An integer value between 0 and 100 that indicates the percentage of the total number of applications that have either been shut /// down or restarted. /// /// None // https://docs.microsoft.com/en-us/windows/win32/api/restartmanager/nc-restartmanager-rm_write_status_callback // RM_WRITE_STATUS_CALLBACK RmWriteStatusCallback; void RmWriteStatusCallback( UINT nPercentComplete ) {...} [UnmanagedFunctionPointer(CallingConvention.Winapi)] [PInvokeData("restartmanager.h", MSDNShortId = "NC:restartmanager.RM_WRITE_STATUS_CALLBACK")] public delegate void RM_WRITE_STATUS_CALLBACK(uint nPercentComplete); /// Describes the current status of an application that is acted upon by the Restart Manager. /// /// The constants of RM_APP_STATUS can be combined with OR operators. The combination describes the history of actions taken /// by Restart Manager on the application. /// // https://docs.microsoft.com/en-us/windows/win32/api/restartmanager/ne-restartmanager-rm_app_status typedef enum _RM_APP_STATUS { // RmStatusUnknown, RmStatusRunning, RmStatusStopped, RmStatusStoppedOther, RmStatusRestarted, RmStatusErrorOnStop, // RmStatusErrorOnRestart, RmStatusShutdownMasked, RmStatusRestartMasked } RM_APP_STATUS; [PInvokeData("restartmanager.h", MSDNShortId = "NE:restartmanager._RM_APP_STATUS")] [Flags] public enum RM_APP_STATUS { /// The application is in a state that is not described by any other enumerated state. RmStatusUnknown = 0x0, /// The application is currently running. RmStatusRunning = 0x1, /// The Restart Manager has stopped the application. RmStatusStopped = 0x2, /// An action outside the Restart Manager has stopped the application. RmStatusStoppedOther = 0x4, /// The Restart Manager has restarted the application. RmStatusRestarted = 0x8, /// The Restart Manager encountered an error when stopping the application. RmStatusErrorOnStop = 0x10, /// The Restart Manager encountered an error when restarting the application. RmStatusErrorOnRestart = 0x20, /// Shutdown is masked by a filter. RmStatusShutdownMasked = 0x40, /// Restart is masked by a filter. RmStatusRestartMasked = 0x80, } /// Specifies the type of application that is described by the RM_PROCESS_INFO structure. // https://docs.microsoft.com/en-us/windows/win32/api/restartmanager/ne-restartmanager-rm_app_type typedef enum _RM_APP_TYPE { // RmUnknownApp, RmMainWindow, RmOtherWindow, RmService, RmExplorer, RmConsole, RmCritical } RM_APP_TYPE; [PInvokeData("restartmanager.h", MSDNShortId = "NE:restartmanager._RM_APP_TYPE")] public enum RM_APP_TYPE { /// /// The application cannot be classified as any other type. An application of this type can only be shut down by a forced shutdown. /// RmUnknownApp = 0, /// A Windows application run as a stand-alone process that displays a top-level window. RmMainWindow, /// A Windows application that does not run as a stand-alone process and does not display a top-level window. RmOtherWindow, /// The application is a Windows service. RmService, /// The application is Windows Explorer. RmExplorer, /// The application is a stand-alone console application. RmConsole, /// /// A system restart is required to complete the installation because a process cannot be shut down. The process cannot be shut /// down because of the following reasons. The process may be a critical process. The current user may not have permission to /// shut down the process. The process may belong to the primary installer that started the Restart Manager. /// RmCritical = 1000, } /// Specifies the type of modification that is applied to restart or shutdown actions. // https://docs.microsoft.com/en-us/windows/win32/api/restartmanager/ne-restartmanager-rm_filter_action typedef enum // _RM_FILTER_ACTION { RmInvalidFilterAction, RmNoRestart, RmNoShutdown } RM_FILTER_ACTION; [PInvokeData("restartmanager.h", MSDNShortId = "NE:restartmanager._RM_FILTER_ACTION")] public enum RM_FILTER_ACTION { /// An invalid filter action. RmInvalidFilterAction = 0, /// Prevents the restart of the specified application or service. RmNoRestart, /// Prevents the shut down and restart of the specified application or service. RmNoShutdown, } /// Describes the restart or shutdown actions for an application or service. // https://docs.microsoft.com/en-us/windows/win32/api/restartmanager/ne-restartmanager-rm_filter_trigger typedef enum // _RM_FILTER_TRIGGER { RmFilterTriggerInvalid, RmFilterTriggerFile, RmFilterTriggerProcess, RmFilterTriggerService } RM_FILTER_TRIGGER; [PInvokeData("restartmanager.h", MSDNShortId = "NE:restartmanager._RM_FILTER_TRIGGER")] public enum RM_FILTER_TRIGGER { /// An invalid filter trigger. RmFilterTriggerInvalid = 0, /// Modifies the shutdown or restart actions for an application identified by its executable filename. RmFilterTriggerFile, /// Modifies the shutdown or restart actions for an application identified by a RM_UNIQUE_PROCESS structure. RmFilterTriggerProcess, /// Modifies the shutdown or restart actions for a service identified by a service short name. RmFilterTriggerService, } /// Describes the reasons a restart of the system is needed. // https://docs.microsoft.com/en-us/windows/win32/api/restartmanager/ne-restartmanager-rm_reboot_reason typedef enum // _RM_REBOOT_REASON { RmRebootReasonNone, RmRebootReasonPermissionDenied, RmRebootReasonSessionMismatch, // RmRebootReasonCriticalProcess, RmRebootReasonCriticalService, RmRebootReasonDetectedSelf } RM_REBOOT_REASON; [PInvokeData("restartmanager.h", MSDNShortId = "NE:restartmanager._RM_REBOOT_REASON")] [Flags] public enum RM_REBOOT_REASON { /// A system restart is not required. RmRebootReasonNone = 0x0, /// The current user does not have sufficient privileges to shut down one or more processes. RmRebootReasonPermissionDenied = 0x1, /// One or more processes are running in another Terminal Services session. RmRebootReasonSessionMismatch = 0x2, /// A system restart is needed because one or more processes to be shut down are critical processes. RmRebootReasonCriticalProcess = 0x4, /// A system restart is needed because one or more services to be shut down are critical services. RmRebootReasonCriticalService = 0x8, /// A system restart is needed because the current process must be shut down. RmRebootReasonDetectedSelf = 0x10, } /// Configures the shut down of applications. /// /// /// The time to wait before initiating a forced shutdown of applications is specified by the following registry key. HKCU\ /// Control Panel\ Desktop\ HungAppTimeout /// /// /// The time to wait before initiating a forced shutdown of services is specified by the following registry key. HKLM\ /// System\ CurrentControlSet\ Control\ WaitToKillServiceTimeout /// /// // https://docs.microsoft.com/en-us/windows/win32/api/restartmanager/ne-restartmanager-rm_shutdown_type typedef enum // _RM_SHUTDOWN_TYPE { RmForceShutdown, RmShutdownOnlyRegistered } RM_SHUTDOWN_TYPE; [PInvokeData("restartmanager.h", MSDNShortId = "NE:restartmanager._RM_SHUTDOWN_TYPE")] [Flags] public enum RM_SHUTDOWN_TYPE { /// /// Forces unresponsive applications and services to shut down after the timeout period. An application that does not respond to /// a shutdown request by the Restart Manager is forced to shut down after 30 seconds. A service that does not respond to a /// shutdown request is forced to shut down after 20 seconds. These default times can be changed by modifying the registry keys /// described in the Remarks section. /// RmForceShutdown = 0x1, /// /// Shuts down applications if and only if all the applications have been registered for restart using the /// RegisterApplicationRestart function. If any processes or services cannot be restarted, then no processes or services are /// shut down. /// RmShutdownOnlyRegistered = 0x10, } /// /// Modifies the shutdown or restart actions that are applied to an application or service. The primary installer can call the /// RmAddFilter function multiple times. The most recent call overrides any previous modifications to the same file, process, /// or service. /// /// A handle to an existing Restart Manager session. /// /// A pointer to a null-terminated string value that contains the full path to the application's executable file. /// Modifications to shutdown or restart actions are applied for the application that is referenced by the full path. This parameter /// must be NULL if the Application or strServiceShortName parameter is non- NULL. /// /// /// A pointer to a RM_UNIQUE_PROCESS structure for the application. Modifications to shutdown or restart actions are applied for the /// application that is referenced by the RM_UNIQUE_PROCESS structure. This parameter must be NULL if the strFilename /// or strShortServiceName parameter is non- NULL. /// /// /// A pointer to a null-terminated string value that contains the short service name. Modifications to shutdown or restart /// actions are applied for the service that is referenced by short service filename. This parameter must be NULL if the /// strFilename or Application parameter is non- NULL. /// /// An RM_FILTER_ACTION enumeration value that specifies the type of modification to be applied. /// /// This is the most recent error received. The function can return one of the system error codes that are defined in Winerror.h. /// /// /// Value /// Meaning /// /// /// ERROR_SUCCESS 0 /// The function completed successfully. /// /// /// ERROR_BAD_ARGUMENTS 160 /// /// One or more arguments are not correct. This error value is returned by the Restart Manager function if a NULL pointer or 0 is /// passed in as a parameter that requires a non-null and non-zero value. /// /// /// /// ERROR_SESSION_CREDENTIAL_CONFLICT 1219 /// This error is returned when a secondary installer calls this function. This function is only available to primary installers. /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/restartmanager/nf-restartmanager-rmaddfilter DWORD RmAddFilter( DWORD // dwSessionHandle, LPCWSTR strModuleName, RM_UNIQUE_PROCESS *pProcess, LPCWSTR strServiceShortName, RM_FILTER_ACTION FilterAction ); [DllImport(Lib_Rstrtmgr, SetLastError = false, ExactSpelling = true)] [PInvokeData("restartmanager.h", MSDNShortId = "NF:restartmanager.RmAddFilter")] public static extern Win32Error RmAddFilter(uint dwSessionHandle, [Optional, MarshalAs(UnmanagedType.LPWStr)] string? strModuleName, in RM_UNIQUE_PROCESS pProcess, [Optional, MarshalAs(UnmanagedType.LPWStr)] string? strServiceShortName, RM_FILTER_ACTION FilterAction); /// /// Modifies the shutdown or restart actions that are applied to an application or service. The primary installer can call the /// RmAddFilter function multiple times. The most recent call overrides any previous modifications to the same file, process, /// or service. /// /// A handle to an existing Restart Manager session. /// /// A pointer to a null-terminated string value that contains the full path to the application's executable file. /// Modifications to shutdown or restart actions are applied for the application that is referenced by the full path. This parameter /// must be NULL if the Application or strServiceShortName parameter is non- NULL. /// /// /// A pointer to a RM_UNIQUE_PROCESS structure for the application. Modifications to shutdown or restart actions are applied for the /// application that is referenced by the RM_UNIQUE_PROCESS structure. This parameter must be NULL if the strFilename /// or strShortServiceName parameter is non- NULL. /// /// /// A pointer to a null-terminated string value that contains the short service name. Modifications to shutdown or restart /// actions are applied for the service that is referenced by short service filename. This parameter must be NULL if the /// strFilename or Application parameter is non- NULL. /// /// An RM_FILTER_ACTION enumeration value that specifies the type of modification to be applied. /// /// This is the most recent error received. The function can return one of the system error codes that are defined in Winerror.h. /// /// /// Value /// Meaning /// /// /// ERROR_SUCCESS 0 /// The function completed successfully. /// /// /// ERROR_BAD_ARGUMENTS 160 /// /// One or more arguments are not correct. This error value is returned by the Restart Manager function if a NULL pointer or 0 is /// passed in as a parameter that requires a non-null and non-zero value. /// /// /// /// ERROR_SESSION_CREDENTIAL_CONFLICT 1219 /// This error is returned when a secondary installer calls this function. This function is only available to primary installers. /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/restartmanager/nf-restartmanager-rmaddfilter DWORD RmAddFilter( DWORD // dwSessionHandle, LPCWSTR strModuleName, RM_UNIQUE_PROCESS *pProcess, LPCWSTR strServiceShortName, RM_FILTER_ACTION FilterAction ); [DllImport(Lib_Rstrtmgr, SetLastError = false, ExactSpelling = true)] [PInvokeData("restartmanager.h", MSDNShortId = "NF:restartmanager.RmAddFilter")] public static extern Win32Error RmAddFilter(uint dwSessionHandle, [Optional, MarshalAs(UnmanagedType.LPWStr)] string? strModuleName, [In, Optional] IntPtr pProcess, [Optional, MarshalAs(UnmanagedType.LPWStr)] string? strServiceShortName, RM_FILTER_ACTION FilterAction); /// /// Cancels the current RmShutdown or RmRestart operation. This function must be called from the application that has started the /// session by calling the RmStartSession function. /// /// A handle to an existing session. /// /// This is the most recent error received. The function can return one of the system error codes that are defined in Winerror.h. /// /// /// Value /// Meaning /// /// /// ERROR_SUCCESS 0 /// A cancellation of the current operation is requested. /// /// /// ERROR_BAD_ARGUMENTS 160 /// /// One or more arguments are not correct. This error value is returned by the Restart Manager function if a NULL pointer or 0 is /// passed in a parameter that requires a non-null and non-zero value. /// /// /// /// ERROR_OUTOFMEMORY 14 /// A Restart Manager operation could not complete because not enough memory was available. /// /// /// ERROR_INVALID_HANDLE 6 /// No Restart Manager session exists for the handle supplied. /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/restartmanager/nf-restartmanager-rmcancelcurrenttask DWORD // RmCancelCurrentTask( DWORD dwSessionHandle ); [DllImport(Lib_Rstrtmgr, SetLastError = false, ExactSpelling = true)] [PInvokeData("restartmanager.h", MSDNShortId = "NF:restartmanager.RmCancelCurrentTask")] public static extern Win32Error RmCancelCurrentTask(uint dwSessionHandle); /// /// Ends the Restart Manager session. This function should be called by the primary installer that has previously started the /// session by calling the RmStartSession function. The RmEndSession function can be called by a secondary installer that is /// joined to the session once no more resources need to be registered by the secondary installer. /// /// A handle to an existing Restart Manager session. /// /// This is the most recent error received. The function can return one of the system error codes that are defined in Winerror.h. /// /// /// Value /// Meaning /// /// /// ERROR_SUCCESS 0 /// The function completed successfully. /// /// /// ERROR_SEM_TIMEOUT 121 /// /// A Restart Manager function could not obtain a Registry write mutex in the allotted time. A system restart is recommended because /// further use of the Restart Manager is likely to fail. /// /// /// /// ERROR_WRITE_FAULT 29 /// An operation was unable to read or write to the registry. /// /// /// ERROR_OUTOFMEMORY 14 /// A Restart Manager operation could not complete because not enough memory was available. /// /// /// ERROR_INVALID_HANDLE 6 /// An invalid handle was passed to the function. No Restart Manager session exists for the handle supplied. /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/restartmanager/nf-restartmanager-rmendsession DWORD RmEndSession( DWORD // dwSessionHandle ); [DllImport(Lib_Rstrtmgr, SetLastError = false, ExactSpelling = true)] [PInvokeData("restartmanager.h", MSDNShortId = "NF:restartmanager.RmEndSession")] public static extern Win32Error RmEndSession(uint dwSessionHandle); /// /// Lists the modifications to shutdown and restart actions that have already been applied by the RmAddFilter function. The function /// returns a pointer to a buffer containing information about the modifications which have been applied. /// /// A handle to an existing Restart Manager session. /// A pointer to a buffer that contains modification information. /// The size of the buffer that contains modification information in bytes. /// The number of bytes needed in the buffer. /// /// This is the most recent error received. The function can return one of the system error codes that are defined in Winerror.h. /// /// /// Value /// Meaning /// /// /// ERROR_SUCCESS 0 /// The function completed successfully. /// /// /// ERROR_BAD_ARGUMENTS 160 /// /// One or more arguments are not correct. This error value is returned by the Restart Manager function if a NULL pointer or 0 is /// passed in as a parameter that requires a non-null and non-zero value. /// /// /// /// ERROR_MORE_DATA 234 /// /// This error value is returned by the RmGetFilterList function if the pbFilterBuf buffer is too small to hold all the application /// information in the list or if cbFilterBufNeeded was not specified. /// /// /// /// ERROR_SESSION_CREDENTIAL_CONFLICT 1219 /// This error is returned when a secondary installer calls this function. This function is only available to primary installers. /// /// /// /// The returned pbFilterBuf buffer has to be typecast to RM_FILTER_INFO to access the filter list. // https://docs.microsoft.com/en-us/windows/win32/api/restartmanager/nf-restartmanager-rmgetfilterlist DWORD RmGetFilterList( DWORD // dwSessionHandle, PBYTE pbFilterBuf, DWORD cbFilterBuf, LPDWORD cbFilterBufNeeded ); [DllImport(Lib_Rstrtmgr, SetLastError = false, ExactSpelling = true)] [PInvokeData("restartmanager.h", MSDNShortId = "NF:restartmanager.RmGetFilterList")] public static extern Win32Error RmGetFilterList(uint dwSessionHandle, [Out, Optional] IntPtr pbFilterBuf, uint cbFilterBuf, out uint cbFilterBufNeeded); /// /// Gets a list of all applications and services that are currently using resources that have been registered with the Restart /// Manager session. /// /// A handle to an existing Restart Manager session. /// /// A pointer to an array size necessary to receive RM_PROCESS_INFO structures required to return information for all affected /// applications and services. /// /// A pointer to the total number of RM_PROCESS_INFO structures in an array and number of structures filled. /// /// An array of RM_PROCESS_INFO structures that list the applications and services using resources that have been registered with /// the session. /// /// /// Pointer to location that receives a value of the RM_REBOOT_REASON enumeration that describes the reason a system restart is needed. /// /// /// This is the most recent error received. The function can return one of the system error codes that are defined in Winerror.h. /// /// /// Value /// Meaning /// /// /// ERROR_SUCCESS 0 /// The function completed successfully. /// /// /// ERROR_MORE_DATA 234 /// /// This error value is returned by the RmGetList function if the rgAffectedApps buffer is too small to hold all application /// information in the list. /// /// /// /// ERROR_CANCELLED 1223 /// The current operation is canceled by user. /// /// /// ERROR_SEM_TIMEOUT 121 /// /// A Restart Manager function could not obtain a Registry write mutex in the allotted time. A system restart is recommended because /// further use of the Restart Manager is likely to fail. /// /// /// /// ERROR_BAD_ARGUMENTS 160 /// /// One or more arguments are not correct. This error value is returned by the Restart Manager function if a NULL pointer or 0 is /// passed in a parameter that requires a non-null and non-zero value. /// /// /// /// ERROR_WRITE_FAULT 29 /// An operation was unable to read or write to the registry. /// /// /// ERROR_OUTOFMEMORY 14 /// A Restart Manager operation could not complete because not enough memory was available. /// /// /// ERROR_INVALID_HANDLE 6 /// No Restart Manager session exists for the handle supplied. /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/restartmanager/nf-restartmanager-rmgetlist DWORD RmGetList( DWORD // dwSessionHandle, UINT *pnProcInfoNeeded, UINT *pnProcInfo, RM_PROCESS_INFO [] rgAffectedApps, LPDWORD lpdwRebootReasons ); [DllImport(Lib_Rstrtmgr, SetLastError = false, ExactSpelling = true)] [PInvokeData("restartmanager.h", MSDNShortId = "NF:restartmanager.RmGetList")] public static extern Win32Error RmGetList(uint dwSessionHandle, out uint pnProcInfoNeeded, ref uint pnProcInfo, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] RM_PROCESS_INFO[] rgAffectedApps, out RM_REBOOT_REASON lpdwRebootReasons); /// /// Joins a secondary installer to an existing Restart Manager session. This function must be called with a session key that can /// only be obtained from the primary installer that started the session. A valid session key is required to use any of the Restart /// Manager functions. After a secondary installer joins a session, it can call the RmRegisterResources function to register resources. /// /// A pointer to the handle of an existing Restart Manager Session. /// A null-terminated string that contains the session key of an existing session. /// /// This is the most recent error received. The function can return one of the system error codes that are defined in Winerror.h. /// /// /// Value /// Meaning /// /// /// ERROR_SUCCESS 0 /// The function completed successfully. /// /// /// ERROR_SESSION_CREDENTIAL_CONFLICT 1219 /// The session key cannot be validated. /// /// /// ERROR_SEM_TIMEOUT 121 /// /// A Restart Manager function could not obtain a Registry write mutex in the allotted time. A system restart is recommended because /// further use of the Restart Manager is likely to fail. /// /// /// /// ERROR_BAD_ARGUMENTS 22 /// /// One or more arguments are not correct. This error value is returned by the Restart Manager function if a NULL pointer or 0 is /// passed in a parameter that requires a non-null and non-zero value. /// /// /// /// ERROR_WRITE_FAULT 29 /// An operation was unable to read or write to the registry. /// /// /// ERROR_MAX_SESSIONS_REACHED 353 /// The maximum number of sessions has been reached. /// /// /// ERROR_OUTOFMEMORY 14 /// A Restart Manager operation could not complete because not enough memory was available. /// /// /// /// /// The RmJoinSession function joins a secondary installer to an existing Restart Manager session. This is typically an /// installer that does not control the user interface and can run either in-process or out-of-process of the primary installer. /// Only the primary installer can call the RmStartSession function and this is typically the application that controls the user /// interface or that controls the installation sequence of multiple patches in an update. /// // https://docs.microsoft.com/en-us/windows/win32/api/restartmanager/nf-restartmanager-rmjoinsession DWORD RmJoinSession( DWORD // *pSessionHandle, const WCHAR [] strSessionKey ); [DllImport(Lib_Rstrtmgr, SetLastError = false, ExactSpelling = true)] [PInvokeData("restartmanager.h", MSDNShortId = "NF:restartmanager.RmJoinSession")] public static extern Win32Error RmJoinSession(out uint pSessionHandle, [MarshalAs(UnmanagedType.LPWStr)] string strSessionKey); /// /// Registers resources to a Restart Manager session. The Restart Manager uses the list of resources registered with the session to /// determine which applications and services must be shut down and restarted. Resources can be identified by filenames, service /// short names, or RM_UNIQUE_PROCESS structures that describe running applications. The RmRegisterResources function can be /// used by a primary or secondary installer. /// /// A handle to an existing Restart Manager session. /// The number of files being registered. /// /// An array of null-terminated strings of full filename paths. This parameter can be NULL if nFiles is 0. /// /// The number of processes being registered. /// /// An array of RM_UNIQUE_PROCESS structures. This parameter can be NULL if nApplications is 0. /// /// The number of services to be registered. /// /// An array of null-terminated strings of service short names. This parameter can be NULL if nServices is 0. /// /// /// This is the most recent error received. The function can return one of the system error codes that are defined in Winerror.h. /// /// /// Value /// Meaning /// /// /// ERROR_SUCCESS 0 /// The resources specified have been registered. /// /// /// ERROR_SEM_TIMEOUT 121 /// /// A Restart Manager function could not obtain a Registry write mutex in the allotted time. A system restart is recommended because /// further use of the Restart Manager is likely to fail. /// /// /// /// ERROR_BAD_ARGUMENTS 160 /// /// One or more arguments are not correct. This error value is returned by Restart Manager function if a NULL pointer or 0 is passed /// in a parameter that requires a non-null and non-zero value. /// /// /// /// ERROR_WRITE_FAULT 29 /// An operation was unable to read or write to the registry. /// /// /// ERROR_OUTOFMEMORY 14 /// A Restart Manager operation could not complete because not enough memory was available. /// /// /// ERROR_INVALID_HANDLE 6 /// No Restart Manager session exists for the handle supplied. /// /// /// /// /// Each call to the RmRegisterResources function performs relatively expensive write operations. Do not call this function /// once per file, instead group related files together into components and register these together. /// // https://docs.microsoft.com/en-us/windows/win32/api/restartmanager/nf-restartmanager-rmregisterresources DWORD // RmRegisterResources( DWORD dwSessionHandle, UINT nFiles, LPCWSTR [] rgsFileNames, UINT nApplications, RM_UNIQUE_PROCESS [] // rgApplications, UINT nServices, LPCWSTR [] rgsServiceNames ); [DllImport(Lib_Rstrtmgr, SetLastError = false, ExactSpelling = true)] [PInvokeData("restartmanager.h", MSDNShortId = "NF:restartmanager.RmRegisterResources")] public static extern Win32Error RmRegisterResources(uint dwSessionHandle, [Optional] uint nFiles, [In, Optional, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1, ArraySubType = UnmanagedType.LPWStr)] string[]? rgsFileNames, [Optional] uint nApplications, [In, Optional, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] RM_UNIQUE_PROCESS[]? rgApplications, [Optional] uint nServices, [In, Optional, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 5, ArraySubType = UnmanagedType.LPWStr)] string[]? rgsServiceNames); /// /// Removes any modifications to shutdown or restart actions that have been applied using the RmAddFilter function. The primary /// installer can call the RmRemoveFilter function multiple times. /// /// A handle to an existing Restart Manager session. /// /// A pointer to a null-terminated string value that contains the full path for the application's executable file. The /// RmRemoveFilter function removes any modifications to the referenced application's shutdown or restart actions previously /// applied by the RmAddFilter function. This parameter must be NULL if the Application or strServiceShortName parameter is /// non- NULL. /// /// /// The RM_UNIQUE_PROCESS structure for the application. The RmRemoveFilter function removes any modifications to the /// referenced application's shutdown or restart actions previously applied by the RmAddFilter function. This parameter must be /// NULL if the strFilename or strShortServiceName parameter is non- NULL. /// /// /// A pointer to a null-terminated string value that contains the short service name. The RmRemoveFilter function /// removes any modifications to the referenced service's shutdown or restart actions previously applied by the RmAddFilter /// function. This parameter must be NULL if the strFilename or Application parameter is non- NULL. /// /// /// This is the most recent error received. The function can return one of the system error codes that are defined in Winerror.h. /// /// /// Value /// Meaning /// /// /// ERROR_SUCCESS 0 /// The function completed successfully. /// /// /// ERROR_FILE_NOT_FOUND 1 /// The specified filter could not be found. /// /// /// ERROR_SESSION_CREDENTIAL_CONFLICT 1219 /// This error is returned when a secondary installer calls this function. This function is only available to primary installers. /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/restartmanager/nf-restartmanager-rmremovefilter DWORD RmRemoveFilter( DWORD // dwSessionHandle, LPCWSTR strModuleName, RM_UNIQUE_PROCESS *pProcess, LPCWSTR strServiceShortName ); [DllImport(Lib_Rstrtmgr, SetLastError = false, ExactSpelling = true)] [PInvokeData("restartmanager.h", MSDNShortId = "NF:restartmanager.RmRemoveFilter")] public static extern Win32Error RmRemoveFilter(uint dwSessionHandle, [Optional, MarshalAs(UnmanagedType.LPWStr)] string? strModuleName, in RM_UNIQUE_PROCESS pProcess, [Optional, MarshalAs(UnmanagedType.LPWStr)] string? strServiceShortName); /// /// Removes any modifications to shutdown or restart actions that have been applied using the RmAddFilter function. The primary /// installer can call the RmRemoveFilter function multiple times. /// /// A handle to an existing Restart Manager session. /// /// A pointer to a null-terminated string value that contains the full path for the application's executable file. The /// RmRemoveFilter function removes any modifications to the referenced application's shutdown or restart actions previously /// applied by the RmAddFilter function. This parameter must be NULL if the Application or strServiceShortName parameter is /// non- NULL. /// /// /// The RM_UNIQUE_PROCESS structure for the application. The RmRemoveFilter function removes any modifications to the /// referenced application's shutdown or restart actions previously applied by the RmAddFilter function. This parameter must be /// NULL if the strFilename or strShortServiceName parameter is non- NULL. /// /// /// A pointer to a null-terminated string value that contains the short service name. The RmRemoveFilter function /// removes any modifications to the referenced service's shutdown or restart actions previously applied by the RmAddFilter /// function. This parameter must be NULL if the strFilename or Application parameter is non- NULL. /// /// /// This is the most recent error received. The function can return one of the system error codes that are defined in Winerror.h. /// /// /// Value /// Meaning /// /// /// ERROR_SUCCESS 0 /// The function completed successfully. /// /// /// ERROR_FILE_NOT_FOUND 1 /// The specified filter could not be found. /// /// /// ERROR_SESSION_CREDENTIAL_CONFLICT 1219 /// This error is returned when a secondary installer calls this function. This function is only available to primary installers. /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/restartmanager/nf-restartmanager-rmremovefilter DWORD RmRemoveFilter( DWORD // dwSessionHandle, LPCWSTR strModuleName, RM_UNIQUE_PROCESS *pProcess, LPCWSTR strServiceShortName ); [DllImport(Lib_Rstrtmgr, SetLastError = false, ExactSpelling = true)] [PInvokeData("restartmanager.h", MSDNShortId = "NF:restartmanager.RmRemoveFilter")] public static extern Win32Error RmRemoveFilter(uint dwSessionHandle, [Optional, MarshalAs(UnmanagedType.LPWStr)] string? strModuleName, [In, Optional] IntPtr pProcess, [Optional, MarshalAs(UnmanagedType.LPWStr)] string? strServiceShortName); /// /// Restarts applications and services that have been shut down by the RmShutdown function and that have been registered to be /// restarted using the RegisterApplicationRestart function. This function can only be called by the primary installer that called /// the RmStartSession function to start the Restart Manager session. /// /// A handle to the existing Restart Manager session. /// Reserved. This parameter should be 0. /// /// A pointer to a status message callback function that is used to communicate status while the RmRestart function is /// running. If NULL, no status is provided. /// /// /// This is the most recent error received. The function can return one of the system error codes that are defined in Winerror.h. /// /// /// Value /// Meaning /// /// /// ERROR_REQUEST_OUT_OF_SEQUENCE 776 /// /// This error value is returned if the RmRestart function is called with a valid session handle before calling the RmShutdown function. /// /// /// /// ERROR_FAIL_RESTART 352 /// /// One or more applications could not be restarted. The RM_PROCESS_INFO structures that are returned by the RmGetList function /// contain updated status information. /// /// /// /// ERROR_SEM_TIMEOUT 121 /// /// A Restart Manager function could not obtain a registry write mutex in the allotted time. A system restart is recommended because /// further use of the Restart Manager is likely to fail. /// /// /// /// ERROR_CANCELLED 1223 /// This error value is returned by the RmRestart function when the request to cancel an operation is successful. /// /// /// ERROR_BAD_ARGUMENTS 160 /// /// One or more arguments are not correct. This error value is returned by the Restart Manager function if a NULL pointer or 0 is /// passed in a parameter that requires a non-null and non-zero value. /// /// /// /// ERROR_WRITE_FAULT 29 /// An operation was unable to read or write to the registry. /// /// /// ERROR_OUTOFMEMORY 14 /// A Restart Manager operation could not complete because not enough memory was available. /// /// /// ERROR_INVALID_HANDLE 6 /// No Restart Manager session exists for the handle supplied. /// /// /// ERROR_SUCCESS 0 /// The function succeeds and returns. /// /// /// /// /// /// After calling the RmRestart function, the RM_PROCESS_INFO structures that are returned by the RmGetList function contain /// updated status information. /// /// /// The Restart Manager respects the privileges that separate different user or terminal sessions. An installer that is running as a /// service with LocalSystem privileges cannot shut down or restart any applications in another user or terminal session. Installers /// should implement custom methods to shut down and restart applications that are running in other sessions. One method would be to /// start a new installer process in the other session to perform shutdown and restart operations. /// /// When a console application is shut down and restarted by Restart Manager, the application is restarted in a new console. /// /// Installers should always restart application and services using the RmRestart function even when the RmShutdown function /// returns an error indicating that not all applications and services could be shut down. /// /// /// The RmRestart function does not restart any applications that run with elevated privileges. Even if the application was /// shutdown by Restart Manager. /// /// /// The RmRestart function does not restart any applications that do not run as the currently-logged on user. Even if the /// application was shutdown by Restart Manager. For example, the RmRestart function does not restart applications started /// with the Run As command that do not run as the currently-logged on user. These applications must be manually restarted. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/restartmanager/nf-restartmanager-rmrestart DWORD RmRestart( DWORD // dwSessionHandle, DWORD dwRestartFlags, RM_WRITE_STATUS_CALLBACK fnStatus ); [DllImport(Lib_Rstrtmgr, SetLastError = false, ExactSpelling = true)] [PInvokeData("restartmanager.h", MSDNShortId = "NF:restartmanager.RmRestart")] public static extern Win32Error RmRestart(uint dwSessionHandle, [Optional] uint dwRestartFlags, [In, Optional] RM_WRITE_STATUS_CALLBACK? fnStatus); /// /// Initiates the shutdown of applications. This function can only be called from the installer that started the Restart Manager /// session using the RmStartSession function. /// /// A handle to an existing Restart Manager session. /// /// /// One or more RM_SHUTDOWN_TYPE options that configure the shut down of components. The following values can be combined by an OR /// operator to specify that unresponsive applications and services are to be forced to shut down if, and only if, all applications /// have been registered for restart. /// /// /// /// Value /// Meaning /// /// /// RmForceShutdown 0x1 /// /// Force unresponsive applications and services to shut down after the timeout period. An application that does not respond to a /// shutdown request is forced to shut down within 30 seconds. A service that does not respond to a shutdown request is forced to /// shut down after 20 seconds. /// /// /// /// RmShutdownOnlyRegistered 0x10 /// /// Shut down applications if and only if all the applications have been registered for restart using the RegisterApplicationRestart /// function. If any processes or services cannot be restarted, then no processes or services are shut down. /// /// /// /// /// /// A pointer to an RM_WRITE_STATUS_CALLBACK function that is used to communicate detailed status while this function is executing. /// If NULL, no status is provided. /// /// /// This is the most recent error received. The function can return one of the system error codes that are defined in Winerror.h. /// /// /// Value /// Meaning /// /// /// ERROR_SUCCESS 0 /// All shutdown, restart, and callback operations were successfully completed. /// /// /// ERROR_FAIL_NOACTION_REBOOT 350 /// /// No shutdown actions were performed. One or more processes or services require a restart of the system to be shut down. This /// error code is returned when the Restart Manager detects that a restart of the system is required before shutting down any application. /// /// /// /// ERROR_FAIL_SHUTDOWN 351 /// /// Some applications could not be shut down. The AppStatus of the RM_PROCESS_INFO structures returned by the RmGetList function /// contain updated status information. /// /// /// /// ERROR_CANCELLED 1223 /// This error value is returned by the RmShutdown function when the request to cancel an operation is successful. /// /// /// ERROR_SEM_TIMEOUT 121 /// /// A Restart Manager function could not obtain a Registry write mutex in the allotted time. A system restart is recommended because /// further use of the Restart Manager is likely to fail. /// /// /// /// ERROR_BAD_ARGUMENTS 160 /// /// One or more arguments are not correct. This error value is returned by the Restart Manager function if a NULL pointer or 0 is /// passed in a parameter that requires a non-null and non-zero value. /// /// /// /// ERROR_WRITE_FAULT 29 /// An operation was unable to read or write to the registry. /// /// /// ERROR_OUTOFMEMORY 14 /// A Restart Manager operation could not be completed because not enough memory is available. /// /// /// ERROR_INVALID_HANDLE 6 /// No Restart Manager session exists for the handle supplied. /// /// /// /// /// /// The RmShutdown function calls RmGetList and updates the list of processes currently using registered resources before /// attempting to shut down any processes. The RmShutdown function then attempts to shut down the processes using registered /// resources in the most current list. The RmShutdown function updates the AppStatus member of the RM_PROCESS_INFO /// structures that are returned by the RmGetList function with detailed status information. /// /// /// The Restart Manager respects the privileges that separate different user or terminal sessions. An installer that is running as a /// service with LocalSystem privileges cannot shut down or restart any applications in another user or terminal session. Installers /// should implement custom methods to shut down and restart applications that are running in other sessions. One method would be to /// start a new installer process in the other session to perform shutdown and restart operations. /// /// /// Installers should always restart application and services using the RmRestart function even when the RmShutdown function /// returns an error indicating that not all applications and services could be shut down. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/restartmanager/nf-restartmanager-rmshutdown DWORD RmShutdown( DWORD // dwSessionHandle, ULONG lActionFlags, RM_WRITE_STATUS_CALLBACK fnStatus ); [DllImport(Lib_Rstrtmgr, SetLastError = false, ExactSpelling = true)] [PInvokeData("restartmanager.h", MSDNShortId = "NF:restartmanager.RmShutdown")] public static extern Win32Error RmShutdown(uint dwSessionHandle, [Optional] RM_SHUTDOWN_TYPE lActionFlags, [In, Optional] RM_WRITE_STATUS_CALLBACK? fnStatus); /// /// Starts a new Restart Manager session. A maximum of 64 Restart Manager sessions per user session can be open on the system at the /// same time. When this function starts a session, it returns a session handle and session key that can be used in subsequent calls /// to the Restart Manager API. /// /// /// A pointer to the handle of a Restart Manager session. The session handle can be passed in subsequent calls to the Restart /// Manager API. /// /// Reserved. This parameter should be 0. /// /// A null-terminated string that contains the session key to the new session. The string must be allocated before calling /// the RmStartSession function. /// /// /// This is the most recent error received. The function can return one of the system error codes that are defined in Winerror.h. /// /// /// Value /// Meaning /// /// /// ERROR_SUCCESS 0 /// The function completed successfully. /// /// /// ERROR_SEM_TIMEOUT 121 /// /// A Restart Manager function could not obtain a Registry write mutex in the allotted time. A system restart is recommended because /// further use of the Restart Manager is likely to fail. /// /// /// /// ERROR_BAD_ARGUMENTS 160 /// /// One or more arguments are not correct. This error value is returned by the Restart Manager function if a NULL pointer or 0 is /// passed in a parameter that requires a non-null and non-zero value. /// /// /// /// ERROR_MAX_SESSIONS_REACHED 353 /// The maximum number of sessions has been reached. /// /// /// ERROR_WRITE_FAULT 29 /// The system cannot write to the specified device. /// /// /// ERROR_OUTOFMEMORY 14 /// A Restart Manager operation could not complete because not enough memory was available. /// /// /// /// /// The RmStartSession function returns an error if a session with the same session key already exists. /// /// The RmStartSession function should be called by the primary installer that controls the user interface or that controls /// the installation sequence of multiple patches in an update. /// /// /// A secondary installer can join an existing Restart Manager session by calling the RmJoinSession function with the session handle /// and session key returned from the RmStartSession function call of the primary installer. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/restartmanager/nf-restartmanager-rmstartsession DWORD RmStartSession( DWORD // *pSessionHandle, DWORD dwSessionFlags, WCHAR [] strSessionKey ); [DllImport(Lib_Rstrtmgr, SetLastError = false, ExactSpelling = true)] [PInvokeData("restartmanager.h", MSDNShortId = "NF:restartmanager.RmStartSession")] public static extern Win32Error RmStartSession(out uint pSessionHandle, [Optional] uint dwSessionFlags, [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder strSessionKey); /// /// Contains information about modifications to restart or shutdown actions. Add, remove, and list modifications to specified /// applications and services that have been registered with the Restart Manager session by using the RmAddFilter, RmRemoveFilter, /// and the RmGetFilterList functions. /// // https://docs.microsoft.com/en-us/windows/win32/api/restartmanager/ns-restartmanager-rm_filter_info typedef struct _RM_FILTER_INFO // { RM_FILTER_ACTION FilterAction; RM_FILTER_TRIGGER FilterTrigger; DWORD cbNextOffset; union { LPWSTR strFilename; // RM_UNIQUE_PROCESS Process; LPWSTR strServiceShortName; }; } RM_FILTER_INFO, *PRM_FILTER_INFO; [PInvokeData("restartmanager.h", MSDNShortId = "NS:restartmanager._RM_FILTER_INFO")] [StructLayout(LayoutKind.Sequential)] public struct RM_FILTER_INFO { /// /// This member contains a RM_FILTER_ACTION enumeration value. Use the value RmNoRestart to prevent the restart of the /// application or service. Use the value RmNoShutdown to prevent the shutdown and restart of the application or service. /// public RM_FILTER_ACTION FilterAction; /// /// This member contains a RM_FILTER_TRIGGER enumeration value. Use the value RmFilterTriggerFile to modify the restart /// or shutdown actions of an application referenced by the executable's full path filename. Use the value /// RmFilterTriggerProcess to modify the restart or shutdown actions of an application referenced by a RM_UNIQUE_PROCESS /// structure. Use the value RmFilterTriggerService to modify the restart or shutdown actions of a service referenced by /// the short service name. /// public RM_FILTER_TRIGGER FilterTrigger; /// The offset in bytes to the next structure. public uint cbNextOffset; private UNION union; [StructLayout(LayoutKind.Explicit)] private struct UNION { [FieldOffset(0)] public StrPtrUni str; [FieldOffset(0)] public RM_UNIQUE_PROCESS proc; } /// /// If the value of FilterTrigger is RmFilterTriggerFile, this member contains a pointer to a string value that /// contains the application filename. /// public string? strFilename => union.str; /// /// If the value of FilterTrigger is RmFilterTriggerProcess, this member is a RM_PROCESS_INFO structure for the application. /// public RM_UNIQUE_PROCESS Process => union.proc; /// /// If the value of FilterTrigger is RmFilterTriggerService this member is a pointer to a string value that /// contains the short service name. /// public string? strServiceShortName => union.str; } /// Describes an application that is to be registered with the Restart Manager. // https://docs.microsoft.com/en-us/windows/win32/api/restartmanager/ns-restartmanager-rm_process_info typedef struct // _RM_PROCESS_INFO { RM_UNIQUE_PROCESS Process; WCHAR strAppName[CCH_RM_MAX_APP_NAME + 1]; WCHAR // strServiceShortName[CCH_RM_MAX_SVC_NAME + 1]; RM_APP_TYPE ApplicationType; ULONG AppStatus; DWORD TSSessionId; BOOL bRestartable; // } RM_PROCESS_INFO, *PRM_PROCESS_INFO; [PInvokeData("restartmanager.h", MSDNShortId = "NS:restartmanager._RM_PROCESS_INFO")] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct RM_PROCESS_INFO { /// /// Contains an RM_UNIQUE_PROCESS structure that uniquely identifies the application by its PID and the time the process began. /// public RM_UNIQUE_PROCESS Process; /// /// If the process is a service, this parameter returns the long name for the service. If the process is not a service, this /// parameter returns the user-friendly name for the application. If the process is a critical process, and the installer is run /// with elevated privileges, this parameter returns the name of the executable file of the critical process. If the process is /// a critical process, and the installer is run as a service, this parameter returns the long name of the critical process. /// [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCH_RM_MAX_APP_NAME + 1)] public string strAppName; /// /// If the process is a service, this is the short name for the service. This member is not used if the process is not a service. /// [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCH_RM_MAX_SVC_NAME + 1)] public string strServiceShortName; /// /// Contains an RM_APP_TYPE enumeration value that specifies the type of application as RmUnknownApp, /// RmMainWindow, RmOtherWindow, RmService, RmExplorer or RmCritical. /// public RM_APP_TYPE ApplicationType; /// Contains a bit mask that describes the current status of the application. See the RM_APP_STATUS enumeration. public RM_APP_STATUS AppStatus; /// /// Contains the Terminal Services session ID of the process. If the terminal session of the process cannot be determined, the /// value of this member is set to RM_INVALID_SESSION (-1). This member is not used if the process is a service or a /// system critical process. /// public uint TSSessionId; /// /// TRUE if the application can be restarted by the Restart Manager; otherwise, FALSE. This member is always /// TRUE if the process is a service. This member is always FALSE if the process is a critical system process. /// [MarshalAs(UnmanagedType.Bool)] public bool bRestartable; } /// /// Uniquely identifies a process by its PID and the time the process began. An array of RM_UNIQUE_PROCESS structures can be /// passed to the RmRegisterResources function. /// /// /// The RM_UNIQUE_PROCESS structure can be used to uniquely identify an application in an RM_PROCESS_INFO structure or /// registered with the Restart Manager session by the RmRegisterResources function. /// // https://docs.microsoft.com/en-us/windows/win32/api/restartmanager/ns-restartmanager-rm_unique_process typedef struct // _RM_UNIQUE_PROCESS { DWORD dwProcessId; FILETIME ProcessStartTime; } RM_UNIQUE_PROCESS, *PRM_UNIQUE_PROCESS; [PInvokeData("restartmanager.h", MSDNShortId = "NS:restartmanager._RM_UNIQUE_PROCESS")] [StructLayout(LayoutKind.Sequential)] public struct RM_UNIQUE_PROCESS { /// The product identifier (PID). public uint dwProcessId; /// /// The creation time of the process. The time is provided as a FILETIME structure that is returned by the lpCreationTime /// parameter of the GetProcessTimes function. /// public FILETIME ProcessStartTime; } }