最新消息

[公告2014/05/30] 如有需要將部落格中,任何一篇文章的程式碼使用在商業用途,請與我聯繫。

[公告2015/04/26] Line版的 iInfo程式與投資應用 群組已上線想加入的朋友們,請先查看 "入群須知" 再與我聯繫 Line : aminwhite5168,加入請告知身分與回答 "入群須知" 的問題。

[公告2018/04/22] 台北 Python + Excel VBA 金融資訊爬蟲課程,課程如網頁內容 金融資訊爬蟲班:台北班 Python 金融資訊爬蟲、EXCEL VBA 金融資訊爬蟲

[公告2019/01/08] 請注意:我再次重申,部落格文章的程式碼,是要提供各位參考與學習,一旦網頁改版請自行修改,別要求東要求西要我主動修改,你們用我寫東西賺錢了、交差了,請問有分我一杯羹嗎?既然賺錢沒分我,請問有什麼理由要求我修改,如果沒能力改,就花錢來找我上課。

[公告2019/12/01] 若各位有 Excel VBA 案子開發需求,歡迎與我聯繫,可接案處理。

[公告2020/05/22] 頁面載入速度慢,起因為部分JS來源(alexgorbatchev.com)失效導致頁面載入變慢,目前已做調整,請多見諒。

2015年9月24日 星期四

在Vista、Win7、Win8、Win10,處理UAC權限問題

近期群裡有朋友提到,要如何處理UAC權限的問題,雖然已經會了,但還是在網路上找一下相關資料,順道做紀錄。
方法一:透過VC++程式碼,將程式的執行權限提高至管理者權限,如下程式碼內容。
BOOL EnablePrivilege(LPCTSTR lpszPrivilegeName)
{
 HANDLE hToken;
 TOKEN_PRIVILEGES tkp;

 // Get a token for this process.
 if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY ,&hToken))
 {
  printf("ERROR : Fail to open process token.\n");
  return FALSE;
 }

 // Get the LUID for the shutdown privilege. 
 if(!LookupPrivilegeValue(NULL, lpszPrivilegeName, &tkp.Privileges[0].Luid))
  return TRUE;

 tkp.PrivilegeCount = 1;
 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

 // Get the shutdown privilege for this process. 
 AdjustTokenPrivileges(hToken, FALSE, &tkp, NULL, (PTOKEN_PRIVILEGES)NULL, NULL);
 CloseHandle(hToken);

 return  GetLastError() == ERROR_SUCCESS
}

方法二:透過編譯器的Linker的設定,限定VC2008以後的版本使用。

我們先來了解系統權限分類:
asInvoker:應用程式的權限層級相當於啟動應用程式的處理序,例如 A 程序啟動 B 程序,B 的層級就與 A 的層級相同,如果由使用者手動啟動,則等於使用者的帳戶權限層級。

highestAvailable:應用程式的權限層級會與從使用者帳戶層級和啟動它的程序中挑出最高的層級,例如使用者為管理者,有個一般權限的 A 啟動了 B,則 B 的層級會是管理者層級,因為管理者層級較高。或是使用者為一般帳戶執行了一個有數位簽章的安裝檔,則此安裝檔在安裝完畢後所啟動的應用程式會是超過使用者帳戶的權限層級。

requireAdministrator:開啟此應用程式時一律要求要獲得管理者帳戶認證,一般用戶開啟則跳帳號密碼認證,管理者開啟即跳此為管理者權限詢問是否開啟並允許修改電腦設定。

開啟VS2010,在Properties->Linker->UAC Execution Level->選擇 requireAdministrator (/level='requireAdministrator')。

方法三:VS2008前的版本需要在resource中添加一個manifest檔案,resource名稱24,ID為1。
以下筆者拿VC6的做法來說明,如何添加manifest檔案。
假設你的EXE名稱為TestApp.exe,在EXE資料夾中建立一個res的目錄,裡面編寫一個manifest檔案,命名為TestApp.exe.manifest。
manifest文件如下:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
    version="1.0.0.0"
    processorArchitecture="X86"
    name="TestApp.exe.manifest"
    type="win32"
/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
        <requestedPrivileges>
            <requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
        </requestedPrivileges>
    </security>
</trustInfo>
</assembly>

Step 2. 建立一個Resource名稱為"24"的項目。

Step 3. 加入TestApp.exe.manifest到Resource "24" 下。


Step 4. 修改Resource ID為"1"。


最完成的內容。

比較有添加TestApp.exe.manifest跟未添加TestApp.exe.manifest的圖形差異。

方法四:修改系統機碼。
For User
HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers

For Machine
HKEY_LOCAL_MACHUNE\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers

Step 1. 如果沒有見到Layers資料夾,請自行手動新增一個 機碼(K),名子叫做Layers

Step 2. 新增 "C:\TestApp.exe" 字串機碼。

Step 3. 指定 "C:\TestApp.exe" 字串機碼的數值資料為Runasadmin,即管理者權限。

或是參考以下懶人做法
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers]
"C:\\TestApp.exe"="Runasadmin"
將上面的內容存成UAC.reg文件,其中把C:\\TestApp.exe改為真實環境的應用程式路徑,按兩下即可。
這種方法後應用程式圖示不會有盾狀圖示,但按兩下運行仍然會彈出對話方塊要求提升許可權。

方法五:透過 Windows SDK 的Mt.exe來添加TestApp.exe.manifest。
將方法三中的TestApp.exe.manifest,與TestApp.exe方法同一資料夾中。
Step 1. 安裝Windows SDK
Step 2. 開啟命令提示字元,將路徑切換至C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin,輸入以下指令。
mt.exe -manifest C:\TestApp.exe.manifest -outputresource:C:\TestApp.exe;1
參考資料來源: