Single copy of BlitzMax program
BlitzMax Forums/BlitzMax Programming/Single copy of BlitzMax program
| ||
Hi everybody, I want to forbid running more than one copy of my game at the same time. As I understand, the direct way is to get the list of running processes and quit the program if the process with the same name is found. But it seems that this will not work because people report problems with PSAPI.dll and I absolutely don't know how to do this on Mac. Can some kind soul share a piece of code which can solve this problem (or at least provide some suggestions)? Thanks in advance! Mikle. |
| ||
By default, Mac only allows one copy of the same app to run at a time. |
| ||
This makes things easier. But what's about Win XP/Vista? |
| ||
The catchword is Mutual exclusion (Mutex) |
| ||
Sorry? Pls explain for dummy :) |
| ||
have the first program create a file which gets deleted when it exits, all other attempts to run the program looks for that file and if its present it also exits (without deleting the file of course ;) ) This way your program will only run once and the concurrent attempts to run it will just make them quit without problem. |
| ||
have the first program create a file which gets deleted when it exits, all other attempts to run the program looks for that file and if its present it also exits (without deleting the file of course ;) ) This way your program will only run once and the concurrent attempts to run it will just make them quit without problem. And if your program ever crashes, or is forced to close by the user, or in any way terminates unexpectedly, your program will never run again. A Mutex is the way to go. Sorry? Pls explain for dummy :) http://msdn.microsoft.com/en-us/library/ms684266(VS.85).aspx Plus the forum has a search function. If you use it, you'll find that the use of a Mutex has been discussed and explained before. |
| ||
Very nice idea! Thanks! But if the program for sime reason quits without deleting this file, it will not run anymore! |
| ||
http://www.blitzbasic.com/codearcs/codearcs.php?code=1937#comments |
| ||
http://blitzmax-ide.svn.sourceforge.net/viewvc/blitzmax-ide/singleinstance.bmx?revision=3&view=markup |
| ||
Thanks a lot everybody! I've finished with this simple function: Function CheckAnotherInstance() Local fname$ = "cai" DeleteFile(fname) If FileType(fname)<>0 End Else WriteFile(fname) EndIf End Function I run it at the beginning of the program and everything works fine. |
| ||
Const ERROR_ALREADY_EXISTS:Int = 183 Extern "win32" Function CreateMutex:Int(lpMutexAttributes :Byte Ptr, bInitialOwner:Int, lpName : Byte Ptr) = "CreateMutexA@12" Function GetLastError:Int() = "GetLastError@0" End Extern Local ret:Int = CreateMutex(Null,Null ,"ProgName".ToCstring()) If getlasterror () = ERROR_ALREADY_EXISTS End EndIf |
| ||
So have a file which you keep all the time but whose content changes to `log` how many times the app started and how many times it correctly `shut down` and if those numbers are odd or even you can tell what state it's in? Or maybe you need a double-buffered system? |
| ||
No, the idea is very simple -- I open an empty file for writing and keep it while the program is working. If an instance of the program is already running, I cannot delete it. So, if I try to delete the file and can't (FileType(fname)<>0), this means that one instance is already working, so I quit. If I can delete the file, this means that I'm running for the first time, so, I reopen the file for writing and start the program. This works even if the program crashes or shuts down unexpectedly. |
| ||
Are you sure that works? A crash could easily leave that file "hung open" by the operating system. So, I still believe that using a file like that is not fool proof. |
| ||
Why is it so bad if two copies are open at once? |
| ||
The file idea is rather crude, why aren't you going to use Mutex? BTW there could be user-rights issues with the file creation/deletion and cause corruption in the information your game is receiving. |
| ||
As for the Mac, it will let you run 2 copies of the same program if you actually copy the app, and rename one copy. So, a user wouldn't be able to *accidentally* run two copies, but they could force it if they wanted to. So it really depends on what you're trying to protect against. At least that's how it worked in Tiger - I haven't tried with Leopard. |
| ||
There's really nothing you can do if people 'really' want to run two copies. A simple idea would be to have the application write to a temp file the current millisecs of the app, and then check & update every random amount of time that the file still contains the same number. If two apps do this, they will write different numbers and detect that the number has changed. Not the best way to do it, but simple. It wouldn't stop someone from being able to hex edit it to write to a different file though, just as it isn't really possible to prevent people from opening 2 of the same app on the same machine. There's virtual machines, nada you can do!. What advantage will people get from running multiple processes of your app anyways? Maybe it's those advantages you should be more worried about toning down; that's probobly the best thing you could do. |
| ||
Ya, I cannot protect my app from running two copies if the user wants to. But I don't attempt to do this. I simply want to protect the user (and myself) from occational running of the second copy of my game engine. If this happen, the engine slows down and becomes buggy. Under normal conditions the engine should not crash or, even if it crashes, it shuts down and frees the file. I think that the system will keep the file open only when serious error happen, but this anyway will need reboot. I decided not to use Mutex because it works only under Windows, though this method generally is more correct. |
| ||
Why do you feel that you need to do this for the user? Most games go to crap if you run two of them. Run any serious FPS game and then start it a second time. It will run slow. Why do you feel you need to protect the user from him/her self in this instance? |
| ||
I would have thought opening a socket and broadcasting something on it to secondary instances was much more effective and less prone to errors than something with a file. |
| ||
I would have thought opening a socket and broadcasting something on it to secondary instances was much more effective and less prone to errors than something with a file. That's brilliant, popup a windows firewall warning for a game that isn't online, perfect way to make your customers happy.And what if they don't have a network card? (I know highly unlikely, but you never know.. overparanoid parents?) |
| ||
2 TaskMaster: It is very irritating when the mouse slows down and you can't shut down unnecessary copy of the program for 20-40 sec. And I do know that nobody in healthy mind will run second copy of my game. So it is mostly for my (customer’s) convenience and for protection from mistakes, not from intentional action. |