Программа VBScript неправильно идентифицирует свой PID? - PullRequest
0 голосов
/ 11 марта 2020

Каждый раз, когда мне нужно предоставить пользователю доступ к общей папке на нашем сервере, я получаю многочисленные всплывающие сообщения, потому что процесс обращается к различным файлам, права доступа которых я не могу изменить:

Error Applying Security Error

Это не проблема, но мне надоело постоянно останавливать то, над чем я работал, чтобы нажать кнопку «Продолжить». Итак, я написал программу, которая постоянно сканирует окно «Ошибка применения безопасности», и всякий раз, когда оно обнаруживает его, отправляет ему клавишу «Enter». Это работало достаточно хорошо, но поскольку центральный l oop никогда не завершается, я решил добавить возможность завершать программу после ее завершения. Я мог бы использовать файл .hta, но я решил попробовать другой подход, который держал все в одном файле, чтобы облегчить дальнейшее обслуживание. Я принял код из этого вопроса о переполнении стека , чтобы найти PID моей программы и позволить завершить программу с помощью команды Windows TASKKILL после закрытия всплывающего окна.

Программа, кажется, работать правильно, идентифицируя его PID и передавая его всплывающему окну. Однако, когда запускается TASKKILL, он утверждает, что PID не существует. Кто-нибудь может увидеть, что я делаю не так? Заранее спасибо всем, кто откликнется.

'  AutoContinue.vbs
'  Program to automatically close all "Error Applying Security" messages

Option Explicit

Const Hidden = 0
Dim objWshShell, objWMILocator, objWMIService
Dim strComputerName, objArgs, objChildProcess, colPIDs, objPID

Set objWshShell = CreateObject( "WScript.Shell" )
Set objWMILocator = CreateObject( "WBemScripting.SWbemLocator" )
Set objWMIService = objWMILocator.ConnectServer( "", "", "", "" )

Function MyProcessID ()
' MyProcessID finds and returns my own PID.

    MyProcessID = 0
    Set objChildProcess = objWshShell.Exec( "%comspec% /C pause" )
    Set colPIDs= objWMIService.ExecQuery( "Select * From Win32_Process" & _
        " Where ProcessId=" & objChildProcess.ProcessID,, 0 )
    For Each objPID In colPIDs
        MyProcessID = objPID.ParentProcessID
    Next
    Call objChildProcess.Terminate()
End Function

Set objArgs = WScript.Arguments
If objArgs.Count = 1 Then
    If objArgs.Item(0) = "Popup" Then
        objWshShell.Popup( "AutoContinue PID is " & MyProcessID & _
            vbCrLf & "Hit OK when done." )
'        objWshShell.Run "taskkill /PID " & MyProcessID & " /T", 1
        objWshShell.Run "%comspec% /k taskkill /PID " & MyProcessID & " /T", 1
        Set objArgs = Nothing
        Set objWshShell = Nothing
        WScript.Quit
    End If
End If

objWshShell.Run "wscript.exe " & WScript.ScriptName & " Popup", Hidden

Do
    Do
        WScript.Sleep( 500 )
    Loop While Not objWshShell.AppActivate( "Error Applying Security" )
    WScript.Sleep( 100 )
    objWshShell.AppActivate( "Error Applying Security" )
    WScript.Sleep( 100 )
    objWshShell.SendKeys( "{ENTER}" )
Loop While True

Set objWshShell = Nothing

1 Ответ

1 голос
/ 19 марта 2020

Скрипт правильно идентифицирует свой собственный PID. Однако вы пытаетесь уничтожить себя (экземпляр сценария с предоставленным аргументом Popup), в то время как вам нужно уничтожить экземпляр сценария без него (или с другим 1-м аргументом?).

Может помочь следующее решение: укажите PID экземпляра для уничтожения в качестве 2-го аргумента (см. переменную iPid) вместе с Popup one…

'  AutoContinue.vbs
'  Program to automatically close all "Error Applying Security" messages
Option Explicit
Const Hidden = 0
Dim objWshShell, objWMILocator, objWMIService
Dim strComputerName, objArgs, objChildProcess, colPIDs, objPID

Set objWshShell = CreateObject( "WScript.Shell" )
Set objWMILocator = CreateObject( "WBemScripting.SWbemLocator" )
Set objWMIService = objWMILocator.ConnectServer( "", "", "", "" )

Function MyProcessID ()
' MyProcessID finds and returns my own PID.

    MyProcessID = 0
    Set objChildProcess = objWshShell.Exec( "%comspec% /C pause" )
    Set colPIDs= objWMIService.ExecQuery( "Select * From Win32_Process" & _
        " Where ProcessId=" & objChildProcess.ProcessID,, 0 )
    For Each objPID In colPIDs
        MyProcessID = objPID.ParentProcessID
    Next
    Call objChildProcess.Terminate()
End Function

Dim iPid
iPid = MyProcessID()

Set objArgs = WScript.Arguments
If objArgs.Count >= 2 Then
    If objArgs.Item(0) = "Popup" Then
        objWshShell.Popup( "AutoContinue PID is " & objArgs.Item(1) & _
            vbCrLf & "Hit OK when done." )
'        objWshShell.Run "taskkill /PID " & objArgs.Item(1) & " /T /F", 1
        objWshShell.Run "%comspec% /k taskkill /PID " & objArgs.Item(1) & " /T /F", 1
        Set objArgs = Nothing
        Set objWshShell = Nothing
        WScript.Quit
    End If
End If

objWshShell.Run "wscript.exe """ _
    & WScript.ScriptFullName & """ Popup " & CStr( iPid) , Hidden
''                                 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ two arguments

Do
     Do
        WScript.Sleep( 500 )
     Loop While Not objWshShell.AppActivate( "Error Applying Security" )
     WScript.Sleep( 100 )
     objWshShell.AppActivate( "Error Applying Security" )
     WScript.Sleep( 100 )
     objWshShell.SendKeys( "{ENTER}" )
Loop While True
...