标题: [系统相关] [已解决]实现 u盘插入拔出时,调用一个程序 [打印本页]
作者: newswan 时间: 2024-1-25 23:06 标题: [已解决]实现 u盘插入拔出时,调用一个程序
本帖最后由 newswan 于 2024-1-27 18:45 编辑
有什么程序可以实现,当u盘 移动磁盘插入拔出时,调用一个程序, 批处理或者 powershell脚本
用于自动共享离线盘,
挂上的时候,自动共享 moive 目录
取下的时候,自动删除共享
作者: Five66 时间: 2024-1-26 00:12
得监控u盘插入拔出,需要一直运行
监控可以自己监控,也可以让系统监控
自己监控的话写一个每隔一段时间检测盘符之类的主程序,然后根据检测结果运行其他程序或代码就是了
让系统监控的话得用win api,比如注册并处理WM_DEVICECHANGE
作者: czjt1234 时间: 2024-1-26 09:11
vbs- s = "SELECT * FROM __InstanceOperationEvent WITHIN 1 WHERE " & _
- "TargetInstance ISA 'Win32_LogicalDisk' AND TargetInstance.DriveType = 2"
- Set oWshShell = CreateObject("WScript.Shell")
- Set oWMI = GetObject("Winmgmts:\\.\Root\Cimv2")
- Set oSWbemEventSource = oWMI.ExecNotificationQuery(s)
- Do
- Set oSWbemObject = oSWbemEventSource.NextEvent()
- Select Case oSWbemObject.Path_.Class
- Case "__InstanceCreationEvent"
- 'MsgBox "U盘插入,盘符:" & oSWbemObject.TargetInstance.DeviceId
- oWshShell.Run "net use ......", 0
- Case "__InstanceDeletionEvent"
- 'MsgBox "U盘移除,盘符:" & oSWbemObject.TargetInstance.DeviceId
- oWshShell.Run "net use ......", 0
- End Select
- Loop
复制代码
net命令自己修改一下
作者: yakeyun 时间: 2024-1-26 12:32
本帖最后由 yakeyun 于 2024-1-26 12:33 编辑
回复 1# newswan
在U盘根目录创建一个文本文件,命名为“test.txt”:- @echo off & setlocal enabledelayedexpansion
- :RUN
- set "file=test.txt"
- set "found=false"
- for /D %%d in (D: E: F: G: H: I: J: K: L: M: N: O: P: Q: R: S: T: U: V: W: X: Y: Z:) do (
- if exist "%%d\%file%" (
- set "found=true"
- echo %%d\%file%
- echo 找到标记文件,开始执行命令。
- rem 自动共享 moive 目录
- goto RUN
- )
- )
-
- if "%found%"=="false" (
- echo 未找到标记文件,开始执行命令。
- rem 删除共享
- goto RUN
- )
复制代码
作者: WHY 时间: 2024-1-26 13:43
本帖最后由 WHY 于 2024-1-26 21:15 编辑
- Unregister-Event USBCheck -ea SilentlyContinue;
- $query = "select * from __InstanceOperationEvent within 5 where TargetInstance isa 'Win32_LogicalDisk' and TargetInstance.DriveType=2";
-
- Register-WmiEvent -Query $query -SourceIdentifier USBCheck -Action {
- $class = $eventArgs.NewEvent.__CLASS;
- $name = $eventArgs.NewEvent.TargetInstance.Name;
- Switch ($class) {
- __InstanceCreationEvent {
- Write-Host "USB Drive $name--Inserted."
- #### net share MyShareName="C:\Users"
- }
- __InstanceDeletionEvent {
- Write-Host "USB Drive $name--Removed."
- #### net share MyShareName /Delete
- }
- }
- }
复制代码
保存为 D:\Test.ps1,CMD 或 PowerShell 命令行窗口执行:- PowerShell -NoExit -exec Bypass -file "D:\Test.ps1"
复制代码
作者: newswan 时间: 2024-1-26 16:31
回复 3# czjt1234
谢谢!
作者: newswan 时间: 2024-1-26 16:32
回复 5# WHY
谢谢!
作者: WHY 时间: 2024-1-26 21:18
Test.ps1,右键 "使用 PowerShell 运行"- Unregister-Event USBCheck -ea SilentlyContinue;
- $query = "select * from __InstanceOperationEvent within 5 where TargetInstance isa 'Win32_LogicalDisk' and TargetInstance.DriveType=2";
- Register-WmiEvent -Query $query -SourceIdentifier USBCheck;
-
- while ($true) {
- $e = Wait-Event -SourceIdentifier USBCheck;
- $class = $e.SourceArgs.NewEvent.__CLASS;
- $name = $e.SourceArgs.NewEvent.TargetInstance.Name;
- Switch ($class) {
- __InstanceCreationEvent {
- Write-Host "USB Drive $name --Inserted.";
- #### net share MyShareName="C:\Users"
- }
- __InstanceDeletionEvent {
- Write-Host "USB Drive $name --Removed.";
- #### net share MyShareName /Delete
- }
- }
- Remove-Event -SourceIdentifier USBCheck;
- }
复制代码
作者: newswan 时间: 2024-1-26 22:42
回复 8# WHY
长时间运行的话,应该第一种好些吧
作者: WHY 时间: 2024-1-26 23:40
第1个用的是 -action 脚本块,订阅的事件不会放到队列中;
第2个将订阅的事件会放到队列中,用 Wait-event 处理事件。
一定要分出个孰优孰劣,我认为第2个更方便,相比第1个在命令行输入 PowerShell 命令运行,用右键要方便一点点;
命令行窗口运行还会多启动一个CMD或者POWERSHELL进程。
个人见解,不一定正确,萝卜白菜,各有所爱吧。
作者: newswan 时间: 2024-1-27 15:39
回复 10# WHY
新问题,学习了下相关知识,
__InstanceOperationEvent 包含3种事件:
__InstanceCreationEvent
__InstanceDeletionEvent
__InstanceModificationEvent
能不能在一个查询中查询 Creation Deletion ,避免 Modification- "select * from __InstanceCreationEvent within 5 where TargetInstance isa 'Win32_LogicalDisk' and TargetInstance.DriveType=2"
- "select * from __InstanceDeletionEvent within 5 where TargetInstance isa 'Win32_LogicalDisk' and TargetInstance.DriveType=2"
复制代码
看了wql ,没找到 union ,还有什么办法吗?
作者: newswan 时间: 2024-1-27 15:39
回复 3# czjt1234
新问题,学习了下相关知识,
__InstanceOperationEvent 包含3种事件:
__InstanceCreationEvent
__InstanceDeletionEvent
__InstanceModificationEvent
能不能在一个查询中查询 Creation Deletion ,避免 Modification- "select * from __InstanceCreationEvent within 5 where TargetInstance isa 'Win32_LogicalDisk' and TargetInstance.DriveType=2"
- "select * from __InstanceDeletionEvent within 5 where TargetInstance isa 'Win32_LogicalDisk' and TargetInstance.DriveType=2"
复制代码
看了wql ,没找到 union ,还有什么办法吗?
作者: newswan 时间: 2024-1-27 16:43
回复 4# yakeyun
一开始也是你这种方法,用 net share 和 wmic volume
作者: czjt1234 时间: 2024-1-27 16:50
回复 12# newswan
需要这么查询的目的是?
没理解什么环境需要这个需求
作者: newswan 时间: 2024-1-27 16:56
本帖最后由 newswan 于 2024-1-27 16:57 编辑
回复 14# czjt1234
只需要订阅 __InstanceCreationEvent , __InstanceDeletionEvent
但 __InstanceOperationEvent 还包含了 __InstanceModificationEven ,这个事件很多,也被订阅了, 写的时候,也会引发操作。
从优化的目的,应该去掉这个
作者: czjt1234 时间: 2024-1-27 17:44
回复 15# newswan
我测试了win7x64
拔插U盘会触发设定的程序
在U盘上写入删除修改文件,均不会触发设定的程序
作者: newswan 时间: 2024-1-27 17:58
回复 16# czjt1234
会不停的有消息__InstanceModificationEvent- $psAction = {
- $action = $eventArgs.NewEvent.__CLASS
- Write-Host ""
- Write-Host (Get-Date)
- Write-Host $action
- }
-
- $psQuery = " select * from __InstanceOperationEvent within 1 where TargetInstance isa 'Win32_LogicalDisk' "
-
- Register-WmiEvent -SourceIdentifier mountEvent -Query $psQuery -Action $psAction
复制代码
作者: newswan 时间: 2024-1-27 18:01
回复 16# czjt1234
你加上 case else 试试
作者: WHY 时间: 2024-1-27 18:04
回复 11# newswan - $query = "select * from __InstanceOperationEvent within 5 where (__CLASS='__InstanceCreationEvent' or __CLASS='__InstanceDeletionEvent') and TargetInstance isa 'Win32_LogicalDisk' and TargetInstance.DriveType=2";
复制代码
这样写,除了查询语句变长、变复杂,没啥太大意义。
即使这样写,还是需要 Swith 或 If 判断一下,除非插入与拔出时执行的是一样的命令(比如都是设置共享,或者都是删除共享)。
作者: newswan 时间: 2024-1-27 18:09
回复 19# WHY
谢谢,但是,我是为了避免的不需要的事件
作者: czjt1234 时间: 2024-1-27 18:10
回复 18# newswan
为什么要加 case else
原代码已经满足了你的需求,不是不要加这个么
加了这个反而不好
还有 ps 不是用了 Switch ($class) 么
你把这个去掉当然有问题了
作者: newswan 时间: 2024-1-27 18:13
回复 21# czjt1234
这样通知订阅就 提前过滤掉 __InstanceModificationEvent ,不用到 case 的才过滤掉
作者: newswan 时间: 2024-1-27 18:14
回复 19# WHY
让 ai 给合并,结果是个 250
作者: czjt1234 时间: 2024-1-27 18:49
提前过滤掉 __InstanceModificationEvent
代码运行查看cpu占用基本为0,不用在意这个吧
再说19楼说了,即使过滤掉,还是要对结果进行 case 或 Switch
非要过滤掉,vbs可以变通一下,当然代码非但没简洁反而更复杂了- s1 = "SELECT * FROM __InstanceCreationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_LogicalDisk' AND TargetInstance.DriveType = 2"
- s2 = "SELECT * FROM __InstanceDeletionEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_LogicalDisk' AND TargetInstance.DriveType = 2"
- Set oWshShell = CreateObject("WScript.Shell")
- Set oWMI = GetObject("Winmgmts:\\.\Root\Cimv2")
- Set oSWbemSink = WScript.CreateObject("WbemScripting.SWbemSink", "Sink_")
- Set o1 = CreateObject("WbemScripting.SWbemNamedValueSet")
- o1.Add "类型", "插入"
- Set o2 = CreateObject("WbemScripting.SWbemNamedValueSet")
- o2.Add "类型", "拔出"
- oWMI.ExecNotificationQueryAsync oSWbemSink, s1,,,, o1
- oWMI.ExecNotificationQueryAsync oSWbemSink, s2,,,, o2
- Do
- WScript.Sleep 100
- Loop
- Sub Sink_OnObjectReady(objWbemObject, objWbemAsyncContext)
- If objWbemAsyncContext.Item("类型") = "插入" Then msgbox "插入"
- If objWbemAsyncContext.Item("类型") = "拔出" Then msgbox "拔出"
- End Sub
复制代码
作者: newswan 时间: 2024-1-30 10:40
回复 24# czjt1234
这算强迫症
作者: newswan 时间: 2024-2-5 15:39
最终- if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] 'Administrator')) {
- Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -NoExit -File `"$PSCommandPath`"" -Verb RunAs
- exit
- }
-
-
- $psQuery = @"
- select * from __InstanceOperationEvent within 1
- where TargetInstance isa 'Win32_LogicalDisk' and (__CLASS='__InstanceCreationEvent' or __CLASS='__InstanceDeletionEvent')
- "@
-
- $psAction = {
- $action = $eventArgs.NewEvent.__CLASS
- $diskDriveType = $event.SourceArgs.NewEvent.TargetInstance.DriveType
- $diskLetter = $event.SourceArgs.NewEvent.TargetInstance.Name
- $diskVolume = $event.SourceArgs.NewEvent.TargetInstance.VolumeName
-
- Write-Host "`n"
- Write-Host "- $( Get-Date -format "yyyy-MM-dd HH:mm:ss" ) -"
-
- switch ( $diskDriveType ) {
- 2 {
- $sharePath = $diskLetter + "movie"
- $shareName = $diskVolume -replace "\D+","movie"
-
- Switch ($action) {
- "__InstanceCreationEvent" {
- if ( Test-Path $sharePath ) {
- Write-Host "USB Drive $diskLetter $diskVolume Inserted."
- Write-Host $(net share $shareName=$sharePath /GRANT:everyone,CHANGE)
- }
- }
- "__InstanceDeletionEvent" {
- Write-Host "USB Drive $diskLetter $diskVolume Removed."
- Write-Host $(net share $shareName /Delete)
- }
- }
- }
- 5 {
- $sharePath = $diskLetter
- $shareName = $($sharePath -replace ":","_") + $diskVolume
-
- Switch ($action) {
- "__InstanceCreationEvent" {
- Write-Host "Optical Drive $diskLetter $diskVolume Inserted."
- Write-Host $(net share $shareName=$sharePath)
- }
- "__InstanceDeletionEvent" {
- Write-Host "Optical Drive $diskLetter $diskVolume Removed."
- Write-Host $(net share $shareName /Delete)
- }
- }
- }
- }
- }
-
-
- Unregister-Event mountEvent -ErrorAction SilentlyContinue
- Register-WmiEvent -SourceIdentifier mountEvent -Query $psQuery -Action $psAction
复制代码
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |