1 (изменено: Игорь, 2009-04-28 09:20:48)

Тема: VBS: Ожидание подключения USB накопителей

Нужен скрипт который бы следил за подключением usb накопителей. и если подключен новый накопитель выдавал предупреждающие окно сообщения о наличие нового устройства. Большое спасибо...


Вот нашел где то на этом сайте скрипт

On Error Resume Next
Set FSO = CreateObject("Scripting.FileSystemObject")
colDrives = Split("D E F G H I J K L M N O P Q R S T U V W X Y Z")
Set dictDrives = CreateObject("Scripting.Dictionary")
For Each Drive In colDrives
    Set Drv = FSO.GetDrive(Drive & ":")
    If Err.Number Then
        dictDrives.Add Drive & ":", False
    Else
        If Drv.DriveType = 1 And Drv.IsReady Then
            dictDrives.Add Drive & ":", True
        Else
            dictDrives.Add Drive & ":", False
        End If
    End If
    Err.Clear
Next
' Бесконечный цикл
While True
    For Each Drive In dictDrives.Keys
        Set Drv = FSO.GetDrive(Drive)
        If (Err.Number) Or (Drv.IsReady = False) Or (Drv.DriveType <> 1) Then
            Flag = False
        Else
            Flag = True
        End If
        Err.Clear
        Current = dictDrives.Item(Drive)
        If Current <> Flag Then
            If Current = False And Flag = True Then
                Set FSO=CreateObject("Scripting.FileSystemObject") 
                FSO.CopyFile "C:\1.txt","???:\Копия 1.txt"            
            End If
            dictDrives.Item(Drive) = Flag
        End If
    Next
    WScript.Sleep 1000
Wend

1 Возник вопрос что надо ставить вместо ??? чтобы файл 1.txt копировался на подключенное устройство.? Вот ещё что: Если туда поставить одну из букв A-Z то при подключение флэшки файл скопируется на диск с буквой котороя была указанна вместо ???. например на диск D. а ведь задача копировать только на съемные устройства, а не на жесткие диски этого компьютера.

2 И если кто может и кому не лень : Дайте подробное описание вышеуказанному скрипту.

2

Re: VBS: Ожидание подключения USB накопителей

Игорь пишет:

Нужен скрипт который бы следил за подключением usb накопителей. и если подключен новый накопитель выдавал предупреждающие окно сообщения о наличие нового устройства.

Скрипт по ссылке именно эту задачу и решает.
1. http://www.script-coding.com/WSH/FileSy … .html#3.2.
2. Вначале скрипт составляет список из всех возможных букв дисков. Затем в бесконечном цикле по этому списку пытается получить диск по каждой букве. Если диск с такой буквой доступен и имеет тип съёмного накопителя, выдаётся сообщение, и так бесконечно.

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

3

Re: VBS: Ожидание подключения USB накопителей

The gray Cardinal, Спасибо за ссылку, но меня теперь заинтересовало все же как реализовать автоматическое капирование нужного файла на подключенное устроиство?

4

Re: VBS: Ожидание подключения USB накопителей

3.2. CopyFile

5

Re: VBS: Ожидание подключения USB накопителей

FSO.CopyFile "C:\1.txt","???:\Копия 1.txt"  - что тут надо подставить вместо ???. 

Если подставить допустим     FSO.CopyFile "C:\1.txt","d:\Копия 1.txt"      -  то при появление нового устройства файл скопируется на жесткий диск D, потому что мы его указали, а надо чтобы файл копировался на только что подключенное устройство у которого метка диска зарание не известная и только на внешнеие накопители. Вариант указать все буквы от A-Z не подходит.

6

Re: VBS: Ожидание подключения USB накопителей

Drive.

Вместо «???:».

Осталось только спросить, а зачем нужно что-то копировать в корень съёмного диска ?

7

Re: VBS: Ожидание подключения USB накопителей

alexii пишет:

Осталось только спросить, а зачем нужно что-то копировать в корень съёмного диска ?

Просто я нашел этот пример стало интересно.


alexii пишет:

Drive. вместо ???

не сработало.

8

Re: VBS: Ожидание подключения USB накопителей

Игорь пишет:

Просто я нашел этот пример стало интересно.

Мне тоже: Запреты, § 2.9..

Игорь пишет:

не сработало.

Значит, Вы что-то не так делаете. Покажите результирующий код, который у Вас «не сработало».

9

Re: VBS: Ожидание подключения USB накопителей

On Error Resume Next
Set FSO = CreateObject("Scripting.FileSystemObject")
colDrives = Split("D E F G H I J K L M N O P Q R S T U V W X Y Z")
Set dictDrives = CreateObject("Scripting.Dictionary")
For Each Drive In colDrives
    Set Drv = FSO.GetDrive(Drive & ":")
    If Err.Number Then
        dictDrives.Add Drive & ":", False
    Else
        If Drv.DriveType = 1 And Drv.IsReady Then
            dictDrives.Add Drive & ":", True
        Else
            dictDrives.Add Drive & ":", False
        End If
    End If
    Err.Clear
