Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   [решено] TimeOut для удаленного соединения по WMI на C# (http://forum.oszone.net/showthread.php?t=121123)

Delirium 27-10-2008 04:58 934575

TimeOut для удаленного соединения по WMI на C#
 
Пишу небольшое приложение, использующее WMI для сбора данных с удаленных машин. Все работает, за исключением одного: В случае, если компьютер выключен/на нем нет WMI/другая причина недоступности, то соединение происходит очень долгое время.
Все попытки уменьшить таймаут для попытки соединения ни к чему не приводили. Вот как пытался:


Код:

ConnectionOptions connOptions = new ConnectionOptions();
            ObjectGetOptions getOptions = new ObjectGetOptions();
            getOptions.Timeout = new System.TimeSpan(0, 0, 2); //2 секунды
            //ManagementScope machineScope = new ManagementScope(machineWmiNamespace, connOptions);



            //scope.Options.Timeout = New TimeSpan(20000000) //другим способом 2 секунды

            scope = new ManagementScope(pcstr, connOptions);
            scope.Options.Timeout = new TimeSpan(0, 0, 0); // и даже 0 секунд
           
            scope.Connect();

Результат нулевой. Вот что вычитал путем гугливания:

Цитата:

Remote WMI queries are subject to the system-wide TCP/IP connection timeout settings. A two second timeout for the first attempt, 6 attempts, doubling the timeout each time. 2 + 4 + 8 + 16 + 32 + 64 = 126 seconds. You can try hacking the TCP registry settings, not sure if that's a good idea.
Такой вариант меня тоже не устраивает.
ПРобовал использовать PING, ответ получаю, проанализировать могу, но все равно очень долго. Есть ли какой нибудь способ указания таймаута при коннекте WMI на удаленную машину?

Delirium 28-10-2008 04:37 935635

Решил проблему, не в том направлении копал просто. Проще всего не через WMI, а, действительно через ping проверять доступность машины. Ниже приведен небольшой классик, который в течении 2-3 секунд дает ответ, есть пинг или нет. Если есть, результат мгновенно приходит. Если машина недоступна, то ответ приходит через пару секунд:
Код:

class QueryData
    {
        public bool HasPower(string who)
        {
            Ping pingSender = new Ping();
            PingOptions options = new PingOptions();

            // Use the default Ttl value which is 128,
            // but change the fragmentation behavior.
            options.DontFragment = true;

            // Create a buffer of 32 bytes of data to be transmitted.
            string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
            byte[] buffer = Encoding.ASCII.GetBytes(data);
            int timeout = 10;
            PingReply reply;
            try
            {
                reply = pingSender.Send(who, timeout, buffer, options);
                if (reply.Status == IPStatus.Success)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch
            {
                return false;
            }
        }
    }

При игре с параметром int timeout = 10; можно выставить время ожидания отклика. В случае слишком малого значения возможны ложные срабатывания на true, поэтому выставлено в 10 - практика показала, что в нормальной сети этого времени достаточно.

menpavel 08-06-2010 12:36 1429903

Если кого заинтересует ping средствами JScript:
Код:

function Ping(strHost)
        {
        var objPing, objRetStatus;
        var objPing = GetObject("winmgmts:");
        objRetStatus = new Enumerator(objPing.ExecQuery("select * from Win32_PingStatus where address = '" + strHost + "'"));
        return(objRetStatus.item().StatusCode);
        }

на MSDN можно более подробно рассмотреть Win32_PingStatus


Время: 22:03.

Время: 22:03.
© OSzone.net 2001-