ManagementClass.InvokeMethod在重新启动目标计算机后抛出异常 [英] ManagementClass.InvokeMethod throws exception after restart target computer

查看:86
本文介绍了ManagementClass.InvokeMethod在重新启动目标计算机后抛出异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


在我的远程管理表单应用程序中,我发现很少但却是一个不愉快的例外。

In my form app for the remote administration, I just find little but an unpleasant exception.


In有一点,我需要检查远程机器是否需要重启。该检查的一部分是调用方法"DetermineIfRebootPending""在"CCM_ClientUtilities"中WMI类。

In some point, I need to check if remote machine needs restart or not. One part of this check is invoking method "DetermineIfRebootPending" in "CCM_ClientUtilities" class of WMI.


一切正常,但是......当我重新启动目标机器时,调用该方法会抛出异常。当我在几秒钟后再次调用它时,一切都恢复正常,但是当我在第一次尝试后立即调用它时仍然存在相同的异常。所以
我必须拨打一次,等待几秒钟然后再打电话给它。如果我在线调试时使用断点.InvokeMethod一切都很好,即使是第一次。

Everything works perfect, but... When I reboot the target machine, the invoking the method throws an exception. When I invoke it again after few seconds, everything is OK again, but when i Invoke it right after first attempt there is still same exception. So I have to call it once, wait few secs and call it again. If I put breakpoint when debugging online with.InvokeMethod everything is Ok too, even the first time.


我将非常感谢任何建议,谢谢。

I will be really grateful for any advice, thank you.


有代码示例:

There is the code example:


//Method where I'm calling the method invoker
    private static bool? GetPendingReboot(...)
    {
         //Some other code

         string ccmServiceName = "CcmExec";

         //Just checking and starting service...
         if (RemoteTasks.CheckServiceExists(ccmServiceName, remoteMachine.Name) && 
             RemoteTasks.StartService(ccmServiceName, timeOutServices, remoteMachine.Name))
         {
               Dictionary<string, string> ccmsResult = 
                 RemoteTasks.CallMethodWMI(
                   new ManagementScope(
                       string.Format("\\\\{0}\\root\\ccm\\ClientSDK", remoteMachine.Name)),
                   "DetermineIfRebootPending", 
                   "CCM_ClientUtilities"
                 );

               if (bool.Parse(ccmsResult["IsHardRebootPending"]) ||
                   bool.Parse(ccmsResult["RebootPending"]))
               {
                    return true;
               }
         }
    }

    //WMI method Invoker
    public static Dictionary<string, string> CallMethodWMI(ManagementScope wmiScope, string methodName, string className, Dictionary<string, string> inputParams = null)
    {
        Dictionary<string, string> result = new Dictionary<string, string>();

        using (ManagementClass managementClass = new ManagementClass(wmiScope.Path.Path, className, null))
        {
            using (ManagementBaseObject inParams = (inputParams != null) ? managementClass.GetMethodParameters(methodName) : null)
            {

                if (inputParams != null)
                {
                    foreach (KeyValuePair<string, string> param in inputParams)
                    {
                        inParams[param.Key] = param.Value;
                    }
                }

                //This .InvokeMethod throws the exception, but like a I said, only after machine restart and only for first time call
                using (ManagementBaseObject outParams = managementClass.InvokeMethod(methodName, inParams, null))
                {
                    foreach (PropertyData data in outParams.Properties)
                    {
                        result.Add(data.Name, data.Value.ToString());
                    }
                }
            }
        }

        return result;
    }





例外是:


The exception is:


消息:""

Type :UnauthorizedAccessException

HResult : - 2147024891

StackTrace

Message: ""
Type: UnauthorizedAccessException
HResult: -2147024891
StackTrace:

System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode,IntPtr errorInfo)中的

in System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo)

System.Management.ManagementObject.InvokeMethod中的
(String methodName,ManagementBaseObject inParameters,InvokeMethodOptions选项)

in System.Management.ManagementObject.InvokeMethod(String methodName, ManagementBaseObject inParameters, InvokeMethodOptions options)


in L_Tool_2._0.RemoteMachineClasses.RemoteTasks.CallMethodWMI(ManagementScope wmiScope,String methodName,String className,Dictionary`2 inputParams)v C:... \ source. \\ _repost \ _L_Tool 2.0 \L_Tool 2.0 \RemoteMachineClasses \RemoteTasks.cs:第176行

in L_Tool_2._0.RemoteMachineClasses.RemoteTasks.CallMethodWMI(ManagementScope wmiScope, String methodName, String className, Dictionary`2 inputParams) v C:...\source\repos\L_Tool 2.0\L_Tool 2.0\RemoteMachineClasses\RemoteTasks.cs:line 176


in L_Tool_2._0.RemoteMachineClasses.Relation.GetPendingReboot(Machine remoteMachine,Boolean checkWMICCM)v C:... \\\ source \repos\L_Tool 2.0 \L_Tool 2.0 \RemoteMachineClasses \ Relation.cs:第645行

in L_Tool_2._0.RemoteMachineClasses.Relation.GetPendingReboot(Machine remoteMachine, Boolean checkWMICCM) v C:...\source\repos\L_Tool 2.0\L_Tool 2.0\RemoteMachineClasses\Relation.cs:line 645


推荐答案

一些理论。

1 )当你调用它时,远程服务器没有准备就绪,因此它没有通过调用。

1) The remote server isn't ready when you call it so it fails the call.

2)由于性能原因,你(或你所依赖的代码)正在缓存远程连接对象当目标机器离开时,连接对象不知道。当你再次尝试使用它时,连接对象被使用但由于
远程连接消失而失败。你得到一个异常并且连接被删除再次尝试建立一个新连接。

2) You (or code you're relying on) is caching the remote connection object for performance reasons. When the target machine goes away the connection object doesn't know that. When you try to use it again the connection object is used but fails because the remote connection was gone. You get an exception and the connection is dropped. Trying again establishes a new connection.

这也是ADO.NET连接对象的常见问题,因为它们也是这样做的。

This is a very common problem with ADO.NET connection objects as they do this as well.


这篇关于ManagementClass.InvokeMethod在重新启动目标计算机后抛出异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