Next
' Бесконечный цикл
While True
    For Each Drive In dictDrives.Keys
        Set Drv = FSO.GetDrive(Drive)
        If (Err.Number) Or (Drv.IsReady = False) Or (Drv.DriveType <> 1) Then
            Flag = False
        Else
            Flag = True
        End If
        Err.Clear
        Current = dictDrives.Item(Drive)
        If Current <> Flag Then
            If Current = False And Flag = True Then
                Set FSO=CreateObject("Scripting.FileSystemObject") 
                FSO.CopyFile "C:\1.txt","Drive.\копия1.txt"            
            End If
            dictDrives.Item(Drive) = Flag
        End If
    Next
    WScript.Sleep 1000
Wend

10

Re: VBS: Ожидание подключения USB накопителей

У Вас ошибка. «Drive» — это вот этот объект:

For Each Drive In dictDrives.Keys
…

Игорь, всё же хотелось бы услышать конкретный ответ на конкретный вопрос: что именно и, главное, зачем нужно копировать в корень съёмного диска?

11

Re: VBS: Ожидание подключения USB накопителей

Именно в корень диска вовсе не обязательно, просто этот пример уже разбирался на вашем сайте и я решил ни чего не менять в нем.  А сам скрипт заинтересовал тем что его можно использовать для бекапа обновлений антивирусных баз. У меня два компьютера на одном из них стоит интернет через который я и обнавляю антиврирус AVG 8.5 и чтобы скопировать последние обновления на usb накопитель и установить их на другой ноутбук мне приходиться лезть глубоко в дирикторию "C:\Documents and Settings\All Users\Application Data\avg8\update\download" при этом открывая в свойствах показ скрытых и системных файлов.  Конечно есть вариант создать на рабочем столе ярлык на нужную дирикторию кинуть на видное место скрипт или твик открывающий показ скрытых и системных файлов, выделить все файлы и отправить их на usb накопитель чем я пока и пользуюсь. Но это все равно неудобно и не так эффектно. А с помощью скрипта это можно довести до автоматизма.

12

Re: VBS: Ожидание подключения USB накопителей

Мне кажется неудачным вариант такой автоматизации. Я предпочёл бы делать сие по ручному вызову скрипта, а не слежением.

Пробуйте так:
1) убрать второе создание объекта «FSO»;
2)

FSO.CopyFile "C:\1.txt", FSO.BuildPath(Drive, "копия1.txt")

13

Re: VBS: Ожидание подключения USB накопителей

alexii, большое спасибо все работает, с папкой (update) тоже все получилось. Жаль только индикатор оставшегося времени на копирование не появляется.

P.S "Лень - двигатель прогресса!"

14

Re: VBS: Ожидание подключения USB накопителей

Игорь пишет:

Жаль только индикатор оставшегося времени на копирование не появляется.

Посмотрите, как сие работает:

Option Explicit

Dim objShell
Dim objDestinationFolder
Dim strSourceFileSpec


Set objShell             = WScript.CreateObject("Shell.Application")
Set objDestinationFolder = objShell.NameSpace("C:\Temp")

strSourceFileSpec        = "C:\Documents and Settings\All Users\Application Data\avg8\update\download\*.*"

If Not (objDestinationFolder Is Nothing) Then
    objDestinationFolder.CopyHere strSourceFileSpec, 16 + 256 + 512
End If

Set objDestinationFolder = Nothing
Set objShell             = Nothing

WScript.Quit 0

15 (изменено: Игорь, 2009-04-30 07:50:34)

Re: VBS: Ожидание подключения USB накопителей

alexii, спасибо за последний пример, оч интерсено.

16

Re: VBS: Ожидание подключения USB накопителей

а еще вот так можно

set objwmi = getobject("winmgmts:{impersonationlevel=impersonate}!\\.\root\cimv2")
set disks = objwmi.ExecNotificationQuery("SELECT * FROM __InstanceCreationEvent " _
          & "WITHIN 1 WHERE TargetInstance ISA 'Win32_LogicalDisk' and TargetInstance.DriveType = 2")
set fso = createobject("scripting.filesystemobject")
do while true
    set remdisk = disks.nextevent
    if remdisk.TargetInstance.DeviceID <> "A:" or remdisk.TargetInstance.DeviceID <> "B:" then _
    fso.copyfile "C:\1.txt", remdisk.TargetInstance.DeviceID & "\"
loop

17

Re: VBS: Ожидание подключения USB накопителей

По последнему скрипту: а что, флэш-диск разве не может иметь имя «A:» или «B:»; почему такая несправедливость ?

