21xrx.com
2024-09-20 05:40:18 Friday
登录
文章检索 我的文章 写文章
如何在C++启动时自动修改注册表并申请管理员权限
2023-07-02 06:22:45 深夜i     --     --
C++ 注册表 自动修改 申请管理员权限

在开发C++应用程序时,有时候需要对注册表进行读写操作,并且这些操作需要管理员权限。但是,用户可能不会以管理员身份运行程序,因此需要用代码来自动申请管理员权限,并在程序启动时自动修改注册表。

下面是如何实现这一功能的步骤:

1. 在程序中包含Windows头文件。


#include <windows.h>

2. 定义需要修改的注册表键值。


#define REGISTRY_PATH "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"

#define REGISTRY_NAME "My Program Name"

#define REGISTRY_VALUE "C:\\MyProgram.exe"

3. 添加管理员特权。


BOOL IsUserAdmin(VOID)

{

  BOOL fIsRunAsAdmin = FALSE;

  DWORD dwError = ERROR_SUCCESS;

  PSID pAdministratorsGroup = NULL;

  SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;

  if (!AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pAdministratorsGroup))

  {

    dwError = GetLastError();

    goto Cleanup;

  }

  if (!CheckTokenMembership(NULL, pAdministratorsGroup, &fIsRunAsAdmin))

  {

    dwError = GetLastError();

    goto Cleanup;

  }

Cleanup:

  if (pAdministratorsGroup)

  {

    FreeSid(pAdministratorsGroup);

    pAdministratorsGroup = NULL;

  }

  SetLastError(dwError);

  return fIsRunAsAdmin;

}

BOOL ElevatePrivileges(VOID)

{

  BOOL fSuccess = FALSE;

  HANDLE hToken = NULL;

  if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))

  

    goto Cleanup;

  

  TOKEN_ELEVATION TokenElevation;

  DWORD cbSize = sizeof(TOKEN_ELEVATION);

  if (!GetTokenInformation(hToken, TokenElevation, &TokenElevation, sizeof(TokenElevation), &cbSize))

  

    goto Cleanup;

  

  if (TokenElevation.TokenIsElevated)

  

    fSuccess = TRUE;

    goto Cleanup;

  

  TOKEN_PRIVILEGES TokenPrivileges;

  TokenPrivileges.PrivilegeCount = 1;

  TokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

  if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &TokenPrivileges.Privileges[0].Luid))

  

    goto Cleanup;

  

  if (!AdjustTokenPrivileges(hToken, FALSE, &TokenPrivileges, sizeof(TOKEN_PRIVILEGES), NULL, NULL))

  

    goto Cleanup;

  

  fSuccess = TRUE;

Cleanup:

  if (hToken)

  {

    CloseHandle(hToken);

    hToken = NULL;

  }

  SetLastError(fSuccess ? ERROR_SUCCESS : GetLastError());

  return fSuccess;

}

BOOL RequireElevation(VOID)

{

  BOOL fSuccess = FALSE;

  SHELLEXECUTEINFO shExecInfo = { 0 };

  shExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);

  shExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;

  shExecInfo.lpVerb = L"runas";

  shExecInfo.lpFile = TEXT(__FILE__);

  shExecInfo.lpParameters = NULL;

  shExecInfo.lpDirectory = NULL;

  shExecInfo.nShow = SW_NORMAL;

  fSuccess = ShellExecuteEx(&shExecInfo);

  if (fSuccess)

  {

    WaitForSingleObject(shExecInfo.hProcess, INFINITE);

    CloseHandle(shExecInfo.hProcess);

  }

  return fSuccess;

}

4. 修改注册表键值。


int main()

{

  if (!IsUserAdmin())

  {

    if (!ElevatePrivileges() || !IsUserAdmin())

    {

      if (RequireElevation())

      

        return 0;

      

      return -1;

    }

    return 0;

  }

  HKEY hKey = NULL;

  LONG lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGISTRY_PATH, 0, KEY_WRITE, &hKey);

  if (lResult != ERROR_SUCCESS)

  

    return -1;

  

  lResult = RegSetValueEx(hKey, REGISTRY_NAME, 0, REG_SZ, (BYTE*)REGISTRY_VALUE, strlen(REGISTRY_VALUE));

  if (lResult != ERROR_SUCCESS)

  {

    RegCloseKey(hKey);

    return -1;

  }

  RegCloseKey(hKey);

  return 0;

}

通过以上步骤,我们可以自动申请管理员权限并在C++启动时自动修改注册表键值。这可以让我们更方便地进行注册表操作,并保证程序正常运行。

  
  

评论区

{{item['qq_nickname']}}
()
回复
回复