0

I create an executable using py2exe in python.
I was looking at this post but unfortunately the answers were superficial.
The first solution using Tendo but this works to limit 1 instance of application per user, and my app is being used in a Windows Server Environment where there are 20+ users loged in at a time.
And the second solution offered Listening to a defined port doesn't have examples of how it could be accomplished.
So I decided to go for mutexes to prevent my app from running multiple times.
So I currently use this code for using mutexes, but it doesn't have mutex detection between applications and Services.
This post shows how to accomplish mutexes, but doesn't show how its done in python.
How could I use Mutexes to have single instance of program on Windows where the mutexes don't limit single instance of program on Windows, and has detection between applications and Services.

Community
  • 1
  • 1
yuval
  • 2,848
  • 4
  • 31
  • 51

1 Answers1

2

I'm not sure why you'd have to use mutexes to this purpose on Windows? There's much simpler option: a bad old lockfile.

If all you want to achieve is making sure that only a single instance of the app runs, you could do something like this:

Windows supports you here since you can't delete a file if it's opened by another process. So (code untested):

tempdir = tempfile.gettempdir()
lockfile = os.sep.join([tempdir, 'myapp.lock'])
try:
    if os.path.isfile(lockfile):
        os.unlink(lockfile)
except WindowsError as e: # Should give you smth like 'WindowsError: [Error 32] The process cannot access the file because it is being used by another process..'   
    # there's instance already running
    sys.exit(0)

with open(lockfile, 'wb') as lockfileobj:
    # run your app's main here
    main()
os.unlink(lockfile)

with section ensures the file is opened when your main runs and it is closed when your main finishes running. Then os.unlink removes the lockfile.

If another instance tries to start up, it exits on WindowsError exception (it would be good to check its numeric code though to be sure it's precisely the case of the file already opened).

Above is a rough solution, a niftier one would be to use entry/exit functionality to delete lockfile if main exits for any reason. Explanation here: http://effbot.org/zone/python-with-statement.htm

LetMeSOThat4U
  • 6,470
  • 10
  • 53
  • 93
  • 1
    what happens if the application suddenly shuts down without executing os.unlink(lockfile)? – yuval Jan 25 '16 at 10:23
  • @yuval: Nothing. The file stays there, it's a "stale lockfile" situation, which is why on next startup the app tries to delete it in the try..except section. If the old process died and Windows has released lockfile, `os.unlink` succeeds and there's no exception. Then `with open..` creates a new lockfile (with the same path but you get the idea). P.S. a niftier solution, possibly combined with shutdown signal handler, could delete a lockfile in almost any scenario of app process eliminated (crash, killed by OS, etc). – LetMeSOThat4U Jan 25 '16 at 10:26
  • But on many computers different users don't have access to share the same file, and my app is being used in a Windows Server Environment where there are 20+ users loged in at a time. – yuval Jan 25 '16 at 10:28
  • @yuval Do you want to ensure that only 1 user can run your app, not 1 app instance / OS account? That strikes me as strange: why should only 1 user / system be able to run it? What is it precisely you're trying to accomplish? I think you should clarify your goals and the problem instead of solution in your question. – LetMeSOThat4U Jan 25 '16 at 11:39
  • Yes only one user should be able to run the app – yuval Jan 25 '16 at 11:41
  • Why is it relevant why I don't want it to run on multiple users on the same computer. Explaining this in the question would only make the question unnecessarily longer. I just need a way to run it on only one user. – yuval Jan 25 '16 at 11:53
  • This solution works perfectly on my machine with windows 7 x64 and python 3.5 – Dmitry Feb 25 '16 at 09:24