Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» Программирование "удобняшек" на VBScript (Часть 2)

Автор: fff222fffy1
Дата сообщения: 24.04.2016 20:37
Спасибо, если бы ещё подумал, то и надобность в вопросе отпала бы.
Но может ещё кому полезно будет.
Автор: kalyan57
Дата сообщения: 06.05.2016 13:07
Доброго времени суток

Кто сталкивался и знает однозначно: есть ли возможность использования составных условий IF в VBS?

Например

If (a=b) AND (b<>0) then
...
else
...
end if

При запуске в процессе интерпретации вылетает ошибка

Сценарий: my.vbs
Строка: 123
Символ: 34 (сразу за первым условием, будто ожидает then и никак не ожидает логического оператора AND)
Ошибка: Синтаксическая ошибка
Код:800A03EA
Источник: Ошибка компиляции Microsoft VBScript
Автор: Tilks
Дата сообщения: 06.05.2016 13:14
kalyan57
тырнет грит
If ((a=b) AND (b<>0)) then
Автор: fff222fffy1
Дата сообщения: 06.05.2016 13:25
Рабочие варианты, которые я скопировал из своих кодов:

Код:
If Not (NewWidth="" And NewHeight="") Then
...
If Win.NewWidth.Value & Win.NewHeight.Value="" Or IsNumeric(Win.NewWidth.Value & Win.NewHeight.Value) Or (IsNumeric(Win.NewWidth.Value) And IsNumeric(Win.NewHeight.Value)) Then
...
If CInt2(Komplekts(i))>=CInt2(KomplArray(j)) And CInt2(Komplekts(i))<=CInt2(KomplArray(j+1)) Then
...
if tmpDate>=tmpFrom And tmpDate<DateAdd("d",1,tmpTo) then
...
If Left(Stroka(1),1)="\" And Left(Stroka(1),2)<>"\\" Then
Автор: kalyan57
Дата сообщения: 06.05.2016 13:58
Tilks
fff222fffy1
Спасибо за ответы. Внешние скобки не обязательны.
Прост, как оказалось, все условие должно быть записано в одну строку

так
If a=b and
c<>1 then
....
end if
не работает

хорррошо, учтем-с
Автор: fff222fffy1
Дата сообщения: 06.05.2016 14:03
Можно так:

Код: If a>b And _
            c>b Then
Автор: kalyan57
Дата сообщения: 06.05.2016 14:10
Символ нижнего подчеркивания говорит интерпретатору дочитать со следующей строки?
Автор: fff222fffy1
Дата сообщения: 06.05.2016 14:13
Да, это перенос строки.
Автор: fff222fffy1
Дата сообщения: 14.05.2016 13:23
Подскажите пожалуйста по классам.

Код:     Class SimpleClass
        Public Num
        Private Sub Class_Initialize
            Num=0
        End Sub
        
    End Class

        Dim c1,c2,Str
        Set c1=New SimpleClass
'В этот момент c1.Num=0
        Set c2=c1
'c2.Num=0
        c2.Num=2
'а теперь и c2.Num=2, и c1.Num=2, то есть конструкция Set c2=c1 создаёт ещё одну ссылку на тот же объект
Автор: fff222fffy1
Дата сообщения: 19.05.2016 23:41
Создал в классе свойство IsEmpty, которое пересекается именем с функцией vbs IsEmpty.
Теперь внутри класса при использовании IsEmpty автоматически предполагается обращение к свойству класса, а не к функции.
Понятно конечно, что свойство надо переименовывать, но для общего развития:
Можно ли в подобном случае каким-то образом явно обратиться к функции vbs?
Автор: fff222fffy1
Дата сообщения: 20.05.2016 13:44
Из серии "случайно обнаружил":
если при активном окне от MsgBox или сообщения об ошибке нажать Ctrl C, то в буфер обмена попадает всё его содержимое.
Автор: Tilks
Дата сообщения: 21.05.2016 18:02
fff222fffy1
это надо постить в wind0ws, скрипты не причём, такие возможности MessageBox есть по всей системе, и давно уже.
Автор: fff222fffy1
Дата сообщения: 21.05.2016 18:41
Спасибо, буду знать, просто поделился случайно обнаруженным.
Меня собственно больше интересуют ответы на мои предыдущие вопросы, а это так, мимоходом. Если все и так знают, то можно и удалить.
Автор: Tilks
Дата сообщения: 21.05.2016 20:31
fff222fffy1

