VC program to obtain administrator privileges

one:

When compiling the program, set it
in the project properties - linker - manifest file - UAC execution level to requireAdministrator

two:

void GainAdminPrivileges(CString strApp, UINT idd)
{
    CString         strCmd;
    strCmd.Format (_T("/adminoption %d"), idd);

    SHELLEXECUTEINFO execinfo;
    memset(&execinfo, 0, sizeof(execinfo));
    execinfo.lpFile         = strApp;
    execinfo.cbSize         = sizeof(execinfo);
    execinfo.lpVerb         = _T("runas");
    execinfo.fMask          = SEE_MASK_NO_CONSOLE;
    execinfo.nShow          = SW_SHOWDEFAULT;
    execinfo.lpParameters   = strCmd;

    ShellExecuteEx(&execinfo);
}  

strApp is the path idd of the application, I pass it 1, but it seems to be fine

BOOL ElevateCurrentProcess(CString sCmdLine)
{
    TCHAR szPath[MAX_PATH] = {0};

    if (::GetModuleFileName(NULL, szPath, MAX_PATH))
    {
        // Launch itself as administrator.
        SHELLEXECUTEINFO sei = { sizeof(SHELLEXECUTEINFO) };
        sei.lpVerb = _T("runas");
        sei.lpFile = szPath;
        sei.lpParameters = (LPCTSTR)sCmdLine;
        //     sei.hwnd = hWnd;
        sei.nShow = SW_SHOWNORMAL;

        if (!ShellExecuteEx(&sei))
        {
            DWORD dwStatus = GetLastError();
            if (dwStatus == ERROR_CANCELLED)
            {
                // The user refused to allow privileges elevation.
                return FALSE;
            }
            else if (dwStatus == ERROR_FILE_NOT_FOUND)
            {
                // The file defined by lpFile was not found and
                // an error message popped up.
                return FALSE;
            }
            return FALSE;
        }
        return TRUE;
    }
    return FALSE;
}

How to get the correct file path

When our applications designed before Windows 7 encountered UAC Virtualization issues, we needed to redesign our code to write files to the proper location. When improving existing code to make it compatible with Windows 7, we should ensure the following:

  - At runtime, the application will only save data to a location predefined by each user or to a location defined in %alluserprofile% to which normal users have access rights.

  - Determine the "Knownfolders" where you want to write data. In general, common data files common to all users should be written to a global common location so that all users can access them. Other data should be written to each user's own folder.

  1 Common data files include log files, configuration files (usually INI or XML files), application state files, such as saved game progress, etc.

  2 The documents belonging to each user should be kept in the document directory, or the directory specified by the user.

  - When you determine the appropriate file storage location, do not write out (Hard-code) the path you choose in the code. For better compatibility, we should use the following APIs to get the correct path to the operating system's "Knownfolders".

  1 C/C++ unmanaged code: Use the SHGetKnownFolderPath function to get the correct folder path by specifying the KNOWNFOLDERID of the "known folder" as a parameter.

  FOLDERID_ProgramData –所有用户都可以访问的应用程序数据适合放置在这个目录下。
  FOLDERID_LocalAppData – 每个用户单独访问的应用程序数据适合放置在这个目录下。
  FOLDERID_RoamingAppData – 每个用户单独访问的应用程序数据适合放置在这个目录下。 与上面一个目录不同的是,放置在这个目录下的文件会随着用户迁移,当一个用户在同一个域中的其他计算机登录的时候,这些文件会被复制到当前登录的机器上,就像用户随身携带的公文包一样。

The following code demonstrates how to call the shell function in unmanaged code. The SHGetKnownFolderPath function obtains the correct file save path (SHGetFolderLocation, SHGetFolderPath, SHGetSpecialFolderLocation, SHGetSpecialFolderPath):

#include "shlobj.h"
#include "shlwapi.h"
//…

#define AppFolderName _T("YourApp")
#define DataFileName _T("SomeFile.txt")