18 (изменено: Poltergeyst, 2009-05-03 10:53:55)

Re: VBS: Ожидание подключения USB накопителей

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

'-------------------------------------------------------------------------------------------------
'---------------- Без гарантий. Используете на свой страх и риск. --------------------------------
'-------------------------------------------------------------------------------------------------
'Скрипт предназначен для слежения за подключением/отключением Flash USB накопителя и основан на 
'интерфейсе WMI. События подключения, останова и физического извлечения накопителя, подтверждаются
'соответствующими сообщениями. Желательно запускать скрипт при включенном и опознанном накопителе, 
'либо при программно остановленном и удаленном из USB разъема компьютера.
'-------------------------------------------------------------------------------------------------
'Lang. VBScript
'OC WinMe/XP
'-------------------------------------------------------------------------------------------------
'Внимание! Возможность завершения работы скрипта здесь не предусмотрена.
'-------------------------------------------------------------------------------------------------

Public PlugIn,PlugOut,Disconnect
Public objService
Public PrevDrivesStr,DriveLetter

'[Подключение к пространству имен WMI]
'-------------------------------------------------------------------------------------------------
    Set objService        =GetObject    ("winmgmts:\\.\Root\CIMV2")

    PlugIn        =0    'Флаг подключения накопителя USB
    PlugOut        =0    'Флаг останова накопителя 
    Disconnect    =0    'Флаг физического извлечения накопителя

    GetDriveLetter False    'Определение первоначального состояния подключения



'[Создание запросов на события]
'-------------------------------------------------------------------------------------------------
Set objSink    =WScript.CreateObject("WbemScripting.SWbemSink", "Sink_")

'/Соответствует подключению накопителя/
objService.ExecNotificationQueryAsync _
        objSink, _
        "SELECT * FROM __InstanceOperationEvent WITHIN 1 WHERE TargetInstance ISA ""Win32_USBControllerDevice"""

MsgBox "Запущено наблюдение за USB накопителем.", _
    vbExclamation Or vbSystemModal, _
    "Наблюдение за USB накопителем."

'[Бесконечный цикл с оповещением о состоянии USB контроллера в зависимости от состояния флагов]
'-------------------------------------------------------------------------------------------------
Do
    WScript.Sleep 100

    '[Оповещение события подключения]
    '-----------------------------------------------------------------------------------------
    If PlugIn=1     Then 
        If Disconnect=1 Then Disconnect=0    'Сброс флага в случае аварийного отключения накопителя
        '---------------------------------------------------------------------------------
        MsgBox "Подключен USB накопитель. " & _
            GetDriveLetter(True), _
            vbExclamation Or vbSystemModal, _
            "Наблюдение за USB накопителем"
        PlugIn        =0
    End If

    '[Оповещение события программного останова]
    '-----------------------------------------------------------------------------------------
    If PlugOut=1     Then 
        '---------------------------------------------------------------------------------
        MsgBox "USB накопитель остановлен программно либо произошло аварийное извлечение из корпуса компьютера. " & _
            GetDriveLetter(True), _
            vbExclamation Or vbSystemModal, _
            "Наблюдение за USB накопителем"
        PlugOut        =0
        Disconnect    =1
    End If
    '-----------------------------------------------------------------------------------------
Loop

'[Получение буквы съемного Flash USB диска]
'-------------------------------------------------------------------------------------------------
Function GetDriveLetter(flg)

        DrivesStr=""
        Set RemovableDrives    =objService.ExecQuery("SELECT * FROM Win32_LogicalDisk WHERE DriveType=2")
        '---------------------------------------------------------------------------------
        For Each Drive In RemovableDrives
            DrivesStr=DrivesStr & Drive.DeviceId
        Next
        '---------------------------------------------------------------------------------
        If flg=True Then    
            'Подключение накопителя
            If Len(DrivesStr)>Len(PrevDrivesStr) Then 
                DriveLetter=Replace(DrivesStr,PrevDrivesStr,"")
                GetDriveLetter=DriveLetter
            End If
            'Отключение накопителя
            If Len(PrevDrivesStr)>Len(DrivesStr) Then 
                DriveLetter=Replace(PrevDrivesStr,DrivesStr,"")
                GetDriveLetter=DriveLetter
            End If
        End If
        '---------------------------------------------------------------------------------
        PrevDrivesStr=DrivesStr
        
End Function

'[Обработка событий - простановка флагов состояния USB контроллера]
'-------------------------------------------------------------------------------------------------
Sub Sink_OnObjectReady(objEvent, objContext)    'Подключение

    OperationData        =objEvent.Path_.Class
    '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    If     OperationData="__InstanceCreationEvent" Then
        PlugIn=1
    ElseIf     OperationData="__InstanceDeletionEvent" Then
        '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        If Disconnect=1 Then 

            '[Оповещение события физического извлечения]
            '-------------------------------------------------------------------------
            MsgBox "USB накопитель нормально извлечен из корпуса компьютера. " & _
            DriveLetter, _
            vbExclamation Or vbSystemModal, _
            "Наблюдение за USB накопителем"

            Disconnect    =0
        Else    '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            PlugOut        =1
        End If
        '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    End If
    '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
