×
INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!
  • Students Click Here

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here

Jobs

How reliable is WSH AppActivate()? I'm looking for experience and/or people willing to experiment...

How reliable is WSH AppActivate()? I'm looking for experience and/or people willing to experiment...

How reliable is WSH AppActivate()? I'm looking for experience and/or people willing to experiment...

(OP)
We all know and use methods to prevent double starts. I maintain an application that already implmented the usual FindWindow/SetForeGroundWindows method.

A customer's suspicion is, this still doesn't work. I found a possible flaw in the logic, and while I am at rewriting this I remembered WMI queries fro win32_process can also show you whether a process of an exe runs in a separate Windows session.

So my new code works on that basis and I end up with a ProcessIds instead of Hwnd. And I found an easy way to activate a process by that instead of SetForeGroundWindow via this:

CODE

oWSSH = CreateObject("WScript.Shell")
oWSSH.AppActivate(Processid) 

My first tests are all successful, but here's the thing I can't explain: The result value of the AppActivate() call should tell, whether the activation succeeded. But mostly it returns .F., even when the app activation does work.

OK, that's lamenting over a detail, which isn't really a problem, as long as it works it's totally sufficient, but I ask myself: "how reliable is it?"
Does anybody already use WScript.Shell AppActivate? Or are you willing to experiment with it and see whether it works reliable for you, too?

You don't even need any more code to find out a process ID, if you experiment with several Foxpro sessions started one can activate the other once you know the _vfp.processid of the session you want to activate. I'd also be interested in whether this works on WinXP,7 and 8, too.

Bye, Olaf.

Olaf Doschke Software Engineering
https://www.doschke.name

RE: How reliable is WSH AppActivate()? I'm looking for experience and/or people willing to experiment...

Olaf,

I have only ever used oWSSH.AppActivate by passing the name of the application to be activated, rather than the process ID. I have found that it works reliably, but it is often necessary to insert a delay of a few hundred milliseconds between instantiating "WScript.Shell" (or launching an app with oWSSH.Run) and invoking oWSSH.AppActivate.

I don't know any way of determining if the activation is successful, other than the usual FindWindow method, which takes you back to where you started.

I've done this mainly with VFP 9 under Windows XP. When I get a moment, I'll experiment with Windows 7.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads

RE: How reliable is WSH AppActivate()? I'm looking for experience and/or people willing to experiment...

(OP)
Thanks, Mike!

The timing is the lesser problem, but it's a good idea to start-up WScript.Shell proactively even when it's later not used to activate an already running process.

The reason the ProcessId is a better qualifier for me is how WMI enables us to see processes across several Windows sessions. I do these two WMI queries:

CODE

Select ProcessId, SessionId, CreationDate, Name From Win32_Process where ProcessId = <<_vfp.ProcessId>>
Select ProcessId, SessionId, CreationDate From Win32_process where Name='<<the name from the first query>' And ProcessId <> <<_vfp.ProcessId>> 

If a process is found in another SessionId the user gets a notice to change Windows sessions and I quit.

And in the case of a double start in the same Windows session, I get an overview of the own process and what I'd call sibling processes. Usually only one, obviously, once that mechanism is established, but I can decide a winner by earliest CreationDate, which WMI gives with microsecond precision.

In case I switch, I would like to be sure that activation worked. Otherwise, it would seem to the user the software broke and instead it's just a case of a minimized process not maximizing again, for example. Or whatever else doesn't work.

Another reason I'd like to work on the principle of ProcessIds is, they are the earliest handle I can think of. In a startup time of the runtime, there may be no Window handle, judging already running processes by any action the main.prg start code does is already later than that, no matter if you open some file exclusive or create a semaphore.

So testing efforts are welcome. If that turns out nice, I'd judge it as a very stable and unbeatable mechanism, unless someone tells me WMI might only see a process "long" (=a few microseconds) after it was created. But I'll test that, too, intentionally starting an EXE 2 or more times.

Bye, Olaf.

Olaf Doschke Software Engineering
https://www.doschke.name

RE: How reliable is WSH AppActivate()? I'm looking for experience and/or people willing to experiment...

(OP)
I think I found out the circumstances when oWSSH.AppActivate(Processid) returns .f.

