1 回答
TA貢獻(xiàn)1869條經(jīng)驗(yàn) 獲得超4個(gè)贊
不幸的是,實(shí)際上并沒有任何干凈的方法來執(zhí)行此操作,至少我找不到,除非您愿意使用類似query userwithPsExec的方法在每臺(tái) PC 上將其作為子進(jìn)程遠(yuǎn)程執(zhí)行,然后解析結(jié)果。即使那樣,您也無法直接獲得有關(guān)鎖定狀態(tài)的答案,您將不得不按空閑時(shí)間進(jìn)行處理,因?yàn)楫?dāng)沒有人使用計(jì)算機(jī)時(shí),狀態(tài)會(huì)將其中一個(gè)用戶顯示為活動(dòng)狀態(tài)。
然后是多個(gè)用戶登錄計(jì)算機(jī)的問題,使用 Windows 7 或更高版本中的切換用戶功能。在我的環(huán)境中,一臺(tái) PC 可能有 3 或 4 個(gè)后臺(tái)用戶和一個(gè)控制臺(tái)用戶。在某些情況下,PC 由 RDP 用戶使用。事實(shí)證明,當(dāng)您通過 RDP 連接到計(jì)算機(jī)然后登錄到控制臺(tái)或執(zhí)行相反操作時(shí),會(huì)出現(xiàn)一種特殊情況,因?yàn)樵谶@些情況下 LogonSession LogonType 不會(huì)更新。不幸的是,也有可能捕捉到用戶剛剛登錄計(jì)算機(jī),在這種情況下,我的函數(shù)將錯(cuò)誤地指出計(jì)算機(jī)未在使用中。
在我的 PC 和網(wǎng)絡(luò)上,如果 PC 打開,此函數(shù)運(yùn)行大約需要 0.2 秒。在某些 PC 上,它可能需要更長(zhǎng)的時(shí)間(最多 20 秒),因?yàn)樗鼤?huì)在 PC 上加載 perfmon 提供程序。如果 PC 關(guān)閉,超時(shí)時(shí)間會(huì)很長(zhǎng),如果可能的話,我建議先進(jìn)行 ping 檢查。
基本上,該函數(shù)使用 WMI 獲取 LogonSession 和交互式桌面信息,并Process獲取 LogonUI 和資源管理器進(jìn)程。由于 LogonSession 返回已注銷的舊會(huì)話,以及 UAC 管理程序和其他 (Windows 10) 后臺(tái)進(jìn)程 (DWM/UMFD) 的會(huì)話,因此我們只計(jì)算具有explorer.exe進(jìn)程(桌面)的 LogonSession。
然后它將信息組合成不同的情況:
如果 LogonUI 進(jìn)程數(shù)大于或等于交互式桌面數(shù),PC 將被注銷或鎖定。如果PC上有任何LogonSession(帶explorer),則鎖定,否則注銷。
如果 LogonUI 進(jìn)程數(shù)少于交互式桌面數(shù),則 PC 正在使用中。
這是代碼:
enum PCUserStatuses {
Locked, // all users are locked
LoggedOff, // No users are logged in
InUse, // A user is using this computer
Unknown // unable to connect to computer / other error
}
PCUserStatuses GetPCUserStatus(string machineName) {
try {
var scope = GetManagementScope(machineName);
scope.Connect();
var explorerProcesses = Process.GetProcessesByName("explorer", machineName)
.Select(p => p.Id.ToString())
.ToHashSet();
var REprocessid = new Regex(@"(?<=Handle="").*?(?="")", RegexOptions.Compiled);
var numberOfLogonSessionsWithExplorer = new ManagementObjectSearcher(scope, new SelectQuery("SELECT * FROM Win32_SessionProcess")).Get()
.Cast<ManagementObject>()
.Where(mo => explorerProcesses.Contains(REprocessid.Match(mo["Dependent"].ToString()).Value))
.Select(mo => mo["Antecedent"].ToString())
.Distinct()
.Count();
var numberOfUserDesktops = new ManagementObjectSearcher(scope, new SelectQuery("select * from win32_Perfrawdata_TermService_TerminalServicesSession")).Get().Count - 1; // don't count Service desktop
var numberOflogonUIProcesses = Process.GetProcessesByName("LogonUI", machineName).Length;
if (numberOflogonUIProcesses >= numberOfUserDesktops) {
if (numberOfLogonSessionsWithExplorer > 0)
return PCUserStatuses.Locked;
else
return PCUserStatuses.LoggedOff;
}
else
return PCUserStatuses.InUse;
}
catch {
return PCUserStatuses.Unknown;
}
}
- 1 回答
- 0 關(guān)注
- 138 瀏覽
添加回答
舉報(bào)