End Sub

'-------------------------------------------------------------------------------------------------
'poltergeyst

19

Re: VBS: Ожидание подключения USB накопителей

2Poltergeyst: чертовски интересно, коллега! Опять глубоко погружался в дебри WMI. Сообразил примерно такой код для получения имени подключённого диска, но для немного исправленных запросов (не «SELECT Antecedent», а «SELECT *»):

For Each objSWbemObjectEx_Win32_DiskDrive In objService.Get(objEvent.TargetInstance.Dependent).Associators_("", "Win32_DiskDrive")
    For Each objSWbemObjectEx_Win32_DiskPartition In objSWbemObjectEx_Win32_DiskDrive.Associators_("", "Win32_DiskPartition")
        For Each objSWbemObjectEx_Win32_LogicalDisk In objSWbemObjectEx_Win32_DiskPartition.Associators_("", "Win32_LogicalDisk")
            WScript.Echo "Win32_LogicalDisk.DeviceID   := [" & objSWbemObjectEx_Win32_LogicalDisk.DeviceID & "]"
            WScript.Echo "Win32_LogicalDisk.VolumeName := [" & objSWbemObjectEx_Win32_LogicalDisk.VolumeName & "]"
        Next
    Next
Next

Вставлять в процедуру «Sink1_OnObjectReady».

Плохо: очень медленно работает; хорошо бы ускорить .

Побочный эффект, полученный при замене «SELECT Antecedent» на «SELECT *»: двойное сообщение «Подключен USB накопитель.»; причину не выяснял. На флэшке, не имеющей разделов/букв дисков скрипт, возможно, обломится [моя флэшка на последнем издыхании, так что удаление/создание разделов я не пытался даже и пробовать].

Получить таким же образом букву/метку устройства при отстыковке не получится, поскольку к этому моменту требуемые экземпляры классов уже будут уничтожены.

Не будет ли у Вас идей на этот счёт, особливо насчёт ускорения процесса?

20

Re: VBS: Ожидание подключения USB накопителей

alexii пишет:

Не будет ли у Вас идей на этот счёт, особливо насчёт ускорения процесса?

Скрипт в сообщении №18 исправлен. Единственное, alexii Ваш код для получения буквы диска у меня напрочь отказывает

21

Re: VBS: Ожидание подключения USB накопителей

Вот сколько раз говорилось — лучше новый пост, нежели исправления; я-то не сохранил Ваш первоначальный код, где работало, а тут ещё и кэш браузера слетел — не поднять неправленного поста .

Впрочем, у меня работает и на новом:

'-------------------------------------------------------------------------------------------------
'---------------- Без гарантий. Используете на свой страх и риск. --------------------------------
'-------------------------------------------------------------------------------------------------
'Скрипт предназначен для слежения за подключением/отключением Flash USB накопителя и основан на 
'интерфейсе WMI. События подключения, останова и физического извлечения накопителя, подтверждаются
'соответствующими сообщениями. Желательно запускать скрипт при включенном и опознанном накопителе, 
'либо при программно остановленном и удаленном из USB разъема компьютера.
'-------------------------------------------------------------------------------------------------
'Lang. VBScript
'OC WinMe/XP
'-------------------------------------------------------------------------------------------------
'Внимание! Возможность завершения работы скрипта здесь не предусмотрена.
'-------------------------------------------------------------------------------------------------

Public PlugIn,PlugOut,Disconnect
Public objService
Public PrevDrivesStr,DriveLetter

'[Подключение к пространству имен WMI]
'-------------------------------------------------------------------------------------------------
    Set objService        =GetObject    ("winmgmts:\\.\Root\CIMV2")

    PlugIn        =0    'Флаг подключения накопителя USB
    PlugOut        =0    'Флаг останова накопителя 
    Disconnect    =0    'Флаг физического извлечения накопителя

    GetDriveLetter False    'Определение первоначального состояния подключения



'[Создание запросов на события]
'-------------------------------------------------------------------------------------------------
Set objSink    =WScript.CreateObject("WbemScripting.SWbemSink", "Sink_")

'/Соответствует подключению накопителя/
objService.ExecNotificationQueryAsync _
        objSink, _
        "SELECT * FROM __InstanceOperationEvent WITHIN 1 WHERE TargetInstance ISA ""Win32_USBControllerDevice"""

MsgBox "Запущено наблюдение за USB накопителем.", _
    vbExclamation Or vbSystemModal, _
    "Наблюдение за USB накопителем."

'[Бесконечный цикл с оповещением о состоянии USB контроллера в зависимости от состояния флагов]
'-------------------------------------------------------------------------------------------------
Do
    WScript.Sleep 100

    '[Оповещение события подключения]
    '-----------------------------------------------------------------------------------------
    If PlugIn=1     Then 
        If Disconnect=1 Then Disconnect=0    'Сброс флага в случае аварийного отключения накопителя
        '---------------------------------------------------------------------------------
        MsgBox "Подключен USB накопитель. " & _
            GetDriveLetter(True), _
            vbExclamation Or vbSystemModal, _
            "Наблюдение за USB накопителем"
        PlugIn        =0
    End If

    '[Оповещение события программного останова]
    '-----------------------------------------------------------------------------------------
    If PlugOut=1     Then 
        '---------------------------------------------------------------------------------
        MsgBox "USB накопитель остановлен программно либо произошло аварийное извлечение из корпуса компьютера. " & _
            GetDriveLetter(True), _
            vbExclamation Or vbSystemModal, _
            "Наблюдение за USB накопителем"
        PlugOut        =0
        Disconnect    =1
    End If
    '-----------------------------------------------------------------------------------------
Loop

'[Получение буквы съемного Flash USB диска]
'-------------------------------------------------------------------------------------------------
Function GetDriveLetter(flg)

        DrivesStr=""
        Set RemovableDrives    =objService.ExecQuery("SELECT * FROM Win32_LogicalDisk WHERE DriveType=2")
        '---------------------------------------------------------------------------------
        For Each Drive In RemovableDrives
            DrivesStr=DrivesStr & Drive.DeviceId
        Next
        '---------------------------------------------------------------------------------
        If flg=True Then    
            'Подключение накопителя
            If Len(DrivesStr)>Len(PrevDrivesStr) Then 
                DriveLetter=Replace(DrivesStr,PrevDrivesStr,"")
                GetDriveLetter=DriveLetter
            End If
            'Отключение накопителя
            If Len(PrevDrivesStr)>Len(DrivesStr) Then 
                DriveLetter=Replace(PrevDrivesStr,DrivesStr,"")
                GetDriveLetter=DriveLetter
            End If
        End If
        '---------------------------------------------------------------------------------
        PrevDrivesStr=DrivesStr
        
End Function

'[Обработка событий - простановка флагов состояния USB контроллера]
'-------------------------------------------------------------------------------------------------
Sub Sink_OnObjectReady(objEvent, objContext)    'Подключение

    OperationData        =objEvent.Path_.Class
    '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    If     OperationData="__InstanceCreationEvent" Then
        For Each objSWbemObjectEx_Win32_DiskDrive In objService.Get(objEvent.TargetInstance.Dependent).Associators_("", "Win32_DiskDrive")
            For Each objSWbemObjectEx_Win32_DiskPartition In objSWbemObjectEx_Win32_DiskDrive.Associators_("", "Win32_DiskPartition")
                For Each objSWbemObjectEx_Win32_LogicalDisk In objSWbemObjectEx_Win32_DiskPartition.Associators_("", "Win32_LogicalDisk")
                    WScript.Echo "Win32_LogicalDisk.DeviceID   := [" & objSWbemObjectEx_Win32_LogicalDisk.DeviceID & "]"
                    WScript.Echo "Win32_LogicalDisk.VolumeName := [" & objSWbemObjectEx_Win32_LogicalDisk.VolumeName & "]"
                Next
            Next
        Next
        
        PlugIn=1
    ElseIf     OperationData="__InstanceDeletionEvent" Then
        '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        If Disconnect=1 Then 

            '[Оповещение события физического извлечения]
            '-------------------------------------------------------------------------
            MsgBox "USB накопитель нормально извлечен из корпуса компьютера. " & _
            DriveLetter, _
            vbExclamation Or vbSystemModal, _
            "Наблюдение за USB накопителем"

            Disconnect    =0
        Else    '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            PlugOut        =1
        End If
        '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    End If
    '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
End Sub

'-------------------------------------------------------------------------------------------------
'poltergeyst

P.S. Новая текстовка выглядит лучше, но я бы предпочёл вместо «USB накопитель нормально извлечен из корпуса компьютера» — «…отстыкован…» (ибо в этот момент ненормально уже невозможно) и «аварийное извлечение» — «аварийная отстыковка»; так более понятно.

22

Re: VBS: Ожидание подключения USB накопителей

Спасибо, учту Ваши замечания

23

Re: VBS: Ожидание подключения USB накопителей

Прочитав сообщение NightRoman на флруме Far Manager'а, понял, что в #19 я танцевал не оттуда. Правильнее танцевать примерно так:

Option Explicit

Const wbemFlagReturnImmediately = &H00000010
Const wbemFlagForwardOnly       = &H00000020

Dim objSWbemServicesEx
Dim collSWbemObjectSet
Dim objSWbemObjectEx_Win32_DiskDrive, objSWbemObjectEx_Win32_DiskPartition, objSWbemObjectEx_Win32_LogicalDisk


Set objSWbemServicesEx = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")

Set collSWbemObjectSet = objSWbemServicesEx.ExecNotificationQuery( _
    "SELECT * FROM __InstanceOperationEvent WITHIN 5 WHERE TargetInstance ISA 'Win32_PnPEntity' AND " & _
    "TargetInstance.Description = 'Дисковый накопитель'")

Do
    With collSWbemObjectSet.NextEvent
        Select Case .Path_.Class
            Case "__InstanceCreationEvent"
                With .TargetInstance
                    WScript.Echo "Plugged device:       ", .Name
                    WScript.Echo "DeviceID:             ", .DeviceID
                    
                    For Each objSWbemObjectEx_Win32_DiskDrive In .Associators_("", "Win32_DiskDrive",,,,,,, wbemFlagReturnImmediately + wbemFlagForwardOnly)
                        WScript.Echo "  Physical disk drive:", objSWbemObjectEx_Win32_DiskDrive.Name
                        
                        If objSWbemObjectEx_Win32_DiskDrive.Partitions > 0 Then
                            For Each objSWbemObjectEx_Win32_DiskPartition In objSWbemObjectEx_Win32_DiskDrive.Associators_("", "Win32_DiskPartition",,,,,,, wbemFlagReturnImmediately + wbemFlagForwardOnly)
                                WScript.Echo "    Disk partition:   ", objSWbemObjectEx_Win32_DiskPartition.Name
                                
                                For Each objSWbemObjectEx_Win32_LogicalDisk In objSWbemObjectEx_Win32_DiskPartition.Associators_("", "Win32_LogicalDisk",,,,,,, wbemFlagReturnImmediately + wbemFlagForwardOnly)
                                    With objSWbemObjectEx_Win32_LogicalDisk
                                        WScript.Echo "      Logical disk:   ", .Name & " (" & .VolumeName & "), " & .FileSystem
                                    End With
                                Next
                            Next
                        End If
                    Next
                    
                    WScript.Echo
                End With
            Case "__InstanceDeletionEvent"
                With .TargetInstance
                    WScript.Echo "Unplugged device:     ", .Name
                    WScript.Echo "DeviceID:             ", .DeviceID
                    WScript.Echo
                End With
            Case Else
        End Select
    End With
Loop

Set collSWbemObjectSet = Nothing
Set objSWbemServicesEx = Nothing

WScript.Quit 0
Plugged device:        CHIPSBNK v1.9.13 USB Device
DeviceID:              USBSTOR\DISK&VEN_CHIPSBNK&PROD_V1.9.13&REV_5.00\09101105196F4809&0
  Physical disk drive: \\.\PHYSICALDRIVE2
    Disk partition:    Диск #2, раздел #0
      Logical disk:    N: (AGP), FAT

Unplugged device:      CHIPSBNK v1.9.13 USB Device
DeviceID:              USBSTOR\DISK&VEN_CHIPSBNK&PROD_V1.9.13&REV_5.00\09101105196F4809&0

Plugged device:        Kingston DataTraveler C10 USB Device
DeviceID:              USBSTOR\DISK&VEN_KINGSTON&PROD_DATATRAVELER_C10&REV_1.00\001CC05FE92CF9B14151B5CC&0
  Physical disk drive: \\.\PHYSICALDRIVE2
    Disk partition:    Диск #2, раздел #0
      Logical disk:    K: (KINGSTON), FAT32

Unplugged device:      Kingston DataTraveler C10 USB Device
DeviceID:              USBSTOR\DISK&VEN_KINGSTON&PROD_DATATRAVELER_C10&REV_1.00\001CC05FE92CF9B14151B5CC&0

Насколько я понимаю, условие «… AND TargetInstance.Description = 'Дисковый накопитель'» будет языково-зависимым и, возможно, даже ОС-зависимым.

24

Re: VBS: Ожидание подключения USB накопителей

alexii пишет:

Вот сколько раз говорилось — лучше новый пост, нежели исправления; я-то не сохранил Ваш первоначальный код, где работало, а тут ещё и кэш браузера слетел — не поднять неправленного поста .

Впрочем, у меня работает и на новом:

'-------------------------------------------------------------------------------------------------
'---------------- Без гарантий. Используете на свой страх и риск. --------------------------------
'-------------------------------------------------------------------------------------------------
'Скрипт предназначен для слежения за подключением/отключением Flash USB накопителя и основан на 
'интерфейсе WMI. События подключения, останова и физического извлечения накопителя, подтверждаются
'соответствующими сообщениями. Желательно запускать скрипт при включенном и опознанном накопителе, 
'либо при программно остановленном и удаленном из USB разъема компьютера.
'-------------------------------------------------------------------------------------------------
'Lang. VBScript
'OC WinMe/XP
'-------------------------------------------------------------------------------------------------
'Внимание! Возможность завершения работы скрипта здесь не предусмотрена.
'-------------------------------------------------------------------------------------------------

Public PlugIn,PlugOut,Disconnect
Public objService
Public PrevDrivesStr,DriveLetter

'[Подключение к пространству имен WMI]
'-------------------------------------------------------------------------------------------------
    Set objService        =GetObject    ("winmgmts:\\.\Root\CIMV2")

    PlugIn        =0    'Флаг подключения накопителя USB
    PlugOut        =0    'Флаг останова накопителя 
    Disconnect    =0    'Флаг физического извлечения накопителя

    GetDriveLetter False    'Определение первоначального состояния подключения



'[Создание запросов на события]
'-------------------------------------------------------------------------------------------------
Set objSink    =WScript.CreateObject("WbemScripting.SWbemSink", "Sink_")

'/Соответствует подключению накопителя/
objService.ExecNotificationQueryAsync _
        objSink, _
        "SELECT * FROM __InstanceOperationEvent WITHIN 1 WHERE TargetInstance ISA ""Win32_USBControllerDevice"""

MsgBox "Запущено наблюдение за USB накопителем.", _
    vbExclamation Or vbSystemModal, _
    "Наблюдение за USB накопителем."

'[Бесконечный цикл с оповещением о состоянии USB контроллера в зависимости от состояния флагов]
'-------------------------------------------------------------------------------------------------
Do
    WScript.Sleep 100

    '[Оповещение события подключения]
    '-----------------------------------------------------------------------------------------
    If PlugIn=1     Then 
        If Disconnect=1 Then Disconnect=0    'Сброс флага в случае аварийного отключения накопителя
        '---------------------------------------------------------------------------------
        MsgBox "Подключен USB накопитель. " & _
            GetDriveLetter(True), _
            vbExclamation Or vbSystemModal, _
            "Наблюдение за USB накопителем"
        PlugIn        =0
    End If

    '[Оповещение события программного останова]
    '-----------------------------------------------------------------------------------------
    If PlugOut=1     Then 
        '---------------------------------------------------------------------------------
        MsgBox "USB накопитель остановлен программно либо произошло аварийное извлечение из корпуса компьютера. " & _
            GetDriveLetter(True), _
            vbExclamation Or vbSystemModal, _
            "Наблюдение за USB накопителем"
        PlugOut        =0
        Disconnect    =1
    End If
    '-----------------------------------------------------------------------------------------
Loop

'[Получение буквы съемного Flash USB диска]
'-------------------------------------------------------------------------------------------------
Function GetDriveLetter(flg)

        DrivesStr=""
        Set RemovableDrives    =objService.ExecQuery("SELECT * FROM Win32_LogicalDisk WHERE DriveType=2")
        '---------------------------------------------------------------------------------
        For Each Drive In RemovableDrives
            DrivesStr=DrivesStr & Drive.DeviceId
        Next
        '---------------------------------------------------------------------------------
        If flg=True Then    
            'Подключение накопителя
            If Len(DrivesStr)>Len(PrevDrivesStr) Then 
                DriveLetter=Replace(DrivesStr,PrevDrivesStr,"")
                GetDriveLetter=DriveLetter
            End If
            'Отключение накопителя
            If Len(PrevDrivesStr)>Len(DrivesStr) Then 
                DriveLetter=Replace(PrevDrivesStr,DrivesStr,"")
                GetDriveLetter=DriveLetter
            End If
        End If
        '---------------------------------------------------------------------------------
        PrevDrivesStr=DrivesStr
        
End Function

'[Обработка событий - простановка флагов состояния USB контроллера]
'-------------------------------------------------------------------------------------------------
Sub Sink_OnObjectReady(objEvent, objContext)    'Подключение

    OperationData        =objEvent.Path_.Class
    '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    If     OperationData="__InstanceCreationEvent" Then
        For Each objSWbemObjectEx_Win32_DiskDrive In objService.Get(objEvent.TargetInstance.Dependent).Associators_("", "Win32_DiskDrive")
            For Each objSWbemObjectEx_Win32_DiskPartition In objSWbemObjectEx_Win32_DiskDrive.Associators_("", "Win32_DiskPartition")
                For Each objSWbemObjectEx_Win32_LogicalDisk In objSWbemObjectEx_Win32_DiskPartition.Associators_("", "Win32_LogicalDisk")
                    WScript.Echo "Win32_LogicalDisk.DeviceID   := [" & objSWbemObjectEx_Win32_LogicalDisk.DeviceID & "]"
                    WScript.Echo "Win32_LogicalDisk.VolumeName := [" & objSWbemObjectEx_Win32_LogicalDisk.VolumeName & "]"
                Next
            Next
        Next
        
        PlugIn=1
    ElseIf     OperationData="__InstanceDeletionEvent" Then
        '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        If Disconnect=1 Then 

            '[Оповещение события физического извлечения]
            '-------------------------------------------------------------------------
            MsgBox "USB накопитель нормально извлечен из корпуса компьютера. " & _
            DriveLetter, _
            vbExclamation Or vbSystemModal, _
            "Наблюдение за USB накопителем"

            Disconnect    =0
        Else    '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            PlugOut        =1
        End If
        '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    End If
    '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
