我知道有人讨论过,由于 Win 7 中自动运行(或自动播放??)的限制,连接 USB 驱动器后无法启动应用程序。但可以创建具有事件类型触发器的计划任务。当然,当驱动器(或任何 USB 设备)连接时,一定会发生事件。
有人知道我应该使用哪个事件 ID 吗?或者至少知道是什么类型的事件?我在事件查看器中可以在哪里找到该事件?
答案1
线程任务计划程序:如何自动同步我的 USB 闪存驱动器? 有一个名为 monotone 的用户给出了这个答案,它将 PowerShell 与任务计划程序结合使用:
我和你有同样的问题,并使用脚本专家博客中的技术,用 powershell (windows 内置脚本) 解决了一些问题这里和这里。脚本作为后台进程持续运行,您可以在系统登录时使用任务计划程序启动它。每当插入新驱动器时,脚本都会收到通知,然后执行某些操作(在这里您可以配置脚本而不是任务)。由于它在等待下一个插入驱动器时基本上处于暂停状态,因此您不会发现它占用太多资源。我来看一下:
1) 启动 Powershell ISE,可以在开始菜单的附件/Windows Powershell 下找到。2) 将以下内容复制粘贴到 Powershell 中:
#Requires -version 2.0 Register-WmiEvent -Class win32_VolumeChangeEvent -SourceIdentifier volumeChange write-host (get-date -format s) " Beginning script..." do{ $newEvent = Wait-Event -SourceIdentifier volumeChange $eventType = $newEvent.SourceEventArgs.NewEvent.EventType $eventTypeName = switch($eventType) { 1 {"Configuration changed"} 2 {"Device arrival"} 3 {"Device removal"} 4 {"docking"} } write-host (get-date -format s) " Event detected = " $eventTypeName if ($eventType -eq 2) { $driveLetter = $newEvent.SourceEventArgs.NewEvent.DriveName $driveLabel = ([wmi]"Win32_LogicalDisk='$driveLetter'").VolumeName write-host (get-date -format s) " Drive name = " $driveLetter write-host (get-date -format s) " Drive label = " $driveLabel # Execute process if drive matches specified condition(s) if ($driveLetter -eq 'Z:' -and $driveLabel -eq 'Mirror') { write-host (get-date -format s) " Starting task in 3 seconds..." start-sleep -seconds 3 start-process "Z:\sync.bat" } } Remove-Event -SourceIdentifier volumeChange } while (1-eq1) #Loop until next event Unregister-Event -SourceIdentifier volumeChange
3) 您需要修改上述脚本,告诉脚本要查找哪个驱动器以及要执行什么。需要更改的两行是:
if ($driveLetter -eq 'Z:' -and $driveLabel -eq 'Mirror')
我的 USB 硬盘驱动器名为“Mirror”,设置为 Z: 驱动器。
if ($driveLabel -eq 'MyDiskLabel')
如果您不介意字母,则可以直接使用。start-process "Z:\sync.bat"
您要执行的任何任务的路径。在我的示例中,我在 USB 驱动器上创建了一个批处理文件,该文件启动了 3-4 个备份任务命令行。
4) 完成后,将脚本保存在某个位置(扩展名
.ps1
),然后在任务计划程序中创建一个任务,让脚本在后台运行。我的脚本如下所示:
- 触发条件:登录时
- 操作:启动程序
- 程序/脚本:powershell
- 添加参数:
-ExecutionPolicy Unrestricted -File "D:\Stuff\Backup script.ps1"
5)瞧!
6)额外内容:
如果您希望隐藏脚本窗口,请使用以下参数:
- 添加参数:
-WindowStyle Hidden -ExecutionPolicy Unrestricted -File "D:\Stuff\Backup script.ps1"
如果您想要将脚本消息输出到日志文件(每次脚本启动时,即登录时,该文件都会被覆盖),请使用以下任务操作:
- 程序/脚本:cmd
- 添加参数:
/c powershell -WindowStyle Hidden -ExecutionPolicy Unrestricted -File "D:\Stuff\Backup script.ps1" > "D:\Stuff\script
log.txt”任何时候您想要结束正在运行的隐藏脚本,您都可以在任务管理器中结束“Powershell”进程。
唯一的缺点是,当您在驱动器已插入的情况下启动计算机时,什么都不会运行。(虽然可以将脚本更改为最初执行第一次检查,但我今天已经受够了!)
答案2
我能够让它工作:我在应用程序和服务日志中找到了事件 1003,对于插入 USB 的手机,Microsoft-Windows-DriverFrameworks-UserMode
事件的完整 xml:
- <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
- <System>
<Provider Name="Microsoft-Windows-DriverFrameworks-UserMode" Guid="{2E35AAEB-857F-4BEB-A418-2E6C0E54D988}" />
<EventID>1003</EventID>
<Version>1</Version>
<Level>4</Level>
<Task>17</Task>
<Opcode>1</Opcode>
<Keywords>0x8000000000000000</Keywords>
<TimeCreated SystemTime="2016-08-19T01:42:06.292278900Z" />
<EventRecordID>17516</EventRecordID>
<Correlation />
<Execution ProcessID="456" ThreadID="2932" />
<Channel>Microsoft-Windows-DriverFrameworks-UserMode/Operational</Channel>
<Computer>XXXX</Computer>
<Security UserID="S-1-5-18" />
</System>
- <UserData>
- <UMDFDriverManagerHostCreateStart lifetime="{AFEC92AD-6015-4AB4-86AE-F34CEE06A977}" xmlns:auto-ns2="http://schemas.microsoft.com/win/2004/08/events" xmlns="http://www.microsoft.com/DriverFrameworks/UserMode/Event">
<HostGuid>{193a1820-d9ac-4997-8c55-be817523f6aa}</HostGuid>
<DeviceInstanceId>USB.VID_04E8&PID_6860&MS_COMP_MTP&SAMSUNG_ANDROID.6&3400EB54&1&0000</DeviceInstanceId>
</UMDFDriverManagerHostCreateStart>
</UserData>
</Event>
以及我的任务的自定义事件过滤器:
<QueryList>
<Query Id="0" Path="Microsoft-Windows-DriverFrameworks-UserMode/Operational">
<Select Path="Microsoft-Windows-DriverFrameworks-UserMode/Operational">*[System[Provider[@Name='Microsoft-Windows-DriverFrameworks-UserMode'] and EventID=1003]] and *[UserData[UMDFDriverManagerHostCreateStart[DeviceInstanceId="USB.VID_04E8&PID_6860&MS_COMP_MTP&SAMSUNG_ANDROID.6&3400EB54&1&0000"]]]</Select>
</Query>
</QueryList>
同样,对于 USB 驱动器,事件为 2100、2101、2105、2106。
对于特定的 USB 驱动器:
- <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
- <System>
<Provider Name="Microsoft-Windows-DriverFrameworks-UserMode" Guid="{2E35AAEB-857F-4BEB-A418-2E6C0E54D988}" />
<EventID>2101</EventID>
<Version>1</Version>
<Level>4</Level>
<Task>37</Task>
<Opcode>2</Opcode>
<Keywords>0x8000000000000000</Keywords>
<TimeCreated SystemTime="2016-08-19T01:52:37.922289600Z" />
<EventRecordID>17662</EventRecordID>
<Correlation />
<Execution ProcessID="10956" ThreadID="11892" />
<Channel>Microsoft-Windows-DriverFrameworks-UserMode/Operational</Channel>
<Computer>XXXX</Computer>
<Security UserID="S-1-5-19" />
</System>
- <UserData>
- <UMDFHostDeviceRequest instance="WPDBUSENUMROOT\UMB\2&37C186B&0&STORAGE#VOLUME#_??_USBSTOR#DISK&VEN_SANDISK&PROD_SANDISK_CRUZER&REV_8.02#0774230A28933B7E&0#" lifetime="{4493DBFB-81E8-4277-933D-955C4DDDD482}" xmlns:auto-ns2="http://schemas.microsoft.com/win/2004/08/events" xmlns="http://www.microsoft.com/DriverFrameworks/UserMode/Event">
- <Request major="27" minor="20">
<Argument>0x0</Argument>
<Argument>0x141b</Argument>
<Argument>0x0</Argument>
<Argument>0x0</Argument>
</Request>
<Status>0</Status>
</UMDFHostDeviceRequest>
</UserData>
</Event>
"<request>"
当我插入 USB 驱动器时,事件 2101 似乎发生了 3 次,且标签略有不同:
<Request major="27" minor="20">
<Request major="27" minor="9">
<Request major="27" minor="0">
我不知道这是什么意思,但这里只有一个过滤器以避免多次触发:(这只会触发这个特定的 USB 驱动器)
<QueryList>
<Query Id="0" Path="Microsoft-Windows-DriverFrameworks-UserMode/Operational">
<Select Path="Microsoft-Windows-DriverFrameworks-UserMode/Operational">*[System[Provider[@Name='Microsoft-Windows-DriverFrameworks-UserMode'] and EventID=2101]] and *[UserData[UMDFHostDeviceRequest[@instance="WPDBUSENUMROOT\UMB\2&37C186B&0&STORAGE#VOLUME#_??_USBSTOR#DISK&VEN_SANDISK&PROD_SANDISK_CRUZER&REV_8.02#0774230A28933B7E&0#" and Request[@major="27" and @minor="20"]]]]</Select>
</Query>
</QueryList>
请注意,必须将 & 符号转义为&
答案3
答案4
正如其他人提到的,似乎服务控制管理器中的系统日志事件 7036 是唯一与插入 USB 驱动器可靠关联的事件。我通过插入 USB 驱动器并运行以下 powershell 命令来检查这一点,以列出过去一小时内来自所有来源的所有事件日志条目:
get-winevent | where {$_.timecreated -ge (get-date) - (new-timespan -hour 1)}
不幸的是,每次服务控制管理器成功启动或停止任何服务时都会生成事件 7036,因此需要进行额外的过滤。
事件查看器/任务计划程序的 GUI 中提供的过滤功能非常基础,不允许对事件数据进行任何过滤 - 它只允许您过滤元数据,在这种情况下,元数据不会告诉您哪个服务已更改状态以及它已更改为什么状态。这些信息保存在 EventData 的“param1”和“param2”中。因此,可以使用以下 XPath 过滤器仅捕获启动的相关服务:
<QueryList>
<Query Id="0" Path="System">
<Select Path="System">*[System[Provider[@Name='Service Control Manager'] and (Level=4 or Level=0) and (band(Keywords,36028797018963968)) and (EventID=7036)]]
and
*[EventData[
Data[@Name="param1"]="Portable Device Enumerator Service" and
Data[@Name="param2"]="running"
]
]
</Select>
</Query>
</QueryList>
从那里您可以运行脚本,最好使用一些额外的逻辑来检查插入的 USB 驱动器是否是您感兴趣的。