Цитата:
Если все и так знают, то можно и удалить.

не все, конечно, знают, но тут не удаляют, если сильно хочется, можно самому пост поправить, но не удалить.

Цитата:
больше интересуют ответы на мои предыдущие вопросы

тогда надо ждать какого то программиста, который программирует на VBScript.
по моему, большинство использует VBScript, чтобы облегчить себе жизнь, написав пару строчек кода.
ваши же вопросы затрагивает классы, использование которых оправдано в каком нибудь большом проекте, а здесь, на форуме, даже процедурный код не часто, где уж нам до классов. И название темы тоже, как бы, намекает словом - "удобняшек".

VBScript мне нужен только в расширениях других программ, например - Directory Opus, EmEditor , хотя в них есть поддержка и JavaScript , и если писать с нуля, то я предпочитаю его.
Автор: AlessTO
Дата сообщения: 24.05.2016 12:02
Всем привет,
есть такой скрипт:
[more=скрипт]
Цитата:
'Ежедневное разностное резервное копирование данных при помощи 7-Zip и VBScript (28.08.2009)
'http://zheleznov.info/backup_diff.htm

'== НАСТРОЙКИ

'что копировать?
'Const SRC = """C:\Users\*""" 'каталог и маска для резервирования
'Const SRC = """%AppData%\Opera\Opera\*""" 'здесь допускаются переменные окружения
Const SRC = "@C:\files.txt" 'взять список каталогов из текстового файла

'куда копировать?
Const PREFIX = "backup" 'префикс имени архива, условное название архивируемого ресурса
Const EXT = ".7z" 'расширение архивного файла
Const HISTORY = 4 'количество полных архивов в истории

'чем упаковывать?
Function ReadAllTextFile
Const ForReading = 1, ForWriting = 2
Dim fso, f
Set fso = CreateObject("Scripting.FileSystemObject")
Set f = fso.OpenTextFile("C:\run", ForReading)
ReadAllTextFile = f.ReadAll
End Function
Const PROGRAM = """%ProgramFiles%\7-Zip\7z.exe""" 'если 7-Zip установлен
'Const PROGRAM = "7z.exe" 'если архиватор лежит рядом со скриптом
Const OPTIONS = "-mhe -spf -slp -r -mx5 -x@C:\exclude.txt -v2000m" 'опции архиватора

'где отмечать?
Const REPORT = "report.txt" 'файл журнала

'не завершать скрипт аварийно
On Error Resume Next

'== ОБЩИЕ ОПРЕДЕЛЕНИЯ

'записать сообщение в журнал
Sub Log(msg)
    Const APPEND = 8 'добавить в конец файла
    Dim fso, f
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set f = fso.OpenTextFile(REPORT, APPEND, True)
    f.WriteLine Now & " " & msg
    f.Close
End Sub

'объект для работы с файлами
Dim fso
Set fso = WScript.CreateObject("Scripting.FileSystemObject")

Dim full 'имя последнего полного архива

'== СОЗДАНИЕ АРХИВА

'выбрать способ архивации
Dim arg, cmd
cmd = "" 'команда архиватора
Set arg = WScript.Arguments
If arg.Count > 0 Then
    If arg.Item(0) = "diff" Then
        cmd = "u"
    ElseIf arg.Item(0) = "full" Then
        cmd = "a"
    Else
        cmd = ""
    End If
End If

'полный архив
If cmd = "a" Then
    'имя нового архива
    full = PREFIX & "-" & FormatDateTime(Date, vbShortDate) & "-full" & EXT
    'если сегодня архив уже делали - не продолжать
    If (fso.FileExists(full)) Then
        Log full & ": создан РАНЕЕ и не будет перезаписан"
        WScript.Quit
    End If
    'опции командной строки
    opt = OPTIONS

'разностный архив
ElseIf cmd = "u" Then
    'найти полный архив
    Dim dir, fc, f, last
    Set dir = fso.GetFolder(".") 'рабочий каталог
    Set fc = dir.Files 'коллекция файлов
    full = ""
    last = 0 'дата последнего полного архива
    For Each f In fc
        If Left(f.name, Len(PREFIX & "-")) = PREFIX & "-" _
        And Right(f.name, Len("-full" & EXT)) = "-full" & EXT _
        And f.DateLastModified > last Then
            full = f.name
            last = f.DateLastModified
        End If
    Next
    'без полного архива не продолжать
    If Len(full) = 0 Then
        Log "ОШИБКА! Полный архив НЕ НАЙДЕН, разностный архив не может быть создан"
        WScript.Quit
    End If
    'имя нового архива
    diff = Left(full, Len(full) - Len("full" & EXT)) & FormatDateTime(Date, vbShortDate) & EXT
    'если сегодня архив уже делали - не продолжать
    If (fso.FileExists(diff)) Then
        Log diff & ": создан РАНЕЕ и не будет перезаписан"
        WScript.Quit
    End If
    'опции командной строки
    opt = OPTIONS & " -u- -up0q3x2z0!" & diff

'справка
Else
    WScript.Echo "Ежедневное разностное резервное копирование:" & vbCrLf _
    & SRC & vbCrLf _
    & vbCrLf _
    & "Отчет в файле:" & vbCrLf _
    & REPORT & vbCrLf _
    & vbCrLf _
    & "Опции командной строки:" & vbCrLf _
    & "full - создание полного архива" & vbCrLf _
    & "diff - создание разностного архива"
    WScript.Quit
End If

'если нет файла со списком исключений exclude.txt - создать
'файл указан в опциях архиватора и поэтому должен существовать, хотя бы пустой
If Not fso.FileExists("C:\exclude.txt") Then
    Dim tf
    Set tf = fso.CreateTextFile("C:\exclude.txt")
    tf.Close
End If

'создать архив
Dim sho, ret
Set sho = WScript.CreateObject("WSCript.Shell")
ret = sho.Run(PROGRAM & " " & cmd & " " & full & " " & "-p" & ReadAllTextFile & " " & opt & " " & SRC, 7, True) '7 = в свернутом виде

'результат
Dim msg
Select Case ret
Case 0
    msg = "Ok"
Case 1
    msg = "Некоторые файлы были ЗАНЯТЫ и поэтому не добавлены в архив"
Case 2
    msg = "ОШИБКА при создании архива"
Case 7
    msg = "ОШИБКА в командной строке"
Case 8
    msg = "ОШИБКА - недостаточно памяти"
Case 255
    msg = "ОШИБКА - создание архива было ПРЕРВАНО пользователем"
Case Else
    msg = "ОШИБКА при создании архива, код " & ret
End Select
If cmd = "a" Then
    Log full & ": " & msg
Else
    Log diff & ": " & msg
End If

'== УДАЛЕНИЕ УСТАРЕВШИХ АРХИВОВ

'составить массивы имен и дат имеющихся ПОЛНЫХ архивов
'дата берется из файловой системы, а не из имени файла :(
Dim i, names(), dates()
ReDim names(0)
ReDim dates(0)
Set dir = fso.GetFolder(".") 'рабочий каталог
Set fc = dir.Files 'коллекция файлов
i = 0
For Each f in fc
    If Left(f.name, Len(PREFIX & "-")) = PREFIX & "-" _
    And Right(f.name, Len("-full" & EXT)) = "-full" & EXT Then
        ReDim Preserve names(i + 1)
        ReDim Preserve dates(i + 1)
        names(i) = f.name
        dates(i) = f.DateLastModified
        i = i + 1
    End If
Next

'отобрать последние ПОЛНЫЕ архивы
Dim j, dmax, imax
For j = 1 To HISTORY
    dmax = 0
    For i = 0 To UBound(dates)
        If dates(i) > dmax Then
            dmax = dates(i)
            imax = i
        End If
    Next
    dates(imax) = 0
    names(imax) = ""
