locked
Windows Restart Manager API in Windows 8.1 and Windows 10 RRS feed

  • Question

  • I am actually trying to write a demo program which will use restart manager to cause a machine restart and on load open up calc.exe. What I am actually trying to see is whether the RMRestart method actually starts up my machine and launches calc.exe on next launch.

    This is code I have written -

    // TestRestartManager.cpp : Defines the entry point for the console application.

    #include "stdafx.h"
    #include <Windows.h>
    #include <RestartManager.h>

    #pragma comment(lib, "rstrtmgr.lib")

    int _tmain(int argc, _TCHAR* argv[])
    {
        DWORD errorCode = ERROR_SUCCESS;
        DWORD sessionHandle = 0xFFFFFFFF;

        WCHAR sessionKey[CCH_RM_SESSION_KEY + 1];

        DWORD files = 2;

        // trying to start calc on startup
        LPCWSTR filesToStartUp[] = {
            L"C:\\Windows\\System32\\calc.exe",
            L"C:\\Windows\\SysWow64\\calc.exe"
        };


        UINT retryCount = 0;
        UINT affectedAppsCount = 0;
        UINT procInfoNeeded = 0;
        RM_REBOOT_REASON rebootReasons = RmRebootReasonNone;
        RM_PROCESS_INFO *affectedApps = NULL;

        // Start a Restart Manager Session
        errorCode = RmStartSession(&sessionHandle, 0, sessionKey);
        printf("code after RmStartSession = %ld", errorCode);

        errorCode = RmRegisterResources(sessionHandle,
            files,
            filesToStartUp,       // Files
            0,
            NULL,           // Processes
            0,
            NULL);          // Services

        printf("code after RmRegisterResources = %ld", errorCode);

        while ((ERROR_MORE_DATA == errorCode) && (retryCount++ < 3))
        {
            errorCode = RmGetList(sessionHandle,
                &procInfoNeeded,
                &affectedAppsCount,
                affectedApps,
                (LPDWORD)&rebootReasons);
            printf("code after RmGetList = %ld", errorCode);

            if (ERROR_SUCCESS == errorCode)
            {
                break;
            }

            affectedAppsCount = procInfoNeeded;

            if (NULL != affectedApps)
            {
                delete[]affectedApps;
                affectedApps = NULL;
            }

            affectedApps = new RM_PROCESS_INFO[affectedAppsCount];

        }

        errorCode = RmShutdown(sessionHandle, 0, NULL);

        printf("code after RmShutdown = %ld", errorCode);

        errorCode = RmRestart(sessionHandle, 0, NULL);

        if (NULL != affectedApps)
        {
            delete[] affectedApps;
            affectedApps = NULL;
        }

        if (0xFFFFFFFF != sessionHandle)
        {
            // Clean up the Restart Manager session.
            RmEndSession(sessionHandle);
            sessionHandle = 0xFFFFFFFF;
        }


     return 0;
    }

    However, something is not right, as when I am running the test program, nothing is happening. Can you let me know what I am missing here?

    Thursday, January 14, 2016 11:43 AM

Answers

  • So, this is what I found out. RegisterforRestart behaves differently for win32 app and console app. When I created a console application and tried the above mentioned, the application did not restart. But if I do it for a UI source, it's working fine.
    • Marked as answer by Nemo666 Friday, February 12, 2016 10:28 AM
    Friday, February 12, 2016 10:28 AM

All replies

  • I don't see RegisterApplicationRestart anywhere. 



    Visual C++ MVP

    Thursday, January 14, 2016 3:35 PM
  • I am doing "RmRegisterResources". I am under the impression that this is going to register the application.

    I have simplified my code to this - 

    int _tmain(int argc, _TCHAR* argv[])
    {
        WCHAR sessionKey[CCH_RM_SESSION_KEY + 1] = { 0 };
        DWORD sessionHandle = NULL;
        DWORD errorCode = ERROR_SUCCESS;

        errorCode = RmStartSession(&sessionHandle, 0, sessionKey);

        printf("code after RmStartSession = %ld\n", errorCode);

        WCHAR explorer[MAX_PATH] = { 0 };

        if (ExpandEnvironmentStrings(L"%systemroot%\\explorer.exe", explorer, ARRAYSIZE(explorer)) > 0)
        {
            PCWSTR arg[] = { explorer };
            errorCode = RmRegisterResources(sessionHandle, 1, arg, 0, NULL, 0, NULL);

            printf("code after RmRegisterResources = %ld\n", errorCode);

            errorCode = RmShutdown(sessionHandle, RmForceShutdown, NULL);

            printf("code after RmShutdown = %ld\n", errorCode);

            errorCode = RmRestart(sessionHandle, 0, NULL);

            printf("code after RmRestart = %ld\n", errorCode);

            if (sessionHandle)
            {
                RmEndSession(sessionHandle);
            }
        }

        return 0;
    }

    The thing is that, if I change it from explorer to anything else, say msra.exe or calc.exe, this doesn't seem to be working. A a bit confused now. Also, I am thinking of calling "InitiateShutdown()". So, if the app is registered properly, after shutdown happens, it should successfully open up right?

    Thursday, January 14, 2016 11:07 PM
  • So, this is what I found out. RegisterforRestart behaves differently for win32 app and console app. When I created a console application and tried the above mentioned, the application did not restart. But if I do it for a UI source, it's working fine.
    • Marked as answer by Nemo666 Friday, February 12, 2016 10:28 AM
    Friday, February 12, 2016 10:28 AM