亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何在沒有 WMI 的情況下獲得在遠程計算機上運行的進程的所有者

如何在沒有 WMI 的情況下獲得在遠程計算機上運行的進程的所有者

C#
隔江千里 2023-09-24 17:20:20
我正在創建遠程任務管理器應用程序,并且正在嘗試找出如何在沒有 WMI 的情況下獲得在遠程計算機上運行的進程的進程所有者。使用 WMI 確實很容易,但速度太慢。我嘗試使用 WTSQuerySessionInformation,但它僅適用于本地計算機。為了更詳細地說明,我的遠程任務管理器應用程序將在工作站上運行,并將連接到另一個工作站以及同一網絡中的服務器。將運行該應用程序的用戶將是兩臺計算機上的管理員。請問,您是否知道如何獲得遠程進程的所有者的另一種方法,或者對下面的代碼進行一些改進/修復?我的WMI版本(太慢了...)public static Dictionary<Process, string> GetOwners(this IEnumerable<Process> processes){        Dictionary<Process, string> result = new Dictionary<Process, string>();        if (processes == null || processes.Count() == 0) { return result; }        string select = "SELECT Handle, ProcessID FROM Win32_Process";        select += processes.Count() <= 10 ? string.Format(" WHERE ProcessID = {0}", string.Join(" OR ProcessID = ", processes.Select(p => p.Id))) : string.Empty;        ManagementScope scope = new ManagementScope(string.Format("\\\\{0}\\root\\cimv2", processes.ElementAt(0).MachineName));        SelectQuery selectQuery = new SelectQuery(select);        scope.Connect();        using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, selectQuery))        {            using (ManagementObjectCollection objectCollection = searcher.Get())            {                foreach (ManagementObject managementObject in objectCollection)                {                    try                    {                        int id = Convert.ToInt32(managementObject["ProcessID"]);                        string owner = managementObject.InvokeMethod("GetOwner", null, null)["User"]?.ToString();                        result.Add(processes.Single(p => p.Id == id), owner);                    }                    catch                    {                    }                }            }        }        return result;}
查看完整描述

2 回答

?
婷婷同學_

TA貢獻1844條經驗 獲得超8個贊

我建議遷移到較新的命名空間,因為System.Management它較舊、速度較慢且無法擴展。您所追求的新框架是Microsoft.Management.Infrastructure.?以下是Microsoft 文檔對此進行了解釋以及兩者的示例。

所以你會使用這樣的東西:

Using Microsoft.Management.Infrastructure;


CimSession Session = CimSession.Create("computer_name");

CimInstance Instance = Session.QueryInstances(@"root\cimv2", "WQL", "SELECT Name FROM Win32_ComputerSystem");


foreach (CimInstance i in Instance){

? ? Console.WriteLine(i.CimInstanceProperties["Name"].Value);

}

或者


Using Microsoft.Management.Infrastructure;


CimSession Session = CimSession.Create("computer_name");

CimInstance Instance = Session.QueryInstances(@"root\cimv2", "WQL", "SELECT Name FROM Win32_ComputerSystem").First();


Console.WriteLine(Instance.CimInstanceProperties["Name"].Value);

我希望這能給你一些新的兔子洞來解決:-D 如果你還需要什么,請告訴我們:)


查看完整回答
反對 回復 2023-09-24
?
湖上湖

TA貢獻2003條經驗 獲得超2個贊

我創建了獲取流程所有者的最終方法。它仍然不是超級快,但已經足夠快了。與我的問題中的上述 WMI 方法相比,速度提升了 60% 以上,我相信仍有改進的空間。

示例:從另一個 VLAN 中的工作站 獲取數據(進程所有者、ID、句柄、可執行路徑、描述、命令行),但同一網絡域且大約具有 1 個 VLAN。200個進程:

  • 使用上面舊的 WMI 方法:大約。7000毫秒

  • 使用以下新方法:大約。2400毫秒

方法:

public struct WMIProcessProperties

{

? ? public string Owner;

? ? public int ID;

}



public static async Task<Dictionary<Process, WMIProcessProperties>> GetWMIProperties(this IEnumerable<Process> processes)

{

? ? Dictionary<Process, WMIProcessProperties> result = new Dictionary<Process, WMIProcessProperties>();


? ? if (processes == null || processes.Count() == 0) { return result; }


? ? string selectQuery = "SELECT Handle, ProcessID FROM Win32_Process";

? ? selectQuery += processes.Count() <= 10 ? string.Format(" WHERE ProcessID = {0}", string.Join(" OR ProcessID = ", processes.Select(p => p.Id))) : string.Empty;


? ? using (CimSession session = await Task.Run(() => CimSession.Create(processes.ElementAt(0).MachineName)))

? ? {

? ? ? ? List<CimInstance> instances = await Task.Run(() => session.QueryInstances(@"root\cimv2", "WQL", selectQuery).ToList());


? ? ? ? List<Task<WMIProcessProperties>> tasks = new List<Task<WMIProcessProperties>>();


? ? ? ? for (int i = 0; i < instances.Count; i++)

? ? ? ? {

? ? ? ? ? ? CimInstance currentInstance = instances[i];


? ? ? ? ? ? tasks.Add(Task.Run(() =>

? ? ? ? ? ? {

? ? ? ? ? ? ? ? int id = Convert.ToInt32(currentInstance.CimInstanceProperties["ProcessID"].Value);

? ? ? ? ? ? ? ? string owner;

? ? ? ? ? ? ? ? using (CimMethodResult getOwnerResult = session.InvokeMethod(currentInstance, "GetOwner", null))

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ?owner = getOwnerResult.OutParameters["User"]?.Value?.ToString();

? ? ? ? ? ? ? ? }


? ? ? ? ? ? ? ? currentInstance.Dispose();


? ? ? ? ? ? ? ? return new WMIProcessProperties { Owner = owner, ID = id };


? ? ? ? ? ? }));

? ? ? ? }


? ? ? ? WMIProcessProperties[] wmiProcessProperties = await Task.WhenAll(tasks).ConfigureAwait(false);


? ? ? ? for (int i = 0; i < wmiProcessProperties.Length; i++)

? ? ? ? {

? ? ? ? ? ? result.Add(processes.Single(p => p.Id == wmiProcessProperties[i].ID), wmiProcessProperties[i]);

? ? ? ? }

? ? }


? ? return result;

}


查看完整回答
反對 回復 2023-09-24
  • 2 回答
  • 0 關注
  • 153 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號