Next

'удалить устаревшие ПОЛНЫЕ архивы и соответствующие разностные
Dim pref
For i = 0 To UBound(names)
    If Len(names(i)) > 0 Then
        Log names(i) & ": устарел, должен быть УДАЛЕН"
        fso.DeleteFile names(i), False 'файлы с атрибутом ReadOnly не удаляются!
        'соответствующие разностные
        pref = Left(names(i), Len(names(i)) - Len("full" & EXT))
        For Each f in fc
            If Left(f.name, Len(pref)) = pref _
            And Right(f.name, Len(EXT)) = EXT Then
                Log f.name & ": устарел, должен быть УДАЛЕН"
                fso.DeleteFile f.name, False 'файлы с атрибутом ReadOnly не удаляются!
            End If
        Next
    End If
Next
[/more]
Пока не добавил ключ разделения на тома - все работало замечательно. Теперь при создании дифференциальных архивов в логе - ошибка создания тома. Я понимаю что это связано с константой EXT, но как победить проблему не ведаю - вразумите пожалуйста. Архиватор при разбитии на тома - использует нумерацию в качестве расширения - 001, 002 и т.д.
Автор: Dacor
Дата сообщения: 27.05.2016 00:31
Подскажите кому не сложно, как переделать скрипт чтобы он принимал аргументы из файла, а не из командной строки.

Скрипт вызывается из bat файла который ему передает список аргументов


Код:
start "title" /b /wait cscript.exe "%~dp0HideWindowsUpdates.vbs" 971033 2902907
Автор: Tilks
Дата сообщения: 27.05.2016 13:34
Dacor
пробуй, у меня не работает обновление, потому проверить не могу, но если раскомментировать 3 строчки после ' for testing , то выводит содержимое файла построчно.
в подаваемом файле каждая строчка один аргумент, без пробелов, в конце и в начале.
[more=код]
Код:
'// Inspired by Opmet and Colin Bowern: _http://serverfault.com/a/341318
If Wscript.Arguments.Count < 1 Then
WScript.Echo "Syntax: HideWindowsUpdates.vbs [Hotfix Article ID]" & vbCRLF & _
" - Examples: HideWindowsUpdates.vbs 2990214" & vbCRLF & _
" - Examples: HideWindowsUpdates.vbs 3022345 3035583"
WScript.Quit 1
End If