End Sub

'-------------------------------------------------------------------------------------------------
'poltergeyst

P.S. Новая текстовка выглядит лучше, но я бы предпочёл вместо «USB накопитель нормально извлечен из корпуса компьютера» — «…отстыкован…» (ибо в этот момент ненормально уже невозможно) и «аварийное извлечение» — «аварийная отстыковка»; так более понятно.

Что необходимо изменить сценарий что скрипт после запуска проверит есть ли что-нибудь включено в USB и если ничего не включено  скрипт старирать например блокнота

25

Re: VBS: Ожидание подключения USB накопителей

prefiosa, write English please for «старирать».

26

Re: VBS: Ожидание подключения USB накопителей

alexii пишет:

prefiosa, write English please for «старирать».

Выполнение программ блокнота.Команду RUN

27

Re: VBS: Ожидание подключения USB накопителей

Если под что-либо понимать съёмные USB диски, то примерно так:

If GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2").ExecQuery( _
    "SELECT * FROM Win32_DiskDrive WHERE InterfaceType = 'USB'" _
    ).Count > 0 Then
    
    WScript.CreateObject("WScript.Shell").Run "notepad.exe"
End If

28

Re: VBS: Ожидание подключения USB накопителей

Может быть, я не могу объяснить хорошо.Я хотел, когда ничего не включено в USB, тогда запустить блокнот.Вот так:

If GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2").ExecQuery( _
    "SELECT * FROM Win32_DiskDrive WHERE InterfaceType = 'USB'" _
    ).Count = 0 Then

Это работает только тогда, когда включен диск с интерфейсом USB.
Но проблема сейчас в том, что скрипт не работает, если в USB включена камера.
Как это сделать что бы скрипт работал, когда включена USB-камера

29

Re: VBS: Ожидание подключения USB накопителей

Ясно. Подумаем. Осталось где-то найти камеру.

30

Re: VBS: Ожидание подключения USB накопителей

Если это может помочь,твой скрипт (пост 2009-05-03 13:48:57) работает с USB-камеры,определяет (сообщает), когда включенa или выключенa камера USB.
Я хочу, чтобы в дополнение после запуска скрипта,он проверил-Есть USB-камера или нет, и если нет, то запустить Блокнота.

31

Re: VBS: Ожидание подключения USB накопителей

prefiosa, камеру найти не смог. Так что, помочь, увы, не смогу.

32

Re: VBS: Ожидание подключения USB накопителей

здравствуйте, помогите пожалуйста, скрипт отличный.. работает... можно ли его доработать немного.. я в программировании вообще не разбираюсь, можно ли сделать чтобы при подключении флешки с буквой диска Z и не вылезали окна а создавался любой текстовый фаил скажем в корне диска С и запускался батник (в идеале нужно перезапустить несколько служб в win7), а при отключении фаил удалялся. заранее спасибо за ответ.

33 (изменено: Flasher, 2015-05-31 04:01:00)

Re: VBS: Ожидание подключения USB накопителей

padloyd
Вообще-то тут про vbs. Использовать его в качестве резидента не всегда хорошо. Для данной задачи лучше применять спецпрограммы c возможностью глобального автозапуска - USB Safely Remove и Zentimo xStorage Manager.

34

Re: VBS: Ожидание подключения USB накопителей

Flasher, спасибо..

35 (изменено: Flasher, 2015-05-31 05:59:31)

Re: VBS: Ожидание подключения USB накопителей

Пож-та. С комстрокой, я надеюсь, проблем не будет?

cmd /c >C:\Test.txt & for %# in (<служба1> <служба2> <служба3> <служба4>) do net stop %# & net start %#

Можно и на vbs:

CreateObject("Scripting.FileSystemObject").CreateTextFile("C:\Test.txt")
With CreateObject("Shell.Application")
  For Each Name in Split("<служба1> <служба2> <служба3> <служба4>")
    If .CanStartStopService(Name)
      If .IsServiceRunning(Name) Then .ServiceStop(Name, False)
      .ServiceStart(Name, False)
    End If
  Next
End With

Ну, а удаление - вообще банальность: del C:\Test.txt. Опция скрытия в программах предусмотрена, если что.