Link to home
Start Free TrialLog in
Avatar of Member_2_1348041
Member_2_1348041Flag for Ireland

asked on

Synchronous Shell Shock Microsoft Word

heyhey

I've written a bit of code that launches a document with the appropriate app, using ShellExecuteEx

However, I want the code to wait until the user is finished with the document, after which it will check the document for changes and respond accordingly. Should be easy, right?

Well.

The code below works fine for many documents. If I launch a JPG with it, for example, it happily launches the associated program. Sits there. When I close it, it comes back to my proggy and happy days.

Not so with Microsoft Word. It launches happily. Sits there. And then when I close it, it closes the document, tries to close the Word Application. And waits. And Waits. And WAAAAAAAIIIIIITTTTTSSSSS.....

I checked, and when I go use a bit of code to iterates through all the processes to find the one associated with winword.exe, it finds one alright, but its pid is NOT the same as that returned in hProcess in SEI.

Now what?

help me. For the love of Science!


BTW - I found a number of places on t' web where people said they had similar problems, but nobody posted a solution.
Public Function SyncShellDoc(ByVal PathName As String, _
                             ByVal WindowStyle As VbAppWinStyle) As Long
 
Dim lngPid As Long
Dim lngExitCode As Long
 
Dim SEI As SHELLEXECUTEINFO
 
SEI.cbSize = Len(SEI)
SEI.fMask = SEE_MASK_NOCLOSEPROCESS
SEI.hwnd = GetDesktopWindow
SEI.lpVerb = "open"
SEI.lpFile = PathName
SEI.lpDirectory = vbNullChar
SEI.lpParameters = vbNullChar
SEI.nShow = WindowStyle
 
ShellExecuteEx SEI
 
lngPid = SEI.hProcess
             
    If lngPid <> 0 Then
        WaitForSingleObject lngPid, INFINITE
        If GetExitCodeProcess(lngPid, lngExitCode) <> 0 Then
            SyncShellDoc = lngExitCode
            CloseHandle lngPid
        Else
            CloseHandle lngPid
            Err.Raise &H8004AA00, "SyncShell", _
                      "Failed to retrieve exit code, error " _
                      & CStr(Err.LastDllError)
        End If
    Else
        Err.Raise &H8004AA02, "SyncShell", _
                  "Failed to Shell child process"
    End If
 
End Function

Open in new window

Avatar of Member_2_1348041
Member_2_1348041
Flag of Ireland image

ASKER

[tumbleweed]
[rain dance]
w00t!
Avatar of aikimark
1. What version of Word is this?  
2. Have you tried this code with other (prior) versions of Word?
3. Does this always happen or does this happen when there is already an open Word document or does not happen when there is an open Word document?
2003. It's the version we develop our code against, but it shouldn't matter.

It happens when no instance of WinWord.exe is running. I don't think it makes a difference if there isn't.
Earlier versions of Word used an MDI interface.  2003 and later used an SDI interface.  I asked this because I can think of a reason why you aren't seeing the process ID...Word is creating a new thread when it creates the new window.  You can see an example of this in your Task Manager window if you open two documents.  You will only see one process running, although there are two Word applications running.

You should be able to locate the process for the open document by searching the active tasks by name or just iterate them until you find the one with the document name as the title. (FindWindow API)

Unfortunately, this application behavior results in the inability of the WaitForSingleObject API to work as you wish it to (directly following ShellExecuteEx call.  I'm pretty sure you are going to search for the actual document window -- and even then that API might not be able to wait for a thread that is executing.


ASKER CERTIFIED SOLUTION
Avatar of aikimark
aikimark
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ok, it'll have to be Tuesday before I can give you that info. It's a bank holiday weekend here :-)
The problem has just resolved itself. Not in a technical manner, mind you.

The original remit: launch a program to modify a document, and when it's closed, process the document

New remit: keep a tally of documents open for modification and remind the user that they have some still checked out


Problem solved. We no longer need to keep track of whether the document is being modified. If the user stops, so be it. We still know they have the document "checked out", and until they "check in" the document we will consider it as being worked on. That way we no longer need to worry about whether the document is still open or not.
but thanks for your help all the same