Single copy of BlitzMax program

BlitzMax Forums/BlitzMax Programming/Single copy of BlitzMax program

Mik1e(Posted 2008) [#1]
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.


Brucey(Posted 2008) [#2]
By default, Mac only allows one copy of the same app to run at a time.


Mik1e(Posted 2008) [#3]
This makes things easier. But what's about Win XP/Vista?


Vertex(Posted 2008) [#4]
The catchword is Mutual exclusion (Mutex)


Mik1e(Posted 2008) [#5]
Sorry? Pls explain for dummy :)


*(Posted 2008) [#6]
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.


Gabriel(Posted 2008) [#7]
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.


Mik1e(Posted 2008) [#8]
Very nice idea! Thanks!

But if the program for sime reason quits without deleting this file, it will not run anymore!


fredborg(Posted 2008) [#9]
http://www.blitzbasic.com/codearcs/codearcs.php?code=1937#comments


grable(Posted 2008) [#10]
http://blitzmax-ide.svn.sourceforge.net/viewvc/blitzmax-ide/singleinstance.bmx?revision=3&view=markup


Mik1e(Posted 2008) [#11]
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.


Bremer(Posted 2008) [#12]
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



ImaginaryHuman(Posted 2008) [#13]
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?


Mik1e(Posted 2008) [#14]
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.


TaskMaster(Posted 2008) [#15]
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.


Czar Flavius(Posted 2008) [#16]
Why is it so bad if two copies are open at once?


plash(Posted 2008) [#17]
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.


jhans0n(Posted 2008) [#18]
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.


Retimer(Posted 2008) [#19]
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.


Mik1e(Posted 2008) [#20]
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.


TaskMaster(Posted 2008) [#21]
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?


Gabriel(Posted 2008) [#22]
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.


plash(Posted 2008) [#23]
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?)


Mik1e(Posted 2008) [#24]
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.