Set FSO = CreateObject("Scripting.FileSystemObject")
Dim CurrentDirectory
CurrentDirectory = fso.GetAbsolutePathName(".")
Set File = FSO.GetFile(CurrentDirectory &"\"& WScript.Arguments(0))
WScript.Echo CurrentDirectory &"\"& WScript.Arguments(0)
Set TextStream = File.OpenAsTextStream(1)
'WScript.Echo TextStream.ReadAll()

Dim objArgs
'Set objArgs = Wscript.Arguments
Set objArgs = CreateObject("System.Collections.ArrayList")

While Not TextStream.AtEndOfStream
objArgs.Add TextStream.ReadLine()
Wend
TextStream.Close

' for testing
'For Each hotfixId in objArgs
'    WScript.Echo hotfixId
'Next

Dim updateSession, updateSearcher
Set updateSession = CreateObject("Microsoft.Update.Session")
Set updateSearcher = updateSession.CreateUpdateSearcher()

Wscript.Stdout.Write "Searching for pending updates..."
Dim searchResult
Set searchResult = updateSearcher.Search("IsInstalled=0")

Dim update, kbArticleId, index, index2
WScript.Echo CStr(searchResult.Updates.Count) & " found."
For index = 0 To searchResult.Updates.Count - 1
Set update = searchResult.Updates.Item(index)
For index2 = 0 To update.KBArticleIDs.Count - 1
kbArticleId = update.KBArticleIDs(index2)

For Each hotfixId in objArgs
If kbArticleId = hotfixId Then
If update.IsHidden = False Then
WScript.Echo "Hiding update: " & update.Title
update.IsHidden = True
Else
WScript.Echo "Already hidden: " & update.Title
End If
End If
Next

Next
Next
'// EOF
Автор: Dacor
Дата сообщения: 28.05.2016 01:15
Tilks
Попробовал. Что то не получилось(
Выводит на экран:
C:\>start "title" /b /wait cscript.exe "C:\HideWindowsUpdates.vbs" kb.txt
"C:\HideWindowsUpdates.vbs" kb.txt
Сервер сценариев Windows (Microsoft R) версия 5.8
Copyright (C) Корпорация Майкрософт 1996-2006, все права защищены.
C:\kb.txt
яю3
Searching for pending updates...260 found.

и всё..

Если раскоментить "для теста" то выводит странную строку "яю3", количество символов вне зависимости сколько апдейтов прописано. Потом ищет, находит 260 штук, но ничего не прячет.
Еще это нормально что он потребовал framework3.5? Тому варианту было не нужно.
И файл он берет только если запускать из командной строки из каталога. Если просто тыкнуть в батник, пишет что файл не найден. Но это я разобрался, запускал из строки. Фреймворк поставил. Но не сработало(
Если важно, концы строк в kb.txt - CR LF. Номера обновлений в столбик, пробелов нет.
Автор: Tilks
Дата сообщения: 28.05.2016 01:36
Dacor
никакие фреймворки не нужны

Цитата:
странную строку "яю3"

может у вас кодировка файла юникод с меткой, и метку странную и выводит.
проверил, да наверно юникодная метка мешает, надо сохранять в кодировке без метки.

Цитата:
И файл он берет только если запускать из командной строки из каталога. Если просто тыкнуть в батник, пишет что файл не найден.

я запускал без батника, просто в ком строке> HideWindowsUpdates.vbs test.txt

создал ваш батник, у меня всё пишет в консоль.
создал свой , тогда нормально. текст в батнике:
HideWindowsUpdates.vbs test.txt

Добавлено:
если kb.txt должен быть в юникоде, то надо добавить параметр, чтобы скрипт знал что мы передаём юникод.
Set File = FSO.GetFile(CurrentDirectory &"\"& WScript.Arguments(0))
Set TextStream = File.OpenAsTextStream(1, -1)
http://www.script-coding.com/WSH/FileSystemObject.html#5.3.4.

или поменять те две строчки на одну такую
Set TextStream = FSO.OpenTextFile(CurrentDirectory &"\"& WScript.Arguments(0), 1, False, -1)
последний параметр (-1) это юникод кодировка.
-2 - Открыть файл в формате, используемом системой по умолчанию.
-1 - Открыть файл в формате Unicode.
0 - Открыть файл в формате ASCII (по умолчанию).
больше параметров здесь:
http://www.script-coding.com/WSH/FileSystemObject.html#3.24.
Автор: Lord0fLight
Дата сообщения: 28.05.2016 13:03
Есть стандартный код опубликованный на https://msdn.microsoft.com/ru-ru/library/windows/desktop/aa393907%28v=vs.85%29.aspx

Он позволяет отследить запуск нового процесса и потом убить его:

Код: strComputer = "."
Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colMonitoredProcesses = objWMIService.ExecNotificationQuery("SELECT * FROM __InstanceCreationEvent " _
& " WITHIN 1 WHERE TargetInstance ISA 'Win32_Process'")
i = 0
Do While i = 0
Set objLatestProcess = colMonitoredProcesses.NextEvent
If objLatestProcess.TargetInstance.Name = "Download.exe" Then
objLatestProcess.TargetInstance.Terminate()
End If
Loop
Автор: Alexzzy
Дата сообщения: 28.05.2016 18:11
Lord0fLight
"excel.exe" <> "EXCEL.EXE"
Автор: Lord0fLight
Дата сообщения: 29.05.2016 00:07
Alexzzy
Спасибо!

Есть ли способ обратиться к книге, которая создана вновь появившимся процессом excel?
Автор: Dacor
Дата сообщения: 29.05.2016 00:28
Tilks
Благодарю за помощь! Спасибо огромное! Заработало с юникодом. Моя ошибка, текстовик был в неведомом формате, первый раз такое увидел. Аргумент -1 не сработал, юникод видится как китайские иероглифы, но мануал читал, почему так - непонятно. Вариант "поменять те две строчки на одну такую" не пробовал, потому что между ними еще одна, и в какой последовательности они должны идти я не знаю.
Если запускать строкой HideWindowsUpdates.vbs test.txt то вылазит ошибка, необходимо вначале запустить cscript //H:Cscript.


Цитата:
никакие фреймворки не нужны

На 7ке и правда не нужны, а на 8ке предлагает скачать и если отказаться то не работает. Засада(

И по поводу "И файл он берет только если запускать из командной строки из каталога. Если просто тыкнуть в батник, пишет что файл не найден. " Это я имел ввиду что обычно же запускаешь просто батник из каталога. И в этом случае текстовый файл с апдейтами не находится. Если из командной строки пробраться в каталог, то конечно всё работает.

А можно ли так сделать чтобы в текстовом файле с номерами, кроме номеров еще и были описания этих апдейтов, например через точкузпт? Или это великие сложности?
Автор: Tilks
Дата сообщения: 29.05.2016 14:02
Dacor
я так понимаю, что для работы с обновлениями нужны права админа, т.е надо запускать батник пкм > от админа.
но в таком случае текущая папка становится c:\wind0ws\system32 и файла test.txt или kb.txt в той папке нет.
если так, то надо в батнике писать полный путь до kb.txt , а в самом скрипте убирать мои добавки вычисляющие текущую папку
CurrentDirectory = fso.GetAbsolutePathName(".")
или если такой kb.txt только один, то просто его и записать в скрипт, и не надо будет его передавать параметром.
вообщем много вопросов, чтобы понять как лучше использовать этот скрипт.


Цитата:
А можно ли так сделать чтобы в текстовом файле с номерами, кроме номеров еще и были описания этих апдейтов, например через точкузпт?


Код: While Not TextStream.AtEndOfStream
objArgs.Add TextStream.ReadLine()
Wend
TextStream.Close
Автор: Dacor
Дата сообщения: 29.05.2016 20:11

Цитата:
или если такой kb.txt только один, то просто его и записать в скрипт, и не надо будет его передавать параметром. вообщем много вопросов, чтобы понять как лучше использовать этот скрипт.

Ваша правда, ведь запуская батник по ПКМ ему нельзя прописать в качестве аргумента тхт файл, и поэтому его надо жестко прописать внутри. Идея была вытащить все номера артиклей в отдельный файл и использовать дважды, для удаления и сокрытия. И в этом случае внешний файл будет один, просто в него что то будет добавляться/убираться.


Цитата:
будет проверка на первый символ в строке ; или пустая строка (перевод каретки, без пробелов) то есть комментарий будет, если в начале строки будет ;

Фантастика, просто супер! Не перестаю благодарить!

По поводу требования установки Фреймворка на 8.1 при запуске скрипта, нашел статью по этому вопросу. Возможно будет интересно ознакомиться, вот она
https://blogs.msdn.microsoft.com/dsvc/2013/03/04/usage-of-net-collections-types-in-vbscript-is-not-supported-after-net-4-5/
вкратце - это из за использования ArrayList в модификации, и надо ставить Фреймворк, и это как верно подметил комментатор "This seems pretty crazy to me!"
Автор: Numufar
Дата сообщения: 01.06.2016 15:02
[more] Доброго времени суток.
Есть куча удалённых компов, к которым постоянно приходится коннектиться по RAdmin. На всех машинах логин и пароль одинаковые. Для того, чтобы постоянно не вводить одни и те же логин и пароль, написал скрипт:

Код:

Код: set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Exec ("""C:\Program Files (x86)\Radmin Viewer 3\Radmin.exe"" /connect:192.168.1.100:4899" )
WScript.Sleep 4000
WshShell.SendKeys "admin"
WshShell.SendKeys "{TAB}"
WshShell.SendKeys "admin"
WshShell.SendKeys "{ENTER}"

Страницы: 12345678910111213141516171819202122232425

Предыдущая тема: Помогите новичку в C++


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.