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 SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to wait on results from a Shell function? 2

Status
Not open for further replies.

dupe

Technical User
Feb 16, 2001
1
0
0
US
I want to run a perl script from a form button, then run a query based on the results of the perl script. Currently, the only way I have successfully done this is to use two buttons. One, to run the perl script (using the Shell function). And the second, to run the query. I really would like to use only one button. But, I can't find a way to suspend execution of the query until the perl script has completed.

Any help would be appreciated.
 
Hi!

I've run into the a similar challenge once. My solution is a bit dirty, but it works. I made the script perform some kind of action that could be verified thru Access/VBA, for instance create a file in a specific location etc, and then check for it before continuing. Another way is to specify some "waiting time", but that could be dangerous;-)

Good luck, Roy-Vidar

 
Here is some code that will pause the execution for a given length of time:

Private Declare Sub sapiSleep Lib "kernel32" _
Alias "Sleep" _
(ByVal dwMilliseconds As Long)

Sub sSleep(lngMilliSec As Long)
If lngMilliSec > 0 Then
Call sapiSleep(lngMilliSec)
End If
End Sub

paste this into a module, then in your code call the function sSleep with the number of milliseconds you want it to pause: i.e.

Call sSleep(1000)

this will pause the code for 1 second.

Mike Rohde
rohdem@marshallengines.com
 
Hi,

there is in my opinion a safer way: just to wait until the shell has executed whatever it meant to: You'll need a call to kernel32 to do this:

just declare:

Private Const NORMAL_PRIORITY_CLASS = &H20&

Private Declare Function CreateProcessA Lib "kernel32" (ByVal _
lpApplicationName As Long, ByVal lpCommandLine As String, ByVal _
lpProcessAttributes As Long, ByVal lpThreadAttributes As Long, _
ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, _
ByVal lpEnvironment As Long, ByVal lpCurrentDirectory As Long, _
lpStartupInfo As STARTUPINFO, lpProcessInformation As _
PROCESS_INFORMATION) As Long

Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal _
hHandle As Long, ByVal dwMilliseconds As Long) As Long

Private Declare Function CloseHandle Lib "kernel32" (ByVal _
hObject As Long) As Long


THen write a function that replaces the shell command:

Public Sub ExecCmd(cmdline$)
Dim proc As PROCESS_INFORMATION
Dim start As STARTUPINFO
Dim ReturnValue As Integer

' Initialize the STARTUPINFO structure:
start.cb = Len(start)

' Start the shelled application:
ReturnValue = CreateProcessA(0&, cmdline$, 0&, 0&, 1&, _
NORMAL_PRIORITY_CLASS, 0&, 0&, start, proc)

' Wait for the shelled application to finish:
Do
ReturnValue = WaitForSingleObject(proc.hProcess, 0)
DoEvents
Loop Until ReturnValue <> 258

ReturnValue = CloseHandle(proc.hProcess)

End Sub
 
Hi,

I don't know anything about perl but if you use the Shell command in Access to execute your perl script, you might find this webpage of some help. It helped me when I ran into a similar problem, except I was running a simple batch file. ;P

here's the link.

 
I'd be interested in what everyone thinks about this solution. It's similar to the one that nyx uses, but avoids having to associate a Process ID with a Process Handle. Basically, we keep activating the new process until we can't activate it any more. This returns an error which tells allows the ShellAndWait procedure to continue.

Also, Microsoft mentions a possible solution at:
This makes use of the Tasks collection, but I was unable to find a reference for this collection. Can anyone shed some light on this?

The procedures:

Public Function ShellAndWait(PathName As String)

Dim TaskID As Double

'Run application and return Process ID (TaskID)
TaskID = Shell(PathName, vbNormalFocus)

While TaskExists(TaskID)
'Wait for TaskExists False
Wend

End Sub


Public Function TaskExists(TaskID As Double) As Boolean

'Raise Error if TaskID does not exist
On Error GoTo ErrorHandler

'Attempt to activate TaskID
AppActivate (TaskID)

'If AppActivate returns an error, we know that the
'process is finished. We handle the error and return
'the function as false--this allows the calling
'procedure to exit the While loop.

ErrorHandler: If Err.Number = 5 Then
TaskExists = False
Exit Function
Else
TaskExists = True
End If

End Function
 
Used the process described by CUPBURN, works well (also documented on the Microsoft web site).

The difficulty I am having with this is that I want to start a process (shell to it, invoke it or whatever you want to call it) on a server attached to the network from a workstation. This process works great when the Access process is on my workstation and the process being shelled to is also running local on the workstation, but I cannot seem to get it to start a process on another CPU. Right now I am trying to do this at home from my Access desktop app to my laptop which is networked.

Does anyone know if this is possible ?

Thanks
Paul
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top