26

I've been stuck on this for a few hours until I've finally managed to do it. There are already links which pointed me the right direction:

But I've thought that simple overview of the problem could help someone :).

Community
  • 1
  • 1
Samuel
  • 1,975
  • 5
  • 24
  • 36
  • [`LogonUser`](http://msdn.microsoft.com/en-us/library/windows/desktop/aa378184(v=vs.85).aspx) should work well, I would think. It mentions creating processes right in the description. – chris Jul 20 '12 at 19:57
  • .... what is your question? – Lightness Races in Orbit Mar 20 '13 at 13:00
  • 2
    It's not, it's a solution for people who get into same trouble as I. – Samuel Apr 14 '13 at 13:31
  • 3
    This is a legitimate C++ / Windows SDK question. Clearly, the OP is asking about a Windows API call, `CreateProcess`, and providing the error code (740, `The requested operation requires elevation.`). There is no difficulty in understanding what is being asked for anyone who programs in C++ using the Windows SDK. I nominate it for reopening. – Dan Nissenbaum Mar 08 '16 at 17:28

1 Answers1

32

Real problem: (from Wikipedia: http://en.wikipedia.org/wiki/User_Account_Control)

An executable that is marked as "requireAdministrator" in its manifest cannot be started from a non-elevated process using CreateProcess(). Instead, ERROR_ELEVATION_REQUIRED will be returned. ShellExecute() or ShellExecuteEx() must be used instead.

(BTW, ERROR_ELEVATION_REQUIRED error == 740)

Solution: (same site)

In a native Win32 application the same "runas" verb can be added to a ShellExecute() or ShellExecuteEx() call.

ShellExecute(hwnd, "runas", "C:\\Windows\\Notepad.exe", 0, 0, SW_SHOWNORMAL);

This may be also helpful: (source: http://mark.koli.ch/2009/12/uac-prompt-from-java-createprocess-error740-the-requested-operation-requires-elevation.html)

2 - Basic UAC Flow

Ok, so before you dig into it, I thought it might be helpful to explain the basic flow of a UAC aware application and how everything fits together. Normally, your application runs as an unprivileged user. But, sometimes it needs to be an Administrator (to do whatever). So, here's the basic idea, in pseudo code:

int main (int argc, char **argv) {

  HRESULT operation = tryToDoSomethingPrivileged();

  if (operation == ACCESS_DENIED && !alreadyElevated) {

    // Spawn a copy of ourselves, via ShellExecuteEx().
    // The "runas" verb is important because that's what
    // internally triggers Windows to open up a UAC prompt.
    HANDLE child = ShellExecuteEx(argc, argv, "runas");

    if (child) {
      // User accepted UAC prompt (gave permission).
      // The unprivileged parent should wait for
      // the privileged child to finish.
      WaitForSingleObject(child, INFINITE);
      CloseHandle(pid);
    }
    else {
      // User rejected UAC prompt.
      return FAILURE;
    }

    return SUCCESS;

  }  

  return SUCCESS;

}

Finally, this is how I've done it:

if(0 == CreateProcess(argv[2], params, NULL, NULL, false, 0, NULL, NULL, &si, &pi)) {
        //runas word is a hack to require UAC elevation
        ShellExecute(NULL, "runas", argv[2], params, NULL, SW_SHOWNORMAL);
}

And just for completness's sake - MSDN links to ShellExecute and CreateProcess:

http://msdn.microsoft.com/en-us/library/bb762153%28v=vs.85%29.aspx

http://msdn.microsoft.com/en-us/library/ms682425%28VS.85%29.aspx

Community
  • 1
  • 1
Samuel
  • 1,975
  • 5
  • 24
  • 36
  • I have used this same approach in one of my apps (spawning an elevated copy of itself via "runas" to perform a single privileged task, where the command-line for the spawned child process tells it what task to perform), and although it is not how Microsoft prefers people to use UAC elevation, it does work in cases where a UAC manifest on the main .exe is overkill. Microsoft prefers the privileged task to be in its own .exe with a UAC manifest on it, or in its own COM object that is instantiated via the COM Elevation moniker. – Remy Lebeau Jul 20 '12 at 21:06
  • 3
    ShellExecuteEx takes one argument, a pointer to SHELLEXECUTEINFO. http://msdn.microsoft.com/en-us/library/windows/desktop/bb762154(v=vs.85).aspx – M.M May 15 '14 at 03:30
  • 1
    I noted that the "runas" operation isn't mentioned among the others, in the documentation (of ShellExecute): even some user on that page argued if it is safe to use it. The fact that it works isn't as reliable (since you have to hand-check it and in some cases it may not work) as some piece of documentation stating it. Is there someone that has some reference about the reliability of runas? – reallynice Jul 23 '15 at 11:52
  • @reallynic http://ss64.com/vb/shellexecute.html states: “runas will fail if you are running in WOW64 (a 32 bit process on 64 bit windows) for example %systemroot%\syswow64\cmd.exe ...”; also, http://mfctips.com/2013/01/04/createprocess-fails-to-launch-exe-with-elevated-manifest/ is a worthy read (may not be about runas, strictly) – mlvljr Nov 10 '15 at 00:56
  • 1
    @mlvljr: `runas` works fine in WOW64 when spawning another 32bit process. Not sure about spawning a 64bit process, I haven't tried that with `runas`. – Remy Lebeau Mar 01 '17 at 17:35
  • @RemyLebeau good to know – mlvljr Mar 01 '17 at 21:18