Разделение строки на ошибки массива

Попытка написать сценарий, который будет запускаться в WinPE, по сути, получает IP-адрес локального хоста и выбирает действие на основе диапазона IP-адресов.

В Windows скрипт работает без нареканий. Однако в WinPE я получаю следующую ошибку:

script.vbs(1,1) Ошибка выполнения Microsoft VBScript: нижний индекс вне допустимого диапазона

Google-fu говорит мне, что это как-то связано с тем, что мой массив находится за пределами диапазона. Здесь я думал, что у меня есть приличное понимание, но, видимо, нет.

Код, который работает как есть в Windows:

Option Explicit

Dim sIP, sHostname,sPingBat
Dim aIP
Dim iOct1, iOct2, iOct3, iOct4, iReturn
Dim oWMIService, oCmd, oAdapter
Dim cAdapters

iReturn = 999
sHostname = "."
Set oWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & sHostname & "\root\cimv2")
Set cAdapters = oWMIService.ExecQuery("Select IPAddress from Win32_NetworkAdapterConfiguration Where IPEnabled = True")
Set oCmd = CreateObject("Wscript.Shell")

For Each oAdapter in cAdapters
    If Not IsNull(oAdapter.IPAddress) Then 
        sIP = Trim(oAdapter.IPAddress(0))
    Else
        iReturn = 404
        WScript.Quit iReturn
    End If
Next

sIP = CStr(sIP)

aIP = Split(sIP, ".")

iOct1 = CInt(aIP(0))
iOct2 = CInt(aIP(1))
iOct3 = CInt(aIP(2))
iOct4 = CInt(aIP(3))

Теперь, если я изменю объявление массива aIP на одно из следующих:

aIP()
aIP(4)

и беги

aIP = Split(sIP, ".")

я получил

script.vbs(26, 1) Ошибка выполнения Microsoft VBScript: несоответствие типов

Изменение назначения массива / линии разделения на

aIP() = Split(sIP,".")

приводит к

script.vbs(26, 1) Ошибка выполнения Microsoft VBScript: нижний индекс вне допустимого диапазона

Значит, я явно что-то делаю не так.

Также вполне возможно, что мое исходное сообщение об ошибке совершенно не связано с моим диапазоном массивов, а WinPE просто не нравится мой сценарий (в этом случае, если у кого-то есть какие-либо указатели, это будет оценено)

На данный момент я монтирую свой wim, чтобы получить установочные пакеты, чтобы убедиться, что пакеты WMI и Scripting установлены из ADK.


person jparnell8839    schedule 27.04.2016    source источник
comment
Я не понимаю ваше первое сообщение об ошибке. Он говорит Массив вне индекса для Строка 1 Столбец 1, что не имеет смысла.   -  person    schedule 28.04.2016
comment
Я предполагаю, что он возвращает адрес IP6, который совсем не похож на адрес IP4, поэтому ожидаемое разделение не выполняется, потому что нет четырех ожидаемых октетов. Из документации - Массив всех IP-адресов, связанных с текущим сетевым адаптером. Это свойство может содержать либо адреса IPv6, либо адреса IPv4.   -  person user692942    schedule 28.04.2016
comment
IP-адрес с индексом 0 будет адресом IP6, который не содержит ., поэтому Split() просто вернет массив, содержащий полную строку. Простая отладка состоит в том, чтобы записать sIP и проверить значение. Один из подходов состоит в том, чтобы сначала проверить значение ., используя InStr().   -  person user692942    schedule 28.04.2016


Ответы (2)


В коде нет ничего плохого, кроме предположения о том, что возвращает Win32_NetworkAdapterConfiguration.

Из MSDN — класс Win32_NetworkAdapterConfiguration
Массив всех IP-адресов, связанных с текущим сетевым адаптером. Это свойство может содержать либо адреса IPv6, либо адреса IPv4. Дополнительные сведения см. в разделе IPv6 и IPv4. Поддержка в WMI.

Поскольку sIP может содержать адрес IPv6, Split() не будет работать должным образом. Адреса IPv6 не содержат . в качестве разделителя, поэтому Split() вернет массив, содержащий исходную строку только в качестве первого индекса. Следовательно, попытка прочитать что-либо, кроме aIP(0), вызовет

Ошибка выполнения Microsoft VBScript:
Нижний индекс вне допустимого диапазона

ошибка.

Чтобы избежать этого, используйте InStr(), чтобы сначала проверить наличие . в переменной sIP, вам также потребуется выполнить итерацию по массиву oAdapter.IPAddress, чтобы проверить каждый адрес, чтобы получить правильный, вы не можете предполагать, что IPAddress(0) всегда будет правильным. .

Попробуй это

Dim ips, ip

For Each oAdapter in cAdapters
    ips = oAdapter.IPAddress
    If IsArray(ips) Then
        For Each ip In ips
            If InStr(1, ip, ".") > 0 Then
                sIP = Trim(ip)
                Exit For
            End If
        Next
        If Len(sIP) > 0 Then Exit For
    Else
        iReturn = 404
        WScript.Quit iReturn
    End If
Next

Извините, не тестировалось на iPad

person user692942    schedule 28.04.2016

Я предполагаю, что переменная sIP содержит некоторую строку, которую нельзя разделить с помощью разделителя "." (например: «somestringwithNoDOT»)

Итак, в первом случае

aIP = Split(sIP,".")   ' Split("somestringwithNoDOT",".")

оператор вернул только 1 строку, которая не может быть преобразована в целое число. Итак, я вернул ошибку несоответствия типа в строке ниже

iOct1 = CInt(aIP(0))  ' returns Type mismatch error

Во втором случае

aIP() = Split(sIP,".")  ' Split("somestringwithNoDOT",".")

приведенный выше оператор вернет 1 элемент, но aIP равен array без элементов. Итак, это утверждение превратилось в "Subscript out of range" ошибку

Решение этой проблемы состоит в том, чтобы проверить, передается ли правильное значение в sIP.

person Kiran Maroju    schedule 27.04.2016