|
-
Mar 5th, 2007, 08:20 AM
#1
Thread Starter
New Member
WaitForSingleObject Help?
I have written a small app in VB6 that copies a Microsoft Access database application to the local C drive and runs it. It then uses WaitForSingleObject to halt program execution until the user exits the Access database then it deletes the temporary copy of the Access DB from the C drive.
Unfortunately the WaitForSingleObject call also seems to prevent the user from opening other Office documents.
Does anyone know a way to fix this?
Cheers.
-
Mar 5th, 2007, 10:37 AM
#2
Re: WaitForSingleObject Help?
 Originally Posted by btonkinson
Unfortunately the WaitForSingleObject call also seems to prevent the user from opening other Office documents.
Welcome to the forums. 
What happens when they attempt to open these documents?
Is it across the board for all Office products (Word, Excel, etc) or does it only affect one?
-
Mar 5th, 2007, 10:56 AM
#3
Thread Starter
New Member
Re: WaitForSingleObject Help?
Hi thanks
It doesn't appear to effect text files that open in notepad but it does effect Excel and Word files. Furthermore I have realised that they do open it just takes a very, very long time.
If during this time I end the loader.exe task the Excel / Word file opens immediatly.
Think it is related to this problem: "Use caution when calling the wait functions and code that directly or indirectly creates windows. If a thread creates any windows, it must process messages. Message broadcasts are sent to all windows in the system. A thread that uses a wait function with no time-out interval may cause the system to become deadlocked." - quoted from:
http://msdn2.microsoft.com/en-us/library/ms687032.aspx
Brian
-
Mar 5th, 2007, 12:01 PM
#4
Re: WaitForSingleObject Help?
 Originally Posted by btonkinson
Think it is related to this problem: "Use caution when calling the wait functions and code that directly or indirectly creates windows. If a thread creates any windows, it must process messages. Message broadcasts are sent to all windows in the system. A thread that uses a wait function with no time-out interval may cause the system to become deadlocked."
And this is exactly what sounds like is happening.
Since this is in VB6, perhaps tossing a DoEvents into your code to let your OS do some processing would help.
-
Mar 6th, 2007, 04:07 AM
#5
Thread Starter
New Member
Re: WaitForSingleObject Help?
Where would you suggest I put the doEvents command?
Code:
Public Sub ShellAndWait(ByVal program_name As String, ByVal window_style As VbAppWinStyle)
Dim process_id As Long
Dim process_handle As Long
' Start the program.
On Error GoTo ShellError
process_id = Shell(program_name, window_style)
On Error GoTo 0
DoEvents
' Wait for the program to finish.
' Get the process handle.
process_handle = OpenProcess(SYNCHRONIZE, 0, process_id)
If process_handle <> 0 Then
WaitForSingleObject process_handle, INFINITE
CloseHandle process_handle
End If
Exit Sub
If I put it in before WaitForSingleObject process_handle, INFINITE then won't it only process events before the wait period and equally after it only events after it has stopped waiting?
I am happy to look at other ways of halting program execution until the started app has been closed if you know of any?
Thanks for your help.
-
Mar 6th, 2007, 04:32 AM
#6
Re: WaitForSingleObject Help?
Don't know if this little snippet will give you an idea. It's part of a registry monitoring routine, but demonstrates how you can use WaitForSingleObject in combination with DoEvents in a While-Wend loop. You can just Exit Sub to get out of the loop. Although TaskManager shows 100% CPU usage, neither the app, other progs nor the PC freeze or seem to slow down. It's quite efficient for all that.
Code:
'Watch a registry change by looking at KeyChanged.
While DoEvents
KeyChanged = WaitForSingleObject(hEvent, TimeOutInterval) = WAIT_OBJECT_0 'Cast the initial value.
If KeyChanged = True Then 'Start watching for changes.
RegNotifyChangeKeyValue hkey, WatchSubTree, REG_NOTIFY_CHANGE_LAST_SET, hEvent, True
With frmRegMon.txtMsgs
'The key has already been checked for errors.
NewValue = GetDataAsString(hKeyType, strSubKey, strKeyName, "New")
If NewValue <> OldValue Then 'Test for a change.
'Dump the results to the text box.
.Text = .Text & vbCrLf & "Key change detected at " & Time$ & "."
.Text = .Text & vbCrLf & "Old Value = " & OldValue
.Text = .Text & vbCrLf & "New Value = " & NewValue
Else
.Text = .Text & vbCrLf & "A change was detected in another key's value"
End If
OldValue = NewValue 'Reset the initial value to test.
End With
End If
Wend
Edit: Const WAIT_OBJECT_0 = 0
Last edited by schoolbusdriver; Mar 6th, 2007 at 04:38 AM.
-
Mar 6th, 2007, 05:59 AM
#7
Thread Starter
New Member
Re: WaitForSingleObject Help?
Thanks schoolbusdriver - that gave me a bit of inspiration. I have come up with this which seems to solve the problem:
Code:
Public Sub ShellAndWait(ByVal program_name As String, ByVal window_style As VbAppWinStyle)
Dim process_id As Long
Dim process_handle As Long
Dim procState As Long
Dim counter As Long
' Start the program.
On Error GoTo ShellError
process_id = Shell(program_name, window_style)
On Error GoTo 0
DoEvents
' Wait for the program to finish.
' Get the process handle.
process_handle = OpenProcess(SYNCHRONIZE, 0, process_id)
If process_handle <> 0 Then
procState = 258
counter = 0
While procState = 258
If counter = 10000 Then
' Only check procState every 10,000 runs - saves on hogging CPU
procState = WaitForSingleObject(process_handle, 1)
counter = 0
Else
counter = counter + 1
End If
DoEvents
Wend
CloseHandle process_handle
End If
Exit Sub
ShellError:
MsgBox "Error starting task " & _
program_name & vbCrLf & _
Err.Description, vbOKOnly Or vbExclamation, _
"Error" & Err.Number
End Sub
However This is still showing as 100% CPU usage on task manager (due to the counting in the loop). Any ideas? I really want this program to just sit in the background and do nothing until the SHELLed app finishes.
-
Mar 6th, 2007, 07:25 AM
#8
Re: WaitForSingleObject Help?
The usual way to reduce processor usage is to introduce a "Sleep" into the loop. You can do this just before the Wend, ie "Sleep 250" (milliseconds). You may want to change the counter from 10000 as well. Somewhere along the line you should get a happy balance.
There has been some discussion of other various ways to reduce CPU time etc. Take a look at http://www.vbforums.com/showthread.p...light=doevents. Take care if you run the code I posted - if you run it via the IDE, it doesn't exit correctly. However when it's compiled, it seems to work fine.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|