zoukankan      html  css  js  c++  java
  • VC程序获取管理员权限

    一:

    编译程序的时候设置一下
    在项目属性--连接器--清单文件--UAC执行级别改为requireAdministrator

    二:

    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是应用程序的路径idd我传的是1,但好像传几都没问题

    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;
    }
    

    如何获取正确的文件路径

    当我们那些在Windows 7之前设计的应用程序遇到UAC Virtualization问题的时候,我们需要从新设计我们的代码,将文件写入到合适的位置。在改善既有代码,使之可以与Windows 7兼容的时候,我们应该确保以下几点:

      ——在运行的时候,应用程序只会将数据保存到每个用户预先定义的位置或者是%alluserprofile% 中定义的普通用户拥有访问权限的位置。

      ——确定你要写入数据的“已知文件夹”(Knownfolders)。通常,所有用户共用的公共数据文件应该写入到一个全局的公共的位置,这样所有用户都可以访问到。而其它数据则应该写入每个用户自己的文件夹。

      1 公共数据文件包括日志文件,配置文件(通常是INI或者XML文件),应用程序状态文件,比如保存的游戏进程等等。

      2 而属于每个用户的文档,则应该保持在文档目录下,或者是用户自己指定的目录。

      ——当你确定合适的文件保存位置后,不要在代码中明文写出(Hard-code)你选择的路径。为了更好地保持兼容性,我们应该采用下面这些API来获得操作系统“已知文件夹(Knownfolders)”的正确路径。

      1 C/C++非托管代码: 使用SHGetKnownFolderPath函数,通过指定“已知文件夹”的KNOWNFOLDERID作为参数来获得正确的文件夹路径。

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

    下面这段代码演示了在非托管代码中如何调用shell函数,SHGetKnownFolderPath函数获得正确的文件保存路径(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 托管代码: 使用System.Environment.GetFolderPath函数,通过指定我们想要获取的“已知文件夹”为参数,从而获取相应的文件夹的正确路径。

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

    下面这段代码展示了如何在托管代码中获取正确的文件路径:

    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);
                }
            }
            // …
       }
    }
    

    如果上面的方法都不适合你,你还可以使用环境变量,使用getenv()或GetEnvironmentVariable()获取相应的文件夹路径:

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

    参考:

  • 相关阅读:
    在Myeclipse中配置tomcat
    tomcat用startup.bat启动时,界面一闪消失
    单向链表的基本操作
    简单排序的对比
    关于string的排序 选择插入排序
    insertsort
    selectsort
    理解函数式编程
    vue中使用$nextTick后任然无法正确计算出元素高度
    使用vuex+vue-i18n方式国际化
  • 原文地址:https://www.cnblogs.com/yhcao/p/6237592.html
Copyright © 2011-2022 走看看