|
-
Apr 17th, 2013, 10:28 AM
#1
Thread Starter
Hyperactive Member
[RESOLVED] VS 2012 Express: Check for Instance of App Before Running
I have just developed another one of those killer apps which is short and sweet but all the folks in the company are clamoring for it. So it's been deployed now company wide. There are several ladies using it who insist on running a new instance of it each time they need it. Never mind that four instances of it are already up and on their task bar, they need it so now they open a 5th instance of it.
Is there some way to check for an instance of the app and if one is found, refocus that one back onto the user's desktop in lieu of just opening up another instance. I just checked and another gal has 17 instances of it opened. No discipline or standards being exercised by this group...but you gotta love your users especially when they are the ones who bend the big bosses ear about the great apps I'm deploying for them.
-
Apr 17th, 2013, 10:38 AM
#2
Re: VS 2012 Express: Check for Instance of App Before Running
Get all the processes running by using Process.GetProcesses and check if you're process is in there in the Form_Load. If it is, set focus to it using the SetForegroundWindow and then close out the one that's loading:
Code:
Imports System.Runtime.InteropServices
Public Class Form1
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function FindWindow( _
ByVal lpClassName As String, _
ByVal lpWindowName As String) As IntPtr
End Function
<DllImport("user32.dll", EntryPoint:="FindWindow", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function FindWindowByClass( _
ByVal lpClassName As String, _
ByVal zero As IntPtr) As IntPtr
End Function
<DllImport("user32.dll", EntryPoint:="FindWindow", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function FindWindowByCaption( _
ByVal zero As IntPtr, _
ByVal lpWindowName As String) As IntPtr
End Function
<DllImport("user32.dll")> _
Private Shared Function SetForegroundWindow(ByVal hWnd As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
For Each pros As Process In Process.GetProcesses
If pros.ProcessName = "<name here>" Then
Dim theHandle As IntPtr = FindWindow(Nothing, pros.MainWindowTitle)
SetForegroundWindow(theHandle)
Me.Close()
End If
Next
End Sub
End Class
I haven't tested it, but this should work.
Last edited by dday9; Apr 17th, 2013 at 10:39 AM.
Reason: Added link for SetForegroundWindow
-
Apr 17th, 2013, 10:42 AM
#3
Re: VS 2012 Express: Check for Instance of App Before Running
You should be able to make the application as a single instance application in the projects properties.
kevin
Process control doesn't give you good quality, it gives you consistent quality.
Good quality comes from consistently doing the right things.
Vague general questions have vague general answers. A $100 donation is required for me to help you if you PM me asking for help. Instructions for donating to one of our local charities will be provided.
______________________________ Last edited by kebo : Now. Reason: superfluous typo's
-
Apr 17th, 2013, 10:44 AM
#4
Re: VS 2012 Express: Check for Instance of App Before Running
 Originally Posted by kebo
You should be able to make the application as a single instance application in the projects properties.
kevin
+1 I didn't know about that!
-
Apr 17th, 2013, 01:57 PM
#5
Thread Starter
Hyperactive Member
Re: VS 2012 Express: Check for Instance of App Before Running
I wasn't aware of that one either but from what I read in searches it will not bring up the existing instance which is already running on the users' desktops. The trouble with users is they don't stop to think about this kind of stuff. And the trouble with developing apps for users is that you have to think of this kind of stuff for them. I am examining the first reply to see if I can get that working. What I'm after is if the user clicks the icon to run the app and they already have it open, I want to close down the new instance and bring the existing instance up in front of them. Like a big giant button which says, "Click Here to Make Magic Happen".
Last edited by Vladamir; Apr 17th, 2013 at 02:17 PM.
-
Apr 17th, 2013, 02:03 PM
#6
Re: VS 2012 Express: Check for Instance of App Before Running
The argument of the StartupNextInstance handler has a switch to bring the first instance to the foreground. (e.BringToForeground)
http://msdn.microsoft.com/query/dev1...ROUND)&rd=true
And I totally agree with you about users. If they can do it you have to assume they will eventually.
kevin
Last edited by kebo; Apr 17th, 2013 at 07:01 PM.
Process control doesn't give you good quality, it gives you consistent quality.
Good quality comes from consistently doing the right things.
Vague general questions have vague general answers. A $100 donation is required for me to help you if you PM me asking for help. Instructions for donating to one of our local charities will be provided.
______________________________ Last edited by kebo : Now. Reason: superfluous typo's
-
Apr 17th, 2013, 02:20 PM
#7
Thread Starter
Hyperactive Member
Re: VS 2012 Express: Check for Instance of App Before Running
I'll check that one out next as well. But the proposal by dday9 worked slicker than snot on a doorknob. The users will never know what hit them. It is a silent assassin that was needed for this task. Now to just port the whole thing over from MS Access to MySQL so we can finally get rid of Access and it's notorious tendency to crash on a network.
Thanks everyone.
-
Apr 17th, 2013, 02:23 PM
#8
Re: VS 2012 Express: Check for Instance of App Before Running
 Originally Posted by Vladamir
I wasn't aware of that one either but from what I read in searches it will not bring up the existing instance which is already running on the users' desktops. The trouble with users is they don't stop to think about this kind of stuff. And the trouble with developing apps for users is that you have to think of this kind of stuff for them. I am examining the first reply to see if I can get that working. What I'm after is if the user clicks the icon to run the app and they already have it open, I want to close down the new instance and bring the existing instance up in front of them. Like a big giant button which says, "Click Here to Make Magic Happen".
See attached:
-
Apr 17th, 2013, 02:51 PM
#9
Thread Starter
Hyperactive Member
Re: [RESOLVED] VS 2012 Express: Check for Instance of App Before Running
dday9, thanks again. But I may have jumped the gun a bit. I thought this was working but I can see that it's actually still bringing up more than one instance of my app. So let me be sure about this one line of code:
Code:
If pros.ProcessName = "CallLog(06).exe" Then
When I check the task manager the actual name in the process list is
I tried using a mask CallLog* but that didn't work either. Is there something else that I'm missing...? I've been trying to trace this by stepping through it but the For Each loop seems to only execute once, and one point the variable pros.ProcessName = "explorer" but then away she goes into the main part of the program. I never see the processes all listed one by one in the watch window as I was anticipating.
UPDATE: I think what I'm finding is that this is not going to work. If there is no instance of the app running in the first place, it comes up only to find itself running, thus it kills itself and doesn't run at all. Still trying to figure this one out.
Last edited by Vladamir; Apr 17th, 2013 at 04:14 PM.
-
Apr 18th, 2013, 12:57 PM
#10
Re: [RESOLVED] VS 2012 Express: Check for Instance of App Before Running
Well, I've had a chance to test it out and I came up with this solution:
Code:
Option Strict On
Option Explicit On
Imports System.Runtime.InteropServices
Public Class Form1
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function FindWindow( _
ByVal lpClassName As String, _
ByVal lpWindowName As String) As IntPtr
End Function
<DllImport("user32.dll", EntryPoint:="FindWindow", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function FindWindowByClass( _
ByVal lpClassName As String, _
ByVal zero As IntPtr) As IntPtr
End Function
<DllImport("user32.dll", EntryPoint:="FindWindow", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function FindWindowByCaption( _
ByVal zero As IntPtr, _
ByVal lpWindowName As String) As IntPtr
End Function
<DllImport("user32.dll")> _
Private Shared Function SetForegroundWindow(ByVal hWnd As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'Gets the current process(this application)
Dim myprocess As Process = Process.GetCurrentProcess
'Iterate through each process that's running
For Each pros As Process In Process.GetProcesses
'Check if the process in cue has the same name, but not the same unique ID
If pros.ProcessName = myprocess.ProcessName AndAlso pros.Id <> myprocess.Id Then
'If there's a match, set focus to that instance of the application
Dim theHandle As IntPtr = FindWindow(Nothing, pros.MainWindowTitle)
SetForegroundWindow(theHandle)
'Close this one
Me.Close()
End If
Next
End Sub
End Class
I put comments in the form_load so that you understand what I'm doing.
-
Apr 18th, 2013, 01:01 PM
#11
Re: [RESOLVED] VS 2012 Express: Check for Instance of App Before Running
You could also, instead of doing an exact EQUALS() check, you could do a StartsWith() instead (I'd also lowercase everything), just in case. That is, of course, if the call still isn't working. However, using the built in "Single Instance Application" option, and then tweaking the startup event that was suggested earlier is actually much simpler to do. However, to each their own!
-
Apr 18th, 2013, 01:57 PM
#12
Thread Starter
Hyperactive Member
Re: [RESOLVED] VS 2012 Express: Check for Instance of App Before Running
Thanks again to all for the replies. This is starting to gel, almost. And again here is the situation I'm up against.
Making this a single instance application is what this code above achieves...in a sense. That is it will only let the one instance be on the desktop, but these gals, and most of the users are women, open the app, then minimize it to their taskbar. And when I tested this I found it does keep a second instance from running but the app remains minimized on their taskbar. I just haven't been doing this kind of programming enough to know who to refocus it back up in it's previous state on the desktop. That's what we're after. However, this does at least give me some more insight into how one would accomplish this.
I'd like to just tie the users hands together and tell them to stop launching so many instances...but I might as well be talking to the walls.
-
Apr 18th, 2013, 01:59 PM
#13
Re: [RESOLVED] VS 2012 Express: Check for Instance of App Before Running
just curious... have you tried setting the Single Instance bit?
Process control doesn't give you good quality, it gives you consistent quality.
Good quality comes from consistently doing the right things.
Vague general questions have vague general answers. A $100 donation is required for me to help you if you PM me asking for help. Instructions for donating to one of our local charities will be provided.
______________________________ Last edited by kebo : Now. Reason: superfluous typo's
-
Apr 18th, 2013, 02:01 PM
#14
Re: [RESOLVED] VS 2012 Express: Check for Instance of App Before Running
The SetForegroundWindow should make that instance be un minimized. That's not working for you?
-
Apr 18th, 2013, 02:22 PM
#15
Thread Starter
Hyperactive Member
Re: [RESOLVED] VS 2012 Express: Check for Instance of App Before Running
 Originally Posted by dday9
The SetForegroundWindow should make that instance be un minimized. That's not working for you?
Yes, I'm sad to report that I tested before I took it to this woman who insists on opening up a multiple instances (and wow is she ever a fox!) Anyway, I compile the new code and then copy the exe file to the distro location for my apps on the server. I create a shortcut which points to this exe file and then launch it. The app comes up and I minimize it, the way she is going to do with it. Then I click on shortcut icon again, just like she is going to do. There is no second instance created but the icon on the task bar remains there. The window for the app does not return to the desktop.
And to make matters worse...or better... I commented out all the code above and simply checked the Make single instance application...and that did the trick. Actually, it worked with your code in it too but not until I checked Make single instance application. I went back and rechecked this and that is all it takes to keep these users from launching the darn thing 10 to 12 times in each day. I just checked one of the other users in Customer Service and she had it opened 9 times on her task bar. I cautioned them to simply reuse the one they already have running but like I said, that's like talking to the walls. This fix should take care of that issue.
I wasn't aware that this switch behaved this way. I learned something new again today....so it's been worth it. And many thanks to you and kebo for the advice.
Last edited by Vladamir; Apr 18th, 2013 at 02:34 PM.
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
|