程式設計中經常遇到windows相關的多使用者問題,以下透過程式碼進行實際驗證。
一、建立一個UserTest程式
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Security.Principal; using System.Text; using System.Threading.Tasks; namespace UserTest { internal class Program { static void Main(string[] args) { // 獲取當前程序 Process currentProcess = Process.GetCurrentProcess(); // 獲取當前 Windows 使用者 WindowsIdentity identity = WindowsIdentity.GetCurrent(); string userName = identity.Name; Console.WriteLine($"當前程序: {currentProcess.ProcessName}"); Console.WriteLine($"啟動使用者: {userName}"); WindowsPrincipal principal = new WindowsPrincipal(identity); // 檢查使用者是否為管理員 bool isAdmin = principal.IsInRole(WindowsBuiltInRole.Administrator); Console.WriteLine($"當前使用者具有管理員許可權: {isAdmin}"); // 獲取當前使用者的主目錄 string userDirectory = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); Console.WriteLine($"當前使用者目錄: {userDirectory}"); Console.ReadLine(); } } }
以此,我們可以獲得當前程序的啟動使用者、許可權、當前使用者目錄
執行得到結果
二、使用管理員許可權對當前使用者的影響
驗證:在非管理員許可權賬戶下,使用管理員許可權執行此程式
結論:管理員許可權並不會改變當前程式的使用者目錄和啟動使用者,只是改變了執行許可權
三、常用的清單檔案獲取管理員許可權對當前使用者的影響
新增以下清單檔案的程式在非管理員前線下執行
<?xml version="1.0" encoding="utf-8"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"> <security> <requestedPrivileges> <requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> </requestedPrivileges> </security> </trustInfo> </assembly>
結論:只是增加了管理員許可權,不會改變程式的執行使用者和程式的使用者目錄
四、指定啟動程式的使用者
要在雙擊程式時使用其他使用者啟動,通常需要使用指令碼或快捷方式來實現,因為 Windows 不直接支援這種功能。以下是一些可能的方法:
使用批處理指令碼
1. 建立批處理檔案:
- 建立一個 `.bat` 檔案,使用 `runas` 命令來指定使用者。
@echo off runas /user:DOMAIN\Username "path\to\your\program.exe"
- 當執行此批處理檔案時,系統會提示輸入密碼。
使用快捷方式
1. 建立快捷方式:
- 右鍵點選桌面,選擇“新建” > “快捷方式”。
- 在“請鍵入物件的位置”中輸入:
runas /user:DOMAIN\Username "path\to\your\program.exe"
- 完成建立後,雙擊此快捷方式會提示輸入密碼。
使用任務計劃程式
1. 建立計劃任務:
- 開啟任務計劃程式,建立一個新任務。
- 在“常規”選項卡中,選擇“使用以下使用者賬戶執行”並輸入目標使用者。
- 在“操作”選項卡中,設定啟動程式的路徑。
- 建立一個指向該任務的快捷方式,使用 `schtasks` 命令來執行:
schtasks /run /tn "TaskName"
驗證結果表:
雙擊 bat檔案指定runas使用者啟動 | 程序處於當前會話上 | 獲取的為指定的使用者 | 當前使用者目錄為指定的使用者目錄 | 程序使用者為指定使用者 |
雙擊 快捷方式指定runas使用者啟動 | 程序處於當前會話上 | 獲取的為指定的使用者 | 當前使用者目錄為指定的使用者目錄 | 程序使用者為指定使用者 |
雙擊 傳送快捷方式不指定runas使用者啟動 | 程序處於當前會話上 | 獲取的為指定的使用者 | 當前使用者目錄為指定的使用者目錄 | 程序使用者為指定使用者 |
使用定時任務啟動 | 程序處於指定的會話上 | 獲取的為指定的使用者 | 當前使用者目錄為指定的使用者目錄 | 程序使用者為指定使用者 |
結論:
在不指定使用者時,使用者雙擊,哪個使用者的會話就使用哪個使用者的資源。
在指定使用者時候,使用者雙擊啟動(透過會話),會在當前會話建立指定使用者程序的程式。
在指定使用者時候,不透過UI操作啟動,完全使用指定使用者的資源。
五、結論
-
桌面會話:
- Windows 將圖形介面程式與當前使用者的桌面會話關聯,因此即使程式以其他使用者身份執行,它的介面仍會顯示在當前使用者的桌面上。
-
安全和隔離:
- Windows 的安全模型設計為隔離不同使用者的會話,以防止未經授權的訪問。這意味著即使程序以其他使用者身份執行,它也不能直接訪問其他使用者的桌面會話。
-
工作管理員顯示:
- 工作管理員會根據當前使用者的會話顯示程式,即使程式是由其他使用者啟動
六、指定會話啟動
如果希望程式在不同使用者的桌面會話中執行(例如在遠端桌面或不同的使用者會話中),可以考慮以下方法:
-
遠端桌面:
- 使用遠端桌面協議 (RDP) 登入到目標使用者的會話,然後啟動程式。
-
切換使用者:
- 使用“切換使用者”功能登入到另一個使用者會話,然後啟動程式。
-
任務計劃程式:
- 配置任務計劃程式在目標使用者的會話中執行任務,並確保“僅在使用者登入時執行”選項被選中。
- 服務化