通话不明确的问题

时间:2019-09-04 13:07:04

标签: c# winforms

我很难找出问题所在。我正在尝试制作一种进程监视器,该进程监视器加载进程列表,ID,所有者的用户名,内存使用情况和描述..这个错误让我非常头疼。

private void Button1_Click(object sender, EventArgs e)
{
    Process[] procList = Process.GetProcesses();
    foreach (Process process in procList)
    {
        // get status
        string status = (process.Responding == true ? "Responding" : "Not responding");
        // get username and description
        string query = "SELECT * FROM Win32_Process WHERE ProcessID = " + process.Id;
        ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
        ManagementObjectCollection processList = searcher.Get();
        dynamic response = new ExpandoObject();
        response.Description = "";
        response.Username = "Unknown";
        foreach (ManagementObject obj in processList)
        {
            // get username
            string[] argList = new string[] { string.Empty, string.Empty };
            int returnValue = Convert.ToInt32(obj.InvokeMethod("GetOwner", argList));
            if (returnValue == 0)
                response.Username = argList[0];
            if (obj["ExecutablePath"] != null)
            {
                try
                {
                    FileVersionInfo info = FileVersionInfo.GetVersionInfo(obj["ExecutablePath"].ToString());
                    response.Description = info.FileDescription;
                }
                catch { }
            }
        }
        // get memory usage
        int memsize = 0; // memsize in Megabyte
        PerformanceCounter PC = new PerformanceCounter();
        PC.CategoryName = "Process";
        PC.CounterName = "Working Set - Private";
        PC.InstanceName = process.ProcessName;
        memsize = Convert.ToInt32(PC.NextValue()) / (int)(1024);
        memsize = (memsize / 1024);
        PC.Close();
        PC.Dispose();
        ListViewItem item = new ListViewItem();
        item.Text = process.Id.ToString();
        item.SubItems.Add(process.ProcessName);
        item.SubItems.Add(status);
        item.SubItems.Add(response.Username);
        item.SubItems.Add(memsize.ToString() + " MB");
        item.SubItems.Add(response.Description);
        listView1.Items.Add(item);
    }
}

当我尝试调试程序时,它几乎没有任何输出(请参阅此处-> https://i.imgur.com/D4ftBgb.png),然后显示错误-> https://i.imgur.com/m1R90hz.png

3 个答案:

答案 0 :(得分:2)

因为使用dynamic,所以方法重载解析将延迟到运行时。您有一个null response.Usernameresponse.Description,因此动态运行时不知道要调用哪个重载。比较:

public class Test
{
    public static void Main()
    {
        dynamic bar = null;

        try
        {
            Foo(bar);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
        }
    }

    private static void Foo(string f) { }
    private static void Foo(int? o) { }
}

这将引发相同的异常,因为两个重载都可以接受null,并且不存在其他类型信息。

要解决此问题,请通过强制转换为字符串来明确指定重载:

Foo((string)bar);

或者您的情况是SubItems.Add((string)response.Username)

或者根本不使用dynamic来填充变量,而是将它们都声明为单独的变量:string description = "", username = ""

答案 1 :(得分:1)

您的response.Usernameresponse.Description的类型均为dynamicListViewSubItemCollection.Add()无法决定使用which overload,因此,您需要将它们转换为string

尝试以下操作:

string username = Convert.ToString(response.Username);
string description = Convert.ToString(response.Description);

ListViewItem item = new ListViewItem();
item.Text = process.Id.ToString();
item.SubItems.Add(process.ProcessName);
item.SubItems.Add(status);
item.SubItems.Add(username);
item.SubItems.Add(memsize.ToString() + " MB");
item.SubItems.Add(description);
listView1.Items.Add(item);

答案 2 :(得分:0)

最好的长期解决方案是删除对dynamic的使用,并使用具有classDescription属性的显式Username

最直接的解决方法是更改​​:

response.Description = info.FileDescription;

收件人:

response.Description = info.FileDescription ?? "";

为什么需要这样做(?? "")?由于Description永远不会是null,因此它将允许重载解析正常工作。 null时不起作用的原因是null的{​​{1}}属性没有与之关联的类型。这与普通类不同,在普通类中,编译器知道属性的类型为ExpandoObject