从标准用户更改注册表项是否需要启动进程?

时间:2017-05-15 18:21:04

标签: windows uac

我的应用以标准用户身份运行。有时我需要创建一个需要管理员访问权限的注册表项。我想提示用户获得管理员权限。

如果我沿着这些方向做点什么:

GetNamedSecurityInfo
AllocateAndInitializeSid
SetEntriesInAcl
SetNamedSecurityInfo (or RegSetKeySecurity)

这是否会导致Windows自动弹出一个提示用户授权的对话框?

我是否必须启动进程才能访问注册表?在这种情况下,如何提示用户获取进程的管理员权限?

我不想使用CredUIPromptForCredentials,因为我不想看到用户的密码。

我已经阅读了Access Control文档,似乎无法看到森林中的树木。

2 个答案:

答案 0 :(得分:2)

Windows不会显示UAC对话框只是因为您调用了一些需要提升才能执行其任务的API,API将因ERROR_ACCESS_DENIED而失败。

你基本上有三个选择:

  1. 实施elevated COM object
  2. ShellExecute使用RunAs动词和命令行参数,以便您可以检测到您处于此模式。
  3. 创建一个NT service,您可以根据需要启动并通过命名管道进行通信。我不推荐这种方法。

答案 1 :(得分:0)

这是我想出的,感谢@ Anders'优秀的建议:

// launch separate process for elevation to Admin
void launchAsAdmin(void)
{   SHELLEXECUTEINFO shelinfo;
    char *err = NULL;
    DWORD exitCode;

    memset(&shelinfo, 0, sizeof(shelinfo));
    shelinfo.cbSize = sizeof(shelinfo);
    shelinfo.hwnd = NULL;
    shelinfo.fMask = SEE_MASK_NOCLOSEPROCESS;
    shelinfo.lpVerb = "RunAs";
    shelinfo.lpFile = "notepad.exe";
    shelinfo.lpParameters = "C:\\Windows\\System32\\drivers\\etc\\hosts";
    shelinfo.nShow = SW_SHOW;

    ShellExecuteEx(&shelinfo);  
    switch((int)shelinfo.hInstApp)
    {   case SE_ERR_FNF:
            err = "File not found"; break;
        case SE_ERR_PNF:
            err = "Path not found"; break;
        case SE_ERR_ACCESSDENIED:
            err = "Access denied"; break;
        case SE_ERR_OOM:
            err = "Out of memory"; break;
        case SE_ERR_DLLNOTFOUND:
            err = "Dynamic-link library not found"; break;
        case SE_ERR_SHARE:
            err = "Cannot share an open file"; break;
        case SE_ERR_ASSOCINCOMPLETE:
            err = "File association information not complete"; break;
        case SE_ERR_DDETIMEOUT:
            err = "DDE operation timed out"; break;
        case SE_ERR_DDEFAIL:
            err = "DDE operation failed"; break;
        case SE_ERR_DDEBUSY:
            err = "DDE operation is busy"; break;
        case SE_ERR_NOASSOC:
            err = "File association not available"; break;
    }
    if((int)shelinfo.hInstApp <= 32)
        return;     // failed
    if(shelinfo.hProcess == 0)
        return;     // nothing to monitor

    // wait until the process has finished
    time_t st = clock();
    do
    {   if(!GetExitCodeProcess(shelinfo.hProcess, &exitCode))
            break;
        if(clock() - st > CLOCKS_PER_SEC * 5)       // max 5 seconds - give up
            break;
    } while(exitCode != STATUS_WAIT_0); // STILL_ACTIVE
    CloseHandle(shelinfo.hProcess);
}

这很有效。如果我是标准用户并运行调用此功能的程序,系统会提示我输入管理员登录ID&amp;密码,并允许更改和保存&#34; HOSTS&#34;系统文件。 (通常此文件不受标准用户限制。)