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

ShellExecuteEx() in FoxPro (I need find out, when file is closed)

Status
Not open for further replies.

Moleek

Programmer
Aug 11, 2013
4
Hello everyone.
My situation is, that I need to open external file (Doc, TXT, PDF or whatever), which is not a problem, but I need to find out, when this file is closed (because I need write it back to the database when work is done). I tried run it with ShellExecute(), but I was able check windows status only with it's exact title, which I don't know every time.
I think ShellExecuteEx() should return codenumber (handle) of process. Knowing this number it should be easy to find out if this process is still running or not.
I'm able to find structure ShellExecuteINFO in C++, but I can't transform it to VFP.
Is there someone who could help me please?
Thank you.
Martin.
This is it:
Code:
typedef struct _SHELLEXECUTEINFO {
  DWORD     cbSize;
  ULONG     fMask;
  HWND      hwnd;
  LPCTSTR   lpVerb;
  LPCTSTR   lpFile;
  LPCTSTR   lpParameters;
  LPCTSTR   lpDirectory;
  int       nShow;
  HINSTANCE hInstApp;
  LPVOID    lpIDList;
  LPCTSTR   lpClass;
  HKEY      hkeyClass;
  DWORD     dwHotKey;
  union {
    HANDLE hIcon;
    HANDLE hMonitor;
  } DUMMYUNIONNAME;
  HANDLE    hProcess;
} SHELLEXECUTEINFO, *LPSHELLEXECUTEINFO;
 
Googling "VFP ShellExecuteEx" gives all the results you need.

1.
In general you create a sting with the C structure length and fill in the single properties at their positions binary. BINTOC helps a lot. news2news has developed their own simple conversion functions, before BINTOC was extended in VFP9. You pass this struct string in by reference and can extract the hProcess handle from it as the last four bytes.

2. an example

(scroll down to the "LaunchExeAndWait" code)

3. an alternative Wscript.Shell Run
(setting the third parameter of Wscript.Shell's Run to .T. means to wait for completion before continuing)

Bye, Olaf.
 
By the way:

If you shellexecuteex a file like DOC(X), XLS(X), as with shellexecute the associated application is started in the first place. It opens the file specified in the second place. You will get a process handle of that application, not of the file. You will wait for application to close, not for the file.

What can happen is, Word is opened to open a DOC, the user saves and closes the DOC, but your application still waits for word to quit.

You could wait more easy for a file by trying to FOPEN() the file yourself exclusive. Just wait a few seconds after ShellExecute or ShellExecuteEx, so you can be sure the app works on the file, then try to open the file exclusive and continue, if you can open it, otherwise loop and wait.

Bye, Olaf.
 
Thank you for your tips and advices.
OlafDoschke said:
You could wait more easy for a file by trying to FOPEN() the file yourself exclusive. Just wait a few seconds after ShellExecute or ShellExecuteEx, so you can be sure the app works on the file, then try to open the file exclusive and continue, if you can open it, otherwise loop and wait.
I agree with this soulution. It's simple and strong, but ufortunately we find out that it doesn't work 100%. For example some TXT files could be opened exclusively by FOPEN even if they are already open by notepad.

Unfortunately this example in VFP ( is in area for members, which I'm not.
 
Yes, notepad is an editor just reading a file, then closing it again. You edit the loaded text in RAM. So the FOPEN would never indicate the editor is done. But then you can save your edit into another file and if you wait for notepad to close you still don't have the edited file. So you depend on the cooperation of the user really changing the file you want to store in it's new revision.

You could MODIFY FILE ...txt instead of starting notpad in case of TXT.

You can still wait for the application to finish. You don't need the news2news sample, I gave you a LaunchExeAndWait sample reference.

Bye, Olaf.
 
Hello Martin, and welcome to the forum.

What exactly do you expect your calling program to be doing while you are waiting for the called program to close. Should it carry on running asynchronously, and then be interrupted when the file is closed? Or do you want it to be suspended, and to kick back into life when the file is closed?

If the latter, here's one way of achieving that:

Code:
oWsh = CREATEOBJECT("wscript.shell")
oWsh.Run("SomeProgram.EXE, 3, .T.)

This will run the specified EXE in much the same way as ShellExecute(), except that it will run it synchronously. In other words, your VFP program will suspend as long as the called EXE is running. It will resume when the called program terminates.

If this isn't what you want, then just ignore it. But, if it is, then it would seem a simple solution to consider.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Hello.
Calling program doesn't wait at all. In short: There is form with list of available files and button to open file with it's associated program. And I need open some (even more) files and work with all of them (including parental VFP program). And I think I need to know handle of process to periodically check if the process is still running or it's terminated already. When it's terminated I can update information about file in database.
I know about 3 possibilities of opening file:
1) CreateProcess - I can't use it because I need to know which program I want to run (And I don't know what software user uses)
2) ShellExecute - It runs associated program which is great, but don't return handle of process.
3) ShellExecuteEx - It seems that is ideal for my purpose, but I don't exactly know to give him required parameters. Probably through structure ShellExecuteInfo, but I don't know how to fill it.

Thank you
 
Again, there is code you can copy from

And Mike and me pointed to WSH. It does wait, if the third parameter of the Run call is .T., but you can't do anything else in your app then. Therefore I also would go the ShellExecuteEx route.
Please tell us, why you can't get the LaunchExeAndWait code to run, what are your detail problems?

Bye, Olaf.
 
> CreateProcess - I can't use it because I need to know which program I want to run (And I don't know what software user uses)
I see now LaunchExeAndWait uses CreateProcess and not ShellExecuteEx, though I didn't searched CreateProcess.

Well, there is a solution to that, see
WSH can also give you the processid (not handle) and you can exchange that to the hProcess handle with OpenProcess.

But determining the associated exe and then using CreateProcess seems easier to me, if you don't like the synchronous solution with WSH.Run

Bye, Olaf.
 
For years my work had used ShellExecute, but recently has started using WinAPI CreateProcess as a preferred method to give us better control or more options or both. Though I've only been a user, not one of the coders.

 
Hello.
I was away for couple of days, so I didn't react, but good news everyone:
Code:
"But determining the associated exe and then using CreateProcess seems easier to me"
This was exactly what solved my problem after all. I admit I was stuck with my idea of ShelLExecuteEx but this is easier and works good.
So I want thank you all for your time and your ideas.
Martin.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top