Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Call Subroutine Asynchronously 1

Status
Not open for further replies.

DJX995

IS-IT--Management
Jan 12, 2009
20
US
I have the following code that creates a process and then continually checks to make sure it's still running.
If it finds that it is closed, it creates it again and then loops forever.

Code:
Set objWMIServiceWin32Process = GetObject("WinMgmts:\\.\root\cimv2:Win32_Process")
	objWMIServiceWin32Process.Create strCmd1, null, null, intID1
	objWMIServiceWin32Process.Create strCmd2, null, null, intID2

Set objWMIServiceRoot = GetObject("WinMgmts:\\.\root\cimv2")
	Set colProcesses = objWMIServiceRoot.ExecNotificationQuery("Select * From __InstanceDeletionEvent Within 1 Where TargetInstance ISA 'Win32_Process'")
Do
	Set objProcess = colProcesses.NextEvent
	Select Case objProcess.TargetInstance.ProcessID
		Case intID1
			objWMIServiceWin32Process.Create strCmd1, null, null, intID1
		Case intID2
			objWMIServiceWin32Process.Create strCmd2, null, null, intID2
	End Select
Loop

My question is, can I have that loop run asynchronously so that I can run a bunch of other code in another loop.

Currently, I accomplish this by having two separate scripts and using Windows Task Scheduler to run them.
This set of code runs continually as fast as it can but the other code, I want it to run every 5 minutes.
I could accomplish this with a loop running every 5 minutes but I don't want to slow down this set of code.
I am just trying to combine the two scripts into one so I can lower the deployment overhead of this program.

Any suggestions?
Thanks!

 
Sure, you just need an event sink, e.g.

Code:
[blue]Dim EventFired
strCmd1="notepad.exe"
strCmd2="calc.exe"

Set objWMIServiceWin32Process = GetObject("WinMgmts:\\.\root\cimv2:Win32_Process")
objWMIServiceWin32Process.Create strCmd1, null, null, intID1
objWMIServiceWin32Process.Create strCmd2, null, null, intID2
	
Set objWMIServiceRoot = GetObject("WinMgmts:\\.\root\cimv2")
Set objSink = WScript.CreateObject("WbemScripting.SWbemSink","objSink_")

[green]' Async version[/green]
objWMIServiceRoot.ExecNotificationQueryAsync objSink, "Select * From __InstanceDeletionEvent within 1 Where TargetInstance ISA 'Win32_Process'"

[green]' This loop represents your code doing something else whilst waiting for events[/green]
Do Until EventFired
    WScript.Sleep 500
Loop

[green]' Event ...[/green]
Sub objSink_OnObjectReady(objLatestEvent, objWMIAsyncContext)
    Select Case objLatestEvent.TargetInstance.ProcessID
        Case intID1
            objWMIServiceWin32Process.Create strCmd1, null, null, intID1
            EventFired=true [green]' for puposes of this example, want script to terminate after event fires[/green]
        Case intID2
            objWMIServiceWin32Process.Create strCmd2, null, null, intID2
            EventFired=True [green]' for puposes of this example, want script to terminate after event fires[/green]
    End Select
End Sub [/blue]
 
Thanks for the code.
From looking this over and then trying it out real quick, I believe this allows it to run async, but it's only executed once.
I'm basically trying to execute two things at the same time and loop them forever.
One loops as fast as it can, the other loops every 5 minutes.

 
UPDATE:
Please disregard that last comment.
I had some typos when I adapted it to my application.
This code works exactly as I need.
You are the best, thank you.

 
Actually, now that I'm trying to put this into production, the script is dying.
Seems that the unprivileged user I'm running this script as dies at this statement:
Code:
objWMIServiceRoot.ExecNotificationQueryAsync objSink, "SELECT * FROM __InstanceDeletionEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_Process'"

Since I'm running this via Task Scheduler as an unprivileged user, I can only see that the process (wscript) is still running but I find out where it's stuck by placing the following at various parts of the file:
Code:
objFSO.CreateTextFile(strDirRoot & "HERE")

Using that technique I'm able to gather the following:
-2147217400
Invalid parameter

This works fine as an administrator

Any suggestions?

 
Suffice it to say that running my code as an unprivileged user from the scheduler works exactly as I'd expect (always remembering that, unless running as the logged in user, the task cannot interact with the desktop - which I think you already know). i.e. I can't replicate your issue, I'm afraid
 
Ok,
This is on a domain controller so looks like I'll have to start digging through Group Policy: "Local Policies/User Rights Assignment"
I had to add the user to: "Log on as a batch job" to get this to run initially.
I wonder if more is needed.

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top