第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

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

如何讓 Win32_Process 查詢更快?

如何讓 Win32_Process 查詢更快?

C#
拉丁的傳說 2022-06-12 11:06:55
我有以下函數(shù)將進程信息提取到 DataTable 中:public DataTable getProcesses()        {            DataTable dt = new DataTable();            dt.Columns.Add("ID");            dt.Columns.Add("Name");            dt.Columns.Add("Path");            dt.Columns.Add("User");            dt.Columns.Add("Priority");            string pid = "-";            string name = "-";            string path = "-";            string priort = "-";            string user = "-";            string query = "Select * From Win32_Process";            ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);            ManagementObjectCollection processList = searcher.Get();            foreach (ManagementObject proc in processList)            {                pid = proc["ProcessID"].ToString();                name = proc["Name"].ToString();                if (proc["ExecutablePath"] != null)                {                    path = proc["ExecutablePath"].ToString();                    priort = proc["Priority"].ToString();                }                string[] argList = new string[2];                int returnVal = Convert.ToInt32(proc.InvokeMethod("GetOwner", argList));                if (returnVal == 0)                {                    // return DOMAIN\user                    user = argList[1] + "\\" + argList[0];                }                dt.Rows.Add(pid, name, path, user, priort);            }            return dt;        }這最終會奏效并給我想要的回報,但執(zhí)行需要 20-30 秒。我想知道是否有任何方法可以優(yōu)化功能,或者特別是查詢,這很可能是“延遲”的來源。編輯在做了評論中建議的一些事情之后,平均時間已經(jīng)下降到 15-20 秒,但這仍然太長了。最多4-5秒是可以忍受的。我仍然沒有更改查詢,有什么辦法可以讓它更快嗎?編輯 2在應用了@NicoRiff 建議的一些更改后,仍然獲得相同的運行時,我進行了一些調(diào)試以查看實際花費了這么長時間。原來它是特定的一行:int returnVal = Convert.ToInt32(proc.InvokeMethod("GetOwner", argList));,這將使我成為“擁有”每個進程的用戶。這條線大約需要 60 毫秒,而所有其他線需要 1-2 毫秒。超過 200 次迭代(這是我擁有的進程數(shù),我只能想象使用更大的列表所需的時間),總共需要大約 12-13 秒(僅針對那一行),給出 15-20總和。既然我已經(jīng)“挑出”了問題,我該如何優(yōu)化該功能?
查看完整描述

2 回答

?
有只小跳蛙

TA貢獻1824條經(jīng)驗 獲得超8個贊

從技術(shù)上講,這并不能回答您的問題,因為它不使用 Win32_Process 查詢。但是,使用 Powershell,它確實會在很短的時間內(nèi)(~1.5 秒對~25 秒)產(chǎn)生相同的結(jié)果。


您需要在 X64 模式下運行它以詢問 64 位進程,并且需要提升權(quán)限才能讓 Powershell 返回用戶名。


請注意,這是我第一次從 C# 調(diào)用 Powershell 腳本,可能有更好的方法來做。它還需要一些錯誤捕獲以使其更健壯(不適合按原樣生產(chǎn))。


using System.Management.Automation;

using System.Management.Automation.Runspaces;


private DataTable getProcesses() 

{

    // Create the datatable and columns

    DataTable dt = new DataTable();

    dt.Columns.Add("ID");

    dt.Columns.Add("Name");

    dt.Columns.Add("Path");

    dt.Columns.Add("User");

    dt.Columns.Add("Priority");

    dt.Columns.Add("BasePriority"); 


    string script = $"get-process -IncludeUserName | select id, processname, path, username, priorityclass";


    List<string[]> psOutput = new List<string[]>();


    // Invoke Powershell cmdlet and get output

    using (PowerShell ps = PowerShell.Create())

    {

        ps.AddScript(script);

        var output = ps.Invoke();

        if(ps.Streams.Error.Count > 0)

        {

            throw new Exception($"Error running script:{Environment.NewLine}{string.Join(Environment.NewLine, ps.Streams.Error.Select(e => e.ToString()))}");

        }


        // clean and split the output

        psOutput.AddRange(output.Select(i => i.ToString().Replace("; ", ";").TrimStart("@{".ToCharArray()).TrimEnd('}').Split(';')));

    }


    // populate the DataTable

    psOutput

        .AsParallel()           // this does not really help when not calling Process.GetProcessById

        .Select(p => p.Select(f => f.Split("=")).ToDictionary(k => k.FirstOrDefault(), v => v.LastOrDefault()))

        .Select(kv => new object[] {    // "flatten" the dictionaries into object[]'s that will become the datarows

                        kv["Id"]

                        , kv["ProcessName"]

                        , kv["Path"]

                        , kv["UserName"]

                        , kv["PriorityClass"]

                        , Process.GetProcessById(int.Parse(kv["Id"])).BasePriority  // if you need the numerical base priority - takes quite a bit longer though (Not sure how to get this via Powershell)

                    }

            )

        .ToList()

        .ForEach(r => dt.Rows.Add(r));  // add each object[] to the datatable


    // return the datatable 

    return dt;

}


查看完整回答
反對 回復 2022-06-12
?
一只名叫tom的貓

TA貢獻1906條經(jīng)驗 獲得超3個贊

我個人一直想擺脫使用DataTable. 您可以使用List<>可以解決許多潛在問題的集合。


話雖如此,您可能想查看ORMi庫以獲取有關(guān)List<>. 您可以通過以下方式實現(xiàn)您正在嘗試的目標:


        WMIHelper helper = new WMIHelper("root\\CimV2");


        string pid = "-";

        string name = "-";

        string path = "-";

        string priort = "-";

        string user = "-";


        var processes = helper.Query("Select * From Win32_Process").ToList();


        foreach (var p in processes)

        {

            pid = p.ProcessID;

            name = p.Name;

            path = p.ExecutablePath ?? String.Empty;

            priort = p.Priority ?? String.Empty;

        }

上面的代碼適用于dynamic對象,不需要您編寫任何模型。就是那個小代碼。如果您需要使用方法,那么您可以聲明您的模型并使用強類型對象:


1)定義你的模型:


[WMIClass(Name = "Win32_Process", Namespace = "root\\CimV2")]

public class Process

{

    public int Handle { get; set; }

    public string Name { get; set; }

    public int ProcessID { get; set; }

    public string ExecutablePath { get; set; }

    public int Priority { get; set; }


    /// <summary>

    /// Date the process begins executing.

    /// </summary>

    public DateTime CreationDate { get; set; }


    public dynamic GetOwnerSid()

    {

        return WMIMethod.ExecuteMethod(this);

    }


    public ProcessOwner GetOwner()

    {

        return WMIMethod.ExecuteMethod<ProcessOwner>(this);

    }


    public int AttachDebugger()

    {

        return WMIMethod.ExecuteMethod<int>(this);

    }

}


public class ProcessOwner

{

    public string Domain { get; set; }

    public int ReturnValue { get; set; }

    public string User { get; set; }

}

2)查詢WMI


        List<Process> processes = helper.Query<Process>().ToList();


        foreach (Process p in processes)

        {

            pid = p.ProcessID;

            name = p.Name;

            path = p.ExecutablePath ?? String.Empty;

            priort = p.Priority ?? String.Empty;


            dynamic d = p.GetOwnerSid();

            ProcessOwner po = p.GetOwner();

        }

即使對于這個任務(wù),第二種方式可能看起來有點太多的工作,你會得到更干凈和易于理解的代碼。


注意:我已經(jīng)用 ORMi 嘗試過你的代碼,我會在 1-2 秒內(nèi)得到結(jié)果。正如其他人所說,這可能取決于您的環(huán)境。


SELECT注意 2:始終只使用語句中需要的屬性。WMI a 非常昂貴SELECT *。始終指定屬性。在您的情況下,它將是:


Select ProcessID, Name, ExecutablePath, Priority From Win32_Process

(ORMi 也會為您解決這個問題,因為它總是會查詢模型上設(shè)置的屬性。)


查看完整回答
反對 回復 2022-06-12
  • 2 回答
  • 0 關(guān)注
  • 182 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學習伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號