|
| ? Ensuring an application is SINGLE INSTANCE ? |
|
|
|
|
| Messages |
|
Related Types |
This message was discovered on microsoft.public.dotnet.academic.
Responses highlighted in red are from those people who are likely to be able to contribute good, authoratitive information to this discussion. They include Microsoft employees, MVP's and others who IMHO contribute well to these kinds of discussions.
| Steven Van Dyke |
How do I prevent multiple instances of my app from being started?
Steve
|
|
|
| |
|
| |
| |
| Willy Denoyette (VIP) |
Use a named Mutex in your Main function to guard against multiple execution is one possibility. .... Mutex mutex = new Mutex(false, "Thisshouldonlyrunonce"); bool Running = !mutex.WaitOne(0, false); if (Running) // exit program, or ....
Willy.
"Steven Van Dyke" <Click here to reveal e-mail address> wrote in message news:e4okoqMmBHA.1600@tkmsftngp07... [Original message clipped]
|
|
|
| |
|
|
| |
| |
| Steven Van Dyke |
Thanks so much, that worked perfectly to prevent my second instance from running.
One other problem....
My app can take a command line argument. Is there a way to get that argument to my first instance before closing my second instance?
Thank so much!
Steve
"Willy Denoyette" <Click here to reveal e-mail address> wrote in message news:#JUIg6OmBHA.1544@tkmsftngp03... > Use a named Mutex in your Main function to guard against multiple execution is one possibility. [Original message clipped]
|
|
|
| |
|
|
| |
| |
| Willy Denoyette (VIP) |
There are several way's to skin a cat :-), here is one:
using System.Management;
.... //Replace xxxx with the name of the executable image. ManagementObjectSearcher query = new ManagementObjectSearcher ("SELECT * FROM Win32_Process WHERE Name='xxxxx.EXE'"); ManagementObjectCollection queryCollection = query.Get(); foreach( ManagementObject mo in queryCollection ) { Console.WriteLine( "PID [ {0} ] started '{1}' With commandline - '{2}'", mo["ProcessID"].ToString(),mo["CreationDate"].ToString(), mo["CommandLine"].ToString() ); } ....
TODO: You will need to convert the CIM date to DateTime format in order to select the 'first' program. Parse the commandline.
Hope this helps.
Willy.
"Steven Van Dyke" <Click here to reveal e-mail address> wrote in message news:#ux6UEPmBHA.1852@tkmsftngp07... [Original message clipped]
|
|
|
| |
|
|
| |
| |
| Thomas Tomiczek \(MVP\) (VIP) |
Folks,
thanks for these solutions - never seen two being THAT complicated, really. Not at all dotNET related and pure, right?
Here is the right and framework internal one - check for a Process with your name.
Like here:
Process [] processes = Process.GetProcessesByName ("Your program name goes here");
if (processes.Length != 1) {
return;
}
Have fun :)
Oh, I got this from the manual and some support at the dotnet mailing list a while ago.
-- Thomas Tomiczek THONA Consulting Ltd. (Microsoft MVP C#/.NET)
"Willy Denoyette" <Click here to reveal e-mail address> wrote in message news:uNiRP0PmBHA.2752@tkmsftngp02... [Original message clipped]
|
|
|
| |
|
|
| |
| |
| Willy Denoyette (VIP) |
Thomas, Some remarks. 1. The posters question is 'How can I retrieve the commandline arguments of the others instance"? I fail to see how your solution returns the commandline arguments. 2. Your simple solution returns a friendly process name, which is truncated to 15 characters, so it is not guaranteed to be unique. 3. I also fail to see what's not pure and .NET related whan using the Management namespace classes.
Willy.
"Thomas Tomiczek (MVP)" <Click here to reveal e-mail address> wrote in message news:3c3ed8c0$Click here to reveal e-mail address... [Original message clipped]
|
|
|
| |
|
|
| |
| |
| Willy Denoyette (VIP) |
Correction, Point 2 seems to be resolved in RC1 and up.
Sorry for that,
Willy. "Willy Denoyette" <Click here to reveal e-mail address> wrote in message news:OJXv$atmBHA.1640@tkmsftngp05... [Original message clipped]
|
|
|
| |
|
|
| |
|
| |
| [MVP] Thomas Tomiczek (VIP) |
Just to Point 3 -
you assume that WMI is available, which might not be the case "later on" on other platforms, while I referred to core classes :-)
Regards
-- Thomas Tomiczek THONA Consulting Ltd. (Microsoft MVP C#/.NET)
"Willy Denoyette" <Click here to reveal e-mail address> wrote in message news:OJXv$atmBHA.1640@tkmsftngp05... [Original message clipped]
|
|
|
| |
|
|
| |
| |
| Willy Denoyette [MVP] (VIP) |
Management classes are also core classes, they simply wrap something which is now called WMI, it's possible WMI will be re-engineered using a managed provider, but that's an implementation detail. WMI is available on ME, W2K, XP and is meant to be available on all up-coming MSFT platforms.
Windows .NET even includes a brand new .NET namespace with a lot of goodies like High performance counters and registration information. I know some ISV's and Computer Manufacturers who are building Enterprise management frameworks using .NET Management classes.
Willy.
"[MVP] Thomas Tomiczek" <Click here to reveal e-mail address> wrote in message news:3c53d2ce$Click here to reveal e-mail address... [Original message clipped]
|
|
|
| |
|
|
| |
| |
| [MVP] Thomas Tomiczek (VIP) |
Well,
I assume when the runtime for BSD comes out you will start arguing that WMI has also to be implemented there, or?
I accept the usage for something like WMI when necessary, but just to find a process, it is simply a tremendous overhead for me. We also build a framework here (running a hosting operation), but I would never introduce another subsystem just to check whether a process is already running. System.Management is NOT in the .net core defined through ECMA, IMHO (would have to look it up, though). WMI is a MS propietary technology.
Regards
-- Thomas Tomiczek THONA Consulting Ltd. (Microsoft MVP C#/.NET)
"Willy Denoyette [MVP]" <Click here to reveal e-mail address> wrote in message news:uG1TlM0pBHA.2172@tkmsftngp03... > Management classes are also core classes, they simply wrap something which is now called WMI, it's possible WMI will be > re-engineered using a managed provider, but that's an implementation detail. > WMI is available on ME, W2K, XP and is meant to be available on all up-coming MSFT platforms. [Original message clipped]
|
|
|
| |
|
|
| |
| |
| Willy Denoyette [MVP] (VIP) |
Thomas, Are you suggesting now that we shouldn't use the Windows.Forms, System.Data, System.DirectoryServices, System.EnterpriseServices ...... namespace classes because they wont be available on BSD and just stick to the BCL library, you must be kidding. You also seems to be ignorant about the availbility of Wbem (Just like WMI, based on the Common Information Model (CIM) industry standard ) on most Unix system available today. You also seems to be ignorant of the existence of a management framework alliance at MS, consisting of ISV's like NetIQ Tivoly and Others, who are building management frameworks using .NET and the Management namespace.
You also failed to read my post, I didn't use the Management classes to find a process, but to find the command line arguments belonging to that particular process (something you didn't even answered in your response), I also said it was not the only way to do this.
Willy.
"[MVP] Thomas Tomiczek" <Click here to reveal e-mail address> wrote in message news:3c541c64$Click here to reveal e-mail address... [Original message clipped]
|
|
|
| |
|
|
| |
| |
| [MVP] Thomas Tomiczek (VIP) |
No, but I strongly suggest that you keep things as simple as possible.
The original question did not even mention whether it is a web FORMS application - could be a command line tool that CAN be platform independant.
For the availability of Wbem on most unix systems - I dont knoy of any implementation on LINUX. Now, I dont like linx, but this is what the competition will basically be.
I am also not ignorant of initiatives such as NetIQ, but I like things as simple as possible, you know.
-- Thomas Tomiczek THONA Consulting Ltd. (Microsoft MVP C#/.NET)
"Willy Denoyette [MVP]" <Click here to reveal e-mail address> wrote in message news:etyCNI1pBHA.2432@tkmsftngp07... [Original message clipped]
|
|
|
| |
|
|
| |
| |
| Willy Denoyette [MVP] (VIP) |
Thomas,
I was not answering the original question, I answered a second question from the same original poster, the question was 'How can I get the command line arguments of another running process'. I also like simple things, but tell me what's so complicated having two lines of code, using .NET framework classes, to get the command-line args. of an abitrary running process. Like I said there are other way's to achieve the same result, but I don't like to use P/Invoke either. Talking about Linux [not my favorite as well :-)], a know a company (very well) who has an implementation of the standards based Wbem framework available for Linux, it doesn't offer the same rich functionality as the WMI implementation, but that's quite normal as the underlying OS doesn't either.
Willy.
"[MVP] Thomas Tomiczek" <Click here to reveal e-mail address> wrote in message news:Click here to reveal e-mail address... [Original message clipped]
|
|
|
| |
|
|
| |
|
|
|
|
|
|
|
|
|
|
| |
| dk |
How would you activate the previous instance?
"Willy Denoyette" <Click here to reveal e-mail address> wrote in message news:#JUIg6OmBHA.1544@tkmsftngp03... > Use a named Mutex in your Main function to guard against multiple execution is one possibility. [Original message clipped]
|
|
|
| |
|
| |
| |
| Willy Denoyette (VIP) |
The previous (only instance) is still active, or didn't I understand your question.
The first application run will acquire the named mutex and only release it when the application exits, each following run of the application while fail to obtain a handle to the Mutex (assumed it has the same name).
Willy.
"dk" <dk&@junk.com> wrote in message news:uYAltjSmBHA.1652@tkmsftngp05... [Original message clipped]
|
|
|
| |
|
|
| |
| |
| Ed Stegman |
Do you mean bring the window to the front of the desktop ZOrder?
If so, PInvoke the SetForegroundWindow()[1].
You can get the window handle by first changing the title of your 2nd, unwanted instance, then using FindWindow()[2]. The call would look like something like this, depending on your declare.
IntPtr firstWindow = FindWindow(null, "First Window's Title"); SetForegroundWindow(firstWindow);
(watch for wrap) [1] ms-help://MS.VSCC/MS.MSDNVS/winui/windows_1eev.htm [2] ms-help://MS.VSCC/MS.MSDNVS/winui/windows_03sn.htm
Keep Smilin' Ed Stegman
"Willy Denoyette" <Click here to reveal e-mail address> wrote in message news:OeANNFTmBHA.2168@tkmsftngp05... > The previous (only instance) is still active, or didn't I understand your question. [Original message clipped]
|
|
|
| |
|
| |
| |
| Steven Van Dyke |
Great! But how do you write this in C#? Steve
"Ed Stegman" <Click here to reveal e-mail address> wrote in message news:eo9BIAZmBHA.2112@tkmsftngp05... [Original message clipped]
|
|
|
| |
|
| |
| |
| Willy Denoyette (VIP) |
Like this:
[DllImport("User32",EntryPoint="FindWindow")] private static extern IntPtr FindWindow(string lpClassName,string lpWindowName);
[DllImport("User32",EntryPoint="SetForegroundWindow")] private static extern bool SetForegroundWindow(IntPtr hWnd); .... IntPtr hWnd = FindWindow(null, "Window Title Here"); // or ClassName and Title // IntPtr hWnd = FindWindow("notepad", "Window Title Here");
if(hWnd != null) bool ret = SetForegroundWindow(hWnd);
Willy.
"Steven Van Dyke" <Click here to reveal e-mail address> wrote in message news:exO#U7dmBHA.1604@tkmsftngp04... [Original message clipped]
|
|
|
| |
|
|
| |
| |
| Steven Van Dyke |
Only thing,
> if(hWnd != null)
Would not compile. I changed to:
> if(hWnd.ToInt64() != 0)
Thanks so much!
Steve
"Willy Denoyette" <Click here to reveal e-mail address> wrote in message news:uN8QKOemBHA.1516@tkmsftngp07... [Original message clipped]
|
|
|
| |
|
| |
| |
| Willy Denoyette (VIP) |
NO, my bad, don't convert to Int64 unless you are running on a 64 Bit OS. better is to use:
(hWnd != IntPtr.Zero).
Willy.
"Steven Van Dyke" <Click here to reveal e-mail address> wrote in message news:eoeF5nemBHA.708@tkmsftngp03... [Original message clipped]
|
|
|
| |
|
|
| |
| | |
|
|
|
|
| |
| Willy Denoyette (VIP) |
Ok, when talking about Interactive applications you don't have to use Mutexes to guard against multiple instances. Just do as Ed said: If FindWindow returns a valid Handle, activate that instance with SetForegroundWindow using the returned handle, and stop the new application. If FindWindow returns null, go on and activate the new application.
Willy.
"Ed Stegman" <Click here to reveal e-mail address> wrote in message news:eo9BIAZmBHA.2112@tkmsftngp05... [Original message clipped]
|
|
|
| |
|
|
| |
| |
| Foxy |
mutexes and find window will give slightly different results when running on machine capable of multiple user desktops such as XP.
With mutexes you should get only one copy of the application running across all logged on users. Where as the find window option will allow another instance of the application evewn if another user on the same machine is running it.
"Willy Denoyette" <Click here to reveal e-mail address> wrote in message news:ORliwhcmBHA.1876@tkmsftngp03... > Ok, when talking about Interactive applications you don't have to use Mutexes to guard against multiple instances. [Original message clipped]
|
|
|
| |
|
| |
| |
| Willy Denoyette (VIP) |
Sure, that's exactly the reason not to use a Mutex in this case. FindWindow will return a valid handle if it finds the window class in the current active session (desktop). While using a mutex will prevent the user to start an application allready running in another session.
Willy.
"Foxy" <Click here to reveal e-mail address> wrote in message news:ObqhR$cmBHA.2356@tkmsftngp02... [Original message clipped]
|
|
|
| |
|
|
| |
| |
| Luis Angel |
Just a question (not an expert)
Couldn't you name the mutex using current user name? something like:
"myMutex" + System.Security.Principal.WindowsIdentity.GetCurrent.Token.ToString
I does not have Windows XP, but I suppose that the same user can't logon twice.
"Willy Denoyette" <Click here to reveal e-mail address> escribió en el mensaje news:ucGYdKdmBHA.2512@tkmsftngp04... [Original message clipped]
|
|
|
| |
|
| |
| |
| Willy Denoyette (VIP) |
There are several way's to uniquely identify a user and create a trackable name for the Mutex, and retrieving the cureent users name or token whatever is one of them. .. But again the point is, that the poster asked how to activate the first instance of a program when a user started a new one, and that cannot be achieved only using a named mutex Mutex.
Willy.
"Luis Angel" <Click here to reveal e-mail address> wrote in message news:uocLDipmBHA.2112@tkmsftngp05...
Just a question (not an expert)
Couldn't you name the mutex using current user name? something like:
"myMutex" + System.Security.Principal.WindowsIdentity.GetCurrent.Token.ToString
I does not have Windows XP, but I suppose that the same user can't logon twice.
"Willy Denoyette" <Click here to reveal e-mail address> escribió en el mensaje news:ucGYdKdmBHA.2512@tkmsftngp04... [Original message clipped]
|
|
|
| |
|
|
| |
|
|
| |
| Adrian O' Neill |
FindWindow is bad, bad, bad: http://www.pgh.net/~newcomer/nomultiples.htm
Kernel objects are the only way to go.
-- Adrian O' Neill - post replies to newsgroup. Remove * from e-mail address to reply.
"Willy Denoyette" <Click here to reveal e-mail address> wrote in message news:ucGYdKdmBHA.2512@tkmsftngp04... [Original message clipped]
|
|
|
| |
|
|
| |
| |
| Ed Stegman |
Thanks. Nice article. It brought up some issues I hadn't thought too deeply about lately. Been using FindWindow since the beginning of time and haven't revisited it. Just goes to show you that even the old stuff must be relearned very often :-))
Keep Smilin' Ed Stegman
"Adrian O' Neill" <aon*@bigfoot.com> wrote in message news:OZbl5romBHA.1604@tkmsftngp04... [Original message clipped]
|
|
|
| |
|
| |
|
| |
| Willy Denoyette (VIP) |
FindWindow is a simple solution to the problem, I didn't say it's the best/only one, Geez it wasn't even suggested by me.
"Adrian O' Neill" <aon*@bigfoot.com> wrote in message news:OZbl5romBHA.1604@tkmsftngp04... [Original message clipped]
|
|
|
| |
|
|
| |
|
|
|
|
|
|
|
| |
| Florian doyon |
Maybe by using named pipes/ mailslots...
|
|
|
| |
|
|
| |
| |
| Stefano Camaiani |
Well, good thread! First of all please excuse me for my bad english, i'm italian. There is another way to get your code working, fastest. Create another project with the ONLY function to get the command line arguments.(Then this will be the application to store as for example in the SendTo folder) When this new application will receive the arguments, simply pass its from this new exe to your principal product by a lot o ways, as for example by the registry or by a single file and exit. (I have in my mind to do it with the creation of a txt file with the use of the random access)
This will allow you to: - Gain speed of execution. In fact a simple project to get the commands will be about only 10k size. - You will not need to stop the execution of another form. This because, as i understand, the multiple execution of your form is caused by the call of something like SendTo... - You will get the ability to store arguments and open the real product only when you want. As for example if you will use a system-tray icons you will be able also to only store arguments (In my case Mp3 Songs) and only with a specific request to open the real product.
Hope this will help.
-------------------------------- From: Stefano Camaiani
|
|
|
| |
|
| |
|
|
|
| |
| Mark Perrone |
I like the mutex object but I had a problem.
This worked on my local box great but when I moved to the staging box, I was able to start the application multiple times. Is this a registry problem ? Security issue ? OS ?
Mark
|
|
|
| |
|
| |
|
| |
| Dan Menear |
Thanks; this was a great help for me as well!
-------------------------------- From: Dan Menear
|
|
|
| |
|
|
| |
|
|
| |
| wmiuser |
How do i identify and distinguish the multiple instances of a process? I am stuck up at that point.
-------------------------------- From: wmiuser
|
|
|
| |
|
| |
|
|
|
|
|
|
|
|
BootFX
Reliable and powerful .NET application framework. |
|
|
|
|
|
|