在C#中通过WMI终止进程时访问被拒绝

时间:2017-07-28 11:15:44

标签: c# wmi

我有一个控制台应用程序。我使用WMI来终止特定进程。 当我在Visual Studio(IDE)中运行此应用程序时,该过程将成功终止。

我已经构建了应用程序,当我从命令提示符运行exe时,我得到Access Denied。

我正在以管理员身份运行Visual Studio和命令提示符(cmd.exe)。

    public static void WmiProcessHelper(string serverName, string processAction)
    {
        List<string> resultCode = null;
        try
        {
            ConnectionOptions connectionOptions = new ConnectionOptions()
            {
                Impersonation = ImpersonationLevel.Impersonate,

            };

            ManagementScope scope = GetManagementScope(Root + serverName + WmiRootNamespace, connectionOptions);
            scope.Connect();

            string wmiQuery =
                "SELECT * FROM Win32_process WHERE Name = 'dllhost.exe' AND CommandLine LIKE '%/Processid:{69F26581-22FB-4A52-9A7A-806760E3CB7D}%'";
            ObjectQuery objectQuery = new ObjectQuery(wmiQuery);

            ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, objectQuery);
            ManagementObjectCollection objectCollection = searcher.Get();
            foreach (ManagementBaseObject managementBaseObject in objectCollection)
            {
                if (resultCode == null)
                {
                    resultCode = new List<string>();
                }
                ManagementObject process = (ManagementObject)managementBaseObject;
                Console.WriteLine(string.Format("{0} the process.", processAction));
                object returnObject = process.InvokeMethod(processAction, null);
                if (returnObject != null)
                {
                    int returnCode;
                    if (int.TryParse(returnObject.ToString(), out returnCode))
                    {
                        Console.WriteLine("Return Code = " + returnCode);
                        //resultCode.Add(GetProcessErrorMessage(returnCode));
                    }
                }
            }
            if (resultCode == null)
            {
                Console.WriteLine("No Process with the given properties exists. ");
            }
            //return GetReturnMessage(resultCode, processAction);
        }
        catch (ManagementException e)
        {
            Console.WriteLine("Exception Occured: " + e.Message);
            throw;
        }
    }`

1 个答案:

答案 0 :(得分:0)

之前我做过的是这样的事情,从工作代码中复制过来。 您将看到connectionoptions的变化取决于它是否是本地计算机。但是,如果仅在本地使用,则至少需要设置impersionation。此代码来自WMI周围的包装类上的连接。

        public void Connect(IPAddress address, string username, string password, string subRoot)
    {
        try
        {
            if ((connection != null) || ( scope != null))
                throw new AlreadyConnectedException("A WMI connection already exists");

            connection = new ConnectionOptions();
            if (NetworkUtility.IsLocalIpAddress(address))
            {
                connection.Impersonation = System.Management.ImpersonationLevel.Impersonate;
            }
            else
            {
                connection.Username = username;
                connection.Password = password;
                connection.Authority = "ntlmdomain:";
            }

            scope = new ManagementScope("\\\\" + address.ToString() + "\\root\\" + subRoot, connection);
            //Connecting with remote machine
            if (!scope.IsConnected)
                scope.Connect();
        }
        catch (Exception ex)
        {
            ex.Data.Add("Address", address.ToString());
            ex.Data.Add("Username", username);
            ex.Data.Add("Password", password);
            ex.Data.Add("WMI Namespace", subRoot);
            throw;
        }
     }

这是终止代码。但我没有看到你正在做的任何概念上的差异。

        public void TerminateExecutingEXE(string fileName)
    {
        try
        {
             if ((scope == null))
                throw new NotConnectedException("No WMI connection exists");

            ObjectQuery objObjectQuery = new ObjectQuery("SELECT * FROM Win32_Process WHERE Name = '"+fileName+"'");
            ManagementObjectSearcher objSearcher = new ManagementObjectSearcher(scope, objObjectQuery);
            foreach (ManagementObject queryObj in objSearcher.Get())
            {
                   if (queryObj["Name"].ToString().ToLower() == fileName.ToLower())
                    {
                        object[] obj = new object[] { 0 };
                        queryObj.InvokeMethod("Terminate", obj);
                    }
             }
            objSearcher = null;
            objObjectQuery = null;
        }
        catch (Exception ex) 
        {
            ex.Data.Add("Filename", fileName);
            throw;
        }
    }