2016-11-25 8 views
0

Я создал альтернативную утилиту поиска в утилите поиска Windows с помощью VBScript, используя поиск по WQL, но, как оказалось, это довольно медленно. Я бы хотел ускорить его, и я думаю, что смогу это сделать, но мне нужно будет разместить фильтр поиска ПОСЛЕ моего поиска по WQL и до моего For Each. Возможно ли это?После поиска WMI в VBScript, могу ли я создать свой фильтр поиска перед моим заявлением «Для каждого»?

Я уже тестировал фильтрацию в WQL-поиске, но это примерно на 40% быстрее, если я фильтрую после поиска WQL. Я также тестировал с и без iFlags, но они, как правило, замедляют поиск совсем немного, хотя MS, похоже, верит иначе.

Поскольку пользователь может искать по имени файла, дате создания, дате последнего изменения и/или размеру файла, если фильтр после инструкции For Each, тогда скрипт должен создавать фильтр поиска каждый раз, когда он перечисляет файл. Я хотел бы создать фильтр один раз в надежде на бритье некоторое время от поиска.

Это, вероятно, имеет смысл, если взглянуть на фрагмент кода, который я опубликовал. Обратите внимание, что к югу от subCreateSearchString будет звонить на другие параметры поиска и функции (например: конвертирование из UTC в местное время, размеры файлов формата и т.д.)

Dim strSearchName, strComputer, objSWbemServices, objFile, colFiles 
Dim strFileName, strReturnedFileName, strQueryDriveAndPath 

strSearchName = "test" 'Text being searched for - change as needed 
strQueryDriveAndPath = "PATH = '\\Drop_RW\\' AND DRIVE = 'D:'" 'Path and drive in which to search - change as needed 

strComputer = "." 
Set objSWbemServices = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") 
Set colFiles = objSWbemServices.ExecQuery("Select * from CIM_DataFile WHERE " & "" & strQueryDriveAndPath & "") 

'* I'd like to place the call to "subCreateSearchString" here 

On Error Resume Next 

For Each objFile in colFiles 
    strReturnedFileName = objFile.Name 
    subCreateSearchString ' Search filter - it works when placed here 
    If strSearchForString Then 
     MsgBox "File matches:" & vbCrLf & strReturnedFileName 
    Else 
     MsgBox "File DOES NOT match" & vbCrLf & strReturnedFileName 
    End If 
Next 

Sub subCreateSearchString 
    '* Set Filename Variable for search: 
    strFileName = InStr(LCase(strReturnedFileName), LCase(strSearchName)) 
    strSearchForString = strFileName 
End Sub 

ответ

1

Поскольку вы зависите от имен файлов, которые вы будете итерация в петле For Each: нет, невозможно.

Я бы настоятельно рекомендовал внести некоторые изменения.

  • Используйте Function, а не Sub, если вы хотите, чтобы вернуть что-то из подпрограммы.
  • Избегайте использования глобальных переменных. У них есть неприятная тенденция вводить нежелательные побочные эффекты, а также сделать отладку вашего кода болью в тылу. Передавайте значения в свои подпрограммы через параметры и возвращайте значения как фактические возвращаемые значения.
  • Возвращаемое значение представляет собой целое число (или Null), но вы используете его как логическое и назвали ваши переменные (и под), как если бы это была строка. Не делай этого. Назовите свои функции/процедуры после того, что они делают, и назовите свои переменные после того, что они содержат. И если вы хотите использовать логическое значение, ваша функция фактически возвращает логическое значение.
  • Избегать использования Hungarian Notation. Это бессмысленное разрастание кода, как это делают большинство людей. Даже если ваше именование не совпадает даже с фактическим типом.
  • Не использовать глобальные On Error Resume Next. Когда-либо. Это просто заставляет ваш код терпеть неудачу, не сообщая вам ничего о том, что на самом деле пошло не так. Держите обработку ошибок как можно более локальными. Включите его только для одиночных команд или коротких кодовых блоков и только в том случае, если нет другого способа избежать/обрабатывать ошибку.
Function IsInFilename(searchName, fileName) 
    IsInFilename = InStr(LCase(fileName), LCase(searchName)) > 0 
End Function 

For Each objFile in colFiles 
    If IsInFilename(strSearchName, objFile.Name) Then 
     MsgBox "..." 
    Else 
     MsgBox "..." 
    End If 
Next 
+0

Wow - вы удивительное богатство знаний! Большое спасибо за все советы. У меня теперь есть очень много кода для пересмотра. – user7207540

+0

Как вы можете (скорее всего) сказать, я немного более продвинутый, чем новичок, пытающийся использовать передовые методы ... вот как я узнаю. Что касается моего вопроса, есть ли способ изменить мой код, чтобы он не создавал строку поиска для каждого файла, который он итерирует? Пожалуйста, обратите внимание, что я не прошу вас (или кого-либо еще) написать код для меня, просто указать мне направление, в котором я могу учиться? Еще раз спасибо! – user7207540

+0

Вы не можете проверить, содержит ли имя файла строку без проверки, содержит ли имя файла строку.Чтобы ускорить работу вашего скрипта, вам, вероятно, нужно сделать свой запрос WMI более конкретным, чтобы он получал меньше результатов. –