// 构造一个数据文件路径
// dataFilePath指向一个长度为MAX_PATH,类型为TCHAR的字符串数值
// hwndDlg是消息对话框的父窗口句柄
// 当有错误发生的时候用于显示错误提示
// includeFileName用于表示是否在路径后面扩展文件名
BOOL MakeDataFilePath(TCHAR *dataFilePath, 
                      HWND hwndDlg, BOOL includeFileName)
{
    // 初始化工作
    memset(dataFilePath, 0, MAX_PATH * sizeof(TCHAR));
    PWSTR pszPath = NULL;

    // SHGetKnownFolderPath函数可以返回一个已知文件见的路径,
    // 例如我的文档(My Documents),桌面(Desktop),
       // 应用程序文件夹(Program Files)等等。 
    // 对于数据文件来说,FOLDERID_ProgramFiles并不是一个合适的位置
    // 使用FOLDERID_ProgramFiles保存所有用户共享的数据文件
    // 使用FOLDERID_LocalAppData保存属于每个用户自己的文件(non-roaming).
    // 使用FOLDERID_RoamingAppData保存属于每个用户自己的文件(roaming).
// 对于“随身文件”(Roaming files),
// 当一个用户在一个域中的其他计算机登陆的时候,
    // 这些文件会被复制到当前登录的机器上,就像用户随身携带的公文包一样    

    // 获取文件夹路径
    if (FAILED(SHGetKnownFolderPath(FOLDERID_ProgramData,
               0, NULL, &pszPath)))
    // 错误的做法: if (FAILED(SHGetKnownFolderPath(FOLDERID_ProgramFiles,
       // 0, NULL, &pszPath)))
    {
        // 提示错误
        MessageBox(hwndDlg, _T("SHGetKnownFolderPath无法获取文件路径"),
            _T("Error"), MB_OK | MB_ICONERROR);
        return FALSE;
    }

    // 复制路径到目标变量
    _tcscpy_s(dataFilePath, MAX_PATH, pszPath);
    ::CoTaskMemFree(pszPath);

    //错误的做法: _tcscpy_s(dataFilePath, MAX_PATH, _T("C:\\"));

    // 在路径后面扩展应用程序所在文件夹
    if (!::PathAppend(dataFilePath, AppFolderName))
    {
        // 提示错误
        MessageBox(hwndDlg, _T("PathAppend无法扩展路径"),
            _T("Error"), MB_OK | MB_ICONERROR);
        return FALSE;
    }

    // 是否添加文件名
    if (includeFileName)
    {
        // 在路径后扩展文件名
        if (!::PathAppend(dataFilePath, DataFileName))
        {
            // 提示错误
            MessageBox(hwndDlg, _T("PathAppend无法扩展文件名"),
                _T("Error"), MB_OK | MB_ICONERROR);
            return FALSE;
        }
    }

    return TRUE;
}

2 Managed code: Use the System.Environment.GetFolderPath function to get the correct path of the corresponding folder by specifying the "known folder" we want to get as a parameter.

  Environment.SpecialFolder.CommonApplicationData – 所有用户都可以访问的应用程序数据适合放置在这个目录下。
  Environment.SpecialFolder.LocalApplicationData – 每个用户单独访问的应用程序数据适合放置在这个目录下。
  Environment.SpecialFolder.ApplicationData – 每个用户单独访问的应用程序数据适合放置在这个目录下。这是“随身文件夹”。

The following code snippet shows how to get the correct file path in managed code:

internal class FileIO
    {
        private const string AppFolderName = "YourApp";
        private const string DataFileName = "SomeFile.txt";
        private static string _dataFilePath;

        /// <summary>
        /// 构建路径
        /// </summary>
        static FileIO()
        {
            // Environment.GetFolderPath返回一个“已知文件夹”的路径
            // Path.Combine可以合并两个路径成一个合法的路径

            // …

            _dataFilePath = Path.Combine(Environment.GetFolderPath(
                  Environment.SpecialFolder.ProgramFiles), AppFolderName);
            //错误的做法:
            //_dataFilePath = Path.Combine(Environment.GetFolderPath(
             Environment.SpecialFolder.CommonApplicationData), AppFolderName);

            // 扩展文件名
            _dataFilePath = Path.Combine(_dataFilePath, DataFileName);
        }

         public static void Save(string text)
        {
            // 检查要保存的字符串是否为空
            if (String.IsNullOrEmpty(text))
            {
                MessageBox.Show("字符串为空,无法保持.", "空字符串",
                     MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            try
            {
                // 获取文件保存的路径
                string dirPath = Path.GetDirectoryName(_dataFilePath);
                // 检查文件夹是否存在
                if (!Directory.Exists(dirPath))
                    Directory.CreateDirectory(dirPath); // 创建文件夹
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "文件夹创建失败",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            try
            {
                // 保存字符串到文件
                StreamWriter sw = new StreamWriter(_dataFilePath);
                try
                {
                    sw.Write(text);
                }
                finally
                {
                    // 关闭文件
                    sw.Close();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "文件写入失败",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        // …
   }
}

If none of the above methods work for you, you can also use environment variables, use getenv() or GetEnvironmentVariable() to get the corresponding folder path:

  %ALLUSERSPROFILE% – 所有用户都可以访问的应用程序数据适合放置在这个目录下。
  %LOCALAPPDATA% – 每个用户单独访问的应用程序数据适合放置在这个目录下。 - (Windows Vista 或者Windows 7)
  %APPDATA% – 每个用户单独访问的应用程序数据适合放置在这个目录下。这是“随身文件夹”。- (Windows Vista 或者Windows 7)

refer to:

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324137090&siteId=291194637