Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 450
  • Last Modified:

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

0
WernerVonBraun
Asked:
WernerVonBraun
  • 7
  • 3
1 Solution
 
WernerVonBraunAuthor Commented:
[tumbleweed]
0
 
WernerVonBraunAuthor Commented:
[rain dance]
0
 
WernerVonBraunAuthor Commented:
w00t!
0
Free learning courses: Active Directory Deep Dive

Get a firm grasp on your IT environment when you learn Active Directory best practices with Veeam! Watch all, or choose any amount, of this three-part webinar series to improve your skills. From the basics to virtualization and backup, we got you covered.

 
aikimarkCommented:
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?
0
 
WernerVonBraunAuthor Commented:
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.
0
 
aikimarkCommented:
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.


0
 
aikimarkCommented:
One more question:
4. what is the value of lngPid that you are passing?
I ask this question(4) because sometimes SEI.hProcess is Null (0).

some related references:
http://www.experts-exchange.com/Q_23474058.html
http://www.eggheadcafe.com/software/aspnet/34399713/how-to-wait-for-shellexec.aspx

0
 
WernerVonBraunAuthor Commented:
ok, it'll have to be Tuesday before I can give you that info. It's a bank holiday weekend here :-)
0
 
WernerVonBraunAuthor Commented:
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.
0
 
WernerVonBraunAuthor Commented:
but thanks for your help all the same
0

Featured Post

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

  • 7
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now