1. The documentation of AppActivate says the value is false when the activated process can't get focus, meaning SetFocus() to the main window doesn't work
2. I got this when I start an old VFP process which I kept open for hours or even from last day.

I assume it works more reliable when the already running process is active or - as in the critical case I want to prevent - also just started.

And my tests about multiple starts all ran well, only one process remains. With one exception. After several tests one of the starts judged foxuser.dbf as corrupt ans asked whether I want to overwrite it with a new resource file. And since that happens before main.prg it's a process that stayed open, too, it never started the routine to find out it's a secondary sibling process.

But the solution for that is obvious, I include a config.fpw with RESOURCE=OFF, so that dbf never is in the way.

I'd still like to hear how that works in Win8, Win7 or XP.

Bye, Olaf.

Olaf Doschke Software Engineering
https://www.doschke.name

RE: How reliable is WSH AppActivate()? I'm looking for experience and/or people willing to experiment...

Hello Olaf,

we have several customers where WSH is deactivated by admins, so I think this code will not work.

I remembered an old wiki entry showing different ways to ensure only one instance, see
http://fox.wikis.com/wc.dll?Wiki~ControllingTheNum...

Best regards
tom

RE: How reliable is WSH AppActivate()? I'm looking for experience and/or people willing to experiment...

(OP)
Thanks, Tom, for the concern.

I thought of that, but
1. In my case, that's under my control. The software is the major deal on the workstations of the users and the system will be adapted as necessary.
2. I don't RUN /N wscript scriptname of JS or VBS scripts.
3. I remember this discussion, WScript.Shell isn't WSH, it's a COM Helper object. Like other things, eg Scripting.FilesystemObject, it works independently of settings.
4. I'm well aware of other solutions, but nothing in the Fox Wikis shows processes in further Windows sessions!

I just checked once more, whether turning off WSH influences Wscript.Shell usage. It only disables running JS or VBS script files, but nothing more, nothing less, Wscript.Shell doesn't get disabled. What you also can't do is use Wscript.Shell.Run() to run vbs scripts. So the security aspect isn't undermined, too.

Bye, Olaf.

Olaf Doschke Software Engineering
https://www.doschke.name

RE: How reliable is WSH AppActivate()? I'm looking for experience and/or people willing to experiment...

(OP)
Also note: You can use WMI to make the WMI queries with a normal account. I found out, that you need an elevated process to get at some win32_process properties, eg the ExecutablePath is NULL for processes of another SessionId, but you can give your EXE a very specific name with which it appears in the win32_process.name property.

Besides, you can combine that, look for a semaphore or mutex, but everything you do is after process entry already exists. You can CreateMutex() and CreateSemaphore(), but that needs at least one DECLARE and a call while you only need to be the same EXE name and nothing else to be seen by a process list query. Semaphore/Mutex can be a valid add on in case you don't trust another process by name just being sabotage to hinder your EXE from running. Users will look for yourapp.exe in the Task Manager, find and kill it, though. So that's not a very clever attack.

Even though you and only you know what further Semaphore or Mutex identifies a sibling process, it's not there in the first split second. You can check whether CraationDate of another process is old enough, so you can be sure this unique identifier is established by the other process before you look for it. I don't know, though, whether Semaphore/Mutex is per system or per session. Yes, those are the things you only need to worry about for split seconds, but that is my concern about the corner case of starting an EXE twice directly and the other corner case is - in my case - only allowing an app to run in one session.

Sure, in many cases you want to be able to start in multiple sessions, ie when the computer is a terminal server you want to enable that app to run once per session. Then simply only query for processes in the same SessionId.

The only thing I don't figure out is why a long-running VFP session actually activates with Wscript.Shell.AppActivate(), but that still returns .F. I looked into how complex a VFP9.EXE process actually is windows wise. Even when you close all windows except _SCREEN you have already a lot of windows handles of some hidden windows, some for IME (Japanese keyboard input), that always exist. I assume the complex windows structure makes AppActivate fail in the aspect of putting the keyboard focus to the VFP IDE. But it does get it anyway. It's most likely nothing to worry about when you only need this to work for the _SCREEN of a compiled VFP project, not VFP itself.

Bye, Olaf.

Olaf Doschke Software Engineering
https://www.doschke.name

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members! Already a Member? Login

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close