如何在Windows 10分配访问模式下防止用户重复打开同一应用
如何在Windows 10分配访问模式下防止用户重复打开同一应用
嘿,我太懂你这个烦恼了——快速点击的时候,之前那套查进程的脚本根本赶不上,两次点击的脚本都能“钻空子”查到进程数为0,结果就多开了应用。针对Windows 10分配访问(多应用 kiosk)的场景,我给你几个更稳的解决办法:
1. 优先用应用自身的单实例启动参数(最省心)
如果你的目标应用支持单实例启动参数,这绝对是最优解——完全绕开脚本的竞态问题,直接让应用自己限制自己。比如你用的Chrome,只需要给快捷方式加个启动参数:
- 找到Chrome的安装路径,默认是
C:\Program Files\Google\Chrome\Application\chrome.exe - 修改分配访问里的Chrome快捷方式目标,改成:
"C:\Program Files\Google\Chrome\Application\chrome.exe" --single-application
这样不管用户怎么快速点击,Chrome只会打开一个实例,甚至会把新的请求直接转到已打开的窗口里,完美解决重复打开的问题。
2. 优化VBS脚本,解决竞态条件
如果你的应用不支持单实例参数,那得把之前的脚本改一改,补上“检查-启动”之间的空隙问题。核心思路是加个锁机制,要么用锁文件,要么让脚本等待应用退出,避免多个脚本实例同时通过检查。
这里给你改好的VBS脚本,加了锁文件和进程等待的双重保障:
Set objShell = CreateObject("WScript.Shell") Set objFSO = CreateObject("Scripting.FileSystemObject") Set objWMIService = GetObject("winmgmts:\\.\root\cimv2") strProgramName = "chrome.exe" ' 用一个系统级的文件夹存锁文件,避免用户权限问题 strLockFolder = "C:\ProgramData\AppLocks" strLockFile = strLockFolder & "\" & strProgramName & ".lock" ' 先检查进程是否存在,或者锁文件是否存在 Set colProcesses = objWMIService.ExecQuery("SELECT * FROM Win32_Process WHERE Name = '" & strProgramName & "'") If colProcesses.Count = 0 And Not objFSO.FileExists(strLockFile) Then ' 确保锁文件夹存在 If Not objFSO.FolderExists(strLockFolder) Then objFSO.CreateFolder(strLockFolder) End If ' 创建锁文件 objFSO.CreateTextFile(strLockFile, True).Close ' 启动程序并**等待它退出**,这样锁文件会一直存在到程序关闭 objShell.Run strProgramName, 1, True ' 程序退出后删除锁文件 If objFSO.FileExists(strLockFile) Then objFSO.DeleteFile(strLockFile) End If Else ' 要么进程已经在跑,要么有锁文件,直接退出 WScript.Quit End If
这个脚本的改进点:
- 用
Run方法的第三个参数True,让脚本一直等到应用退出再删除锁文件,这样在应用运行期间,锁文件始终存在 - 同时检查进程和锁文件,双重保险,彻底堵上快速点击的空隙
- 锁文件存在系统级目录,避免分配访问的用户权限不足的问题
3. 用本地组策略/AppLocker做兜底(进阶)
如果上面的方法还不够,你可以用Windows的AppLocker来设置更严格的规则:
- 打开本地组策略编辑器,找到计算机配置>Windows设置>安全设置>应用程序控制策略>AppLocker
- 创建一个“可执行规则”,允许目标应用运行,然后结合脚本的锁机制,或者用AppLocker的“仅允许已发布的应用”规则,配合脚本的单实例控制,进一步限制多开
不过这个方法比较复杂,一般前两个方法就足够解决问题了。
备注:内容来源于stack exchange,提问作者Carles Fitó Negre
相关产品推荐
相关产品推荐

