Sandallic Posted December 29, 2004 Posted December 29, 2004 Hello, here comes another question. Isnt there any easy way to disable my application to start twice? I cant accept that there are running two instances of my application at the same time.. I think there is a way withing VS.net where you can turn this off.. Any1 knows ? Thx, Sandallic Quote
Administrators PlausiblyDamp Posted December 29, 2004 Administrators Posted December 29, 2004 http://www.xtremedotnettalk.com/showthread.php?t=89413 http://www.xtremedotnettalk.com/showthread.php?t=75065 Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
AlexCode Posted December 30, 2004 Posted December 30, 2004 I have this solution that works perfectly well for me... Maybe Mutex is a better option but I leave you to choose... Module Global Declare Function ShowWindow Lib "user32" (ByVal hWnd As IntPtr, ByVal nCmdShow As Long) As Long Public Sub main() 'Evaluate if this application is already running on this computer Const SW_MAXIMIZE = 3 Const SW_SHOWMINIMIZED = 2 Const SW_RESTORE = 9 Const SHOWNORMAL = 1 Const SW_SHOW = 5 Dim processes() As Diagnostics.Process = Diagnostics.Process.GetProcessesByName(Diagnostics.Process.GetCurrentProcess.ProcessName) If processes.Length > 1 Then Dim mProcess As Diagnostics.Process For Each p As Diagnostics.Process In processes If mProcess Is Nothing Then mProcess = p Else If p.StartTime < mProcess.StartTime Then mProcess = p End If Next Dim hwnd As IntPtr = mProcess.MainWindowHandle Call ShowWindow(hwnd, SW_SHOWMINIMIZED) Call ShowWindow(hwnd, SHOWNORMAL) Call ShowWindow(hwnd, SW_SHOW) Exit Sub End If Application.EnableVisualStyles() Application.DoEvents() Application.Run(New StartForm) End Sub End Module This code not only block a second instance but also shows the application... Alex :p Quote Software bugs are impossible to detect by anybody except the end user.
Tygur Posted January 1, 2005 Posted January 1, 2005 AlexCode, your code can be easily modified to use mutexes and show the previous instance. That way, there is no chance for your app to be shown twice, and you eliminate the need to loop through all the processes on the first run, which results in a (slightly?) quicker startup time: Module Global Declare Function ShowWindow Lib "user32" (ByVal hWnd As IntPtr, ByVal nCmdShow As Long) As Long Dim MyMutex As Threading.Mutex Public Sub main() 'declare constants Const SW_MAXIMIZE = 3 Const SW_SHOWMINIMIZED = 2 Const SW_RESTORE = 9 Const SHOWNORMAL = 1 Const SW_SHOW = 5 'Evaluate if this application is already running on this computer Dim NoPrevInstance As Boolean 'I changed the string here to make it more obvious that it needs to be changed when this code is used: MyMutex = New Threading.Mutex(True, "Some String that's specific to your app", NoPrevInstance) If Not NoPrevInstance Then 'if this application is already running, show it Dim processes() As Diagnostics.Process = Diagnostics.Process.GetProcessesByName(Diagnostics.Process.GetCurrentProcess.ProcessName) If processes.Length > 1 Then Dim mProcess As Diagnostics.Process For Each p As Diagnostics.Process In processes If mProcess Is Nothing Then mProcess = p Else If p.StartTime < mProcess.StartTime Then mProcess = p End If Next Dim hwnd As IntPtr = mProcess.MainWindowHandle 'Why did you have these two lines in here: 'Call ShowWindow(hwnd, SW_SHOWMINIMIZED) 'Call ShowWindow(hwnd, SHOWNORMAL) Call ShowWindow(hwnd, SW_SHOW) Exit Sub End If End If Application.EnableVisualStyles() Application.DoEvents() Application.Run(New StartForm) End Sub End Module By the way, why did you have those two extra ShowWindow lines? Quote
AlexCode Posted January 1, 2005 Posted January 1, 2005 Hi... 1st - When I did that code I din't knew about Mutex, and after knowing about it I didn't had much intetntion to modify it, since the performance increse shounldn't be "felt"... But shure it's more "clean" and "correct" code... 2nd - Those 2 extra line you queried about... At least on my combuter (try it on yours to see if it's "universially" true), if the windows isn't minimized (if it's only behind others), the SHOW doesn't activate the window as expected, only shows it... The correct behaviour only ocurres when the window is minimized... so, I minimize it (Call ShowWindow(hwnd, SW_SHOWMINIMIZED)), then I show the window with its last size and location (Call ShowWindow(hwnd, SHOWNORMAL)) and finally I call the show to make shure it gets active (Call ShowWindow(hwnd, SW_SHOW)). Like I said, try it if the same behaviour error ocurres with you... if not, just use the last line... By the way... thanks for the code "facelift"... :D Alex :p Quote Software bugs are impossible to detect by anybody except the end user.
Administrators PlausiblyDamp Posted January 1, 2005 Administrators Posted January 1, 2005 Although the performance differrence is probably not a reason to use the mutex based code, try running both on a terminal server based system when multiple sessions want to run the same application multiple times. Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
AlexCode Posted January 1, 2005 Posted January 1, 2005 Hummmm great hint Plausy... I didn't tested it in that environment... what hapens? It gets confused with the instances or just doesn't work? Alex :p Quote Software bugs are impossible to detect by anybody except the end user.
Tygur Posted January 1, 2005 Posted January 1, 2005 On my computer, the performance difference is noticable. Skipping the search through the processes seems to save at least a good couple seconds. After working with the code a bit, I see what you mean about needing those three calls. However, I've always done it with SetForeGroundWindow, anyway. You do still need one call to ShowWindow in case it's minimized. Also, while adding the Declare for SetForegroundWindow, I noticed that ShowWindow had Long's instead of Int32's. Is there a reason why that even still worked? Whatever the case, I changed them to Int32's: Module Global Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As IntPtr) As Int32 Declare Function ShowWindow Lib "user32" (ByVal hWnd As IntPtr, ByVal nCmdShow As Int32) As Int32 Dim MyMutex As Threading.Mutex Public Sub main() 'declare constants Const SW_MAXIMIZE = 3 Const SW_SHOWMINIMIZED = 2 Const SW_RESTORE = 9 Const SHOWNORMAL = 1 Const SW_SHOW = 5 'Evaluate if this application is already running on this computer Dim NoPrevInstance As Boolean MyMutex = New Threading.Mutex(True, "Some String that's specific to your app", NoPrevInstance) If Not NoPrevInstance Then 'if this application is already running, show it Dim processes() As Diagnostics.Process = Diagnostics.Process.GetProcessesByName(Diagnostics.Process.GetCurrentProcess.ProcessName) If processes.Length > 1 Then Dim mProcess As Diagnostics.Process For Each p As Diagnostics.Process In processes If mProcess Is Nothing Then mProcess = p Else If p.StartTime < mProcess.StartTime Then mProcess = p End If Next Dim hwnd As IntPtr = mProcess.MainWindowHandle 'The way I would do it: Call ShowWindow(hwnd, SW_RESTORE) SetForegroundWindow(hwnd) Exit Sub End If End If Application.EnableVisualStyles() Application.DoEvents() Application.Run(New StartForm) End Sub End Module Quote
AlexCode Posted January 1, 2005 Posted January 1, 2005 Ok... Donne... Nice thread this one! :p Alex Quote Software bugs are impossible to detect by anybody except the end user.
Administrators PlausiblyDamp Posted January 2, 2005 Administrators Posted January 2, 2005 In a nutshell you cannot rely on just counting the number of processes, using a mutex you have control over a single instance per server or per session... Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
AlexCode Posted January 2, 2005 Posted January 2, 2005 I never got that nutshell concept just right... :p Alex :D Quote Software bugs are impossible to detect by anybody except the end user.
PROKA Posted January 4, 2005 Posted January 4, 2005 I got this error : Additional information: It is invalid to start a second message loop on a single thread. Use Application.RunDialog or Form.ShowDialog instead. with a break on the line Application.Run(New frmMain) Quote Development & Research Department @ Elven Soft
Tygur Posted January 4, 2005 Posted January 4, 2005 When you look at all the codes out there for making your app only start up once, you might've noticed that they are all in Subs called Main. This is for a reason. You are supposed to put a Sub Main in a Module (alternatively, you can put a Shared Sub Main in a Class, but I prefer the module). Then go to Project -> Properties. In the window that comes up, change "Startup Object" from your form to the Sub Main that you put in. Quote
RampagePS Posted January 5, 2005 Posted January 5, 2005 (edited) Hey I was reading this post and I was wondering if yall could tell me how to do this in C# or if there was a tutorial I could look at. Edited January 5, 2005 by RampagePS Quote
PROKA Posted January 5, 2005 Posted January 5, 2005 oh , thanks tygur ... my mistake :) Works perfectly now! Quote Development & Research Department @ Elven Soft
AlexCode Posted January 5, 2005 Posted January 5, 2005 Hey I was reading this post and I was wondering if yall could tell me how to do this in C# or if there was a tutorial I could look at. Translate it yourself... It's not that hard and sooner or later you'll have to learn a little vb.net... at least to understand the code examples aroud the web... :p Quote Software bugs are impossible to detect by anybody except the end user.
PROKA Posted January 5, 2005 Posted January 5, 2005 I think it would be something like this [CS] using System.Diagnostics; using Microsoft.VisualBasic; using System; using System.Data; using System.Drawing; using System.Windows.Forms; using System.Collections; using System.Runtime.InteropServices; namespace Only_One_Instance { sealed class Global { [DllImport("user32", ExactSpelling=true, CharSet=CharSet.Ansi, SetLastError=true)] public static extern int SetForegroundWindow(IntPtr hwnd); [DllImport("user32", ExactSpelling=true, CharSet=CharSet.Ansi, SetLastError=true)] public static extern int ShowWindow(IntPtr hWnd, int nCmdShow); static System.Threading.Mutex MyMutex; public static void main () { //declare constants const int SW_MAXIMIZE = 3; const int SW_SHOWMINIMIZED = 2; const int SW_RESTORE = 9; const int SHOWNORMAL = 1; const int SW_SHOW = 5; //Evaluate if this application is already running on this computer bool NoPrevInstance = false; bool temp_bool = NoPrevInstance; MyMutex = new System.Threading.Mutex(true, "Some String that's specific to your app", out temp_bool); if (! NoPrevInstance) { //if this application is already running, show it System.Diagnostics.Process[] processes = System.Diagnostics.Process.GetProcessesByName(System.Diagnostics.Process.GetCurrentProcess().ProcessName); if (processes.Length > 1) { System.Diagnostics.Process mProcess = null; foreach (System.Diagnostics.Process p in processes) { if (mProcess == null) { mProcess = p; } else { if (p.StartTime < mProcess.StartTime) { mProcess = p; } } } IntPtr hwnd = mProcess.MainWindowHandle; //The way I would do it : ShowWindow(hwnd, SW_RESTORE); SetForegroundWindow(hwnd); return; } } Application.EnableVisualStyles(); Application.DoEvents(); Application.Run(new Form1()); } } } [/CS] Quote Development & Research Department @ Elven Soft
RampagePS Posted January 5, 2005 Posted January 5, 2005 Hey man thanks for the code, im at school know so no time to test it out, :eek: But I will repost when I get home and let you know if it worked. Quote
DarkKai Posted January 7, 2005 Posted January 7, 2005 You can try this (VB.Net) : If (UBound(Diagnostics.Process.GetProcessesByName(Diagnostics.Process.GetCurrentProcess.ProcessName)) > 0) Then MsgBox(" Application is already running in another window") End End If Quote
AlexCode Posted January 7, 2005 Posted January 7, 2005 You can try this (VB.Net) : If (UBound(Diagnostics.Process.GetProcessesByName(Diagnostics.Process.GetCurrentProcess.ProcessName)) > 0) Then MsgBox(" Application is already running in another window") End End If Read the complete thread and THEN you'll figure out why that code shouln't be used... Alex :p Quote Software bugs are impossible to detect by anybody except the end user.
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.