VB.net program that only allows one user to open the program at a time

Brian
Brian used Ask the Experts™
on
I have a VB.net program that will be launched by users on our network, but I only want one user to be able to open it at a time. I checked the option "Make single instance application", but that only keeps it from being launched more than once on the same computer.  How can I keep it from being launched more than once from any computers on the network?
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Top Expert 2016
Commented:
your program will have to create a semaphore file somewhere that is accessible by all users/computers that can run the program.
The problem being that once a user starts the program and if no semaphore exists it then creates the semaphore and saves it somewhere that if the user turns off their computer, reboots the remove semaphore routine will not be called and the semaphore will still exist. This will prevent all users using the program.
You could use a timestamp that the active user will update periodically and if the semaphore is older than a defined time frame then another user will be able to access the program.
ste5anSenior Developer

Commented:
It's called normally distributed locking. Which is an art, when done right.

Using semaphore files will work under normal circumstances, but it has some drawbacks..

Does your program use a shared resource which can be locked, e.g. if you use SQL Server, then you could use app locks.

When it must be foolproof, you need a witness. Thus a Windows service on a server, which is queried by the started application, whether it is the only instance. When it is, then the program must login for being used and logged out after usage. The service needs to monitor the application. E.g. by using WMI to query that the application process is still running as well as asking for a heart beat of the application itself.
Éric MoreauSenior .Net Consultant
Top Expert 2016

Commented:
your findings on "Make single instance application" are correct. this setting is for a single machine only.

there is nothing built-in that will implement that mechanism over a network. that means that you will need to implement your own.

as said by David, you will need to leave a trace somewhere accessible by everyone on the network (a file share, a database, ...) but that is not a perfect solution because often you will find your trace still on after the application crashed, or PC has rebooted while the application is still open, or a power failure, or ...

can I ask why do you need to a single instance to run?
CompTIA Security+

Learn the essential functions of CompTIA Security+, which establishes the core knowledge required of any cybersecurity role and leads professionals into intermediate-level cybersecurity jobs.

Author

Commented:
So the program is used to put a computer in a domain and add the computer to Active Directory groups. Now that I have read and digested these good comments, I realize that maybe what I need is to have a check happen when someone clicks the submit button, not when the program is being opened.  I say this because someone might have the program open and then become distracted by some YouTube video that a friend sent to their phone.

I wish there was something more foolproof and I also wish there was something to queue the usage. For example, I press submit seconds after my coworker hits submit and the program puts me first in the queue to allow me to continue the process of joining the domain and adding to groups as soon as my coworker is finished.

By the way, the reason I'm doing this is because sometimes when the computer is being added to a group, it fails.  We think it happens when 2 or more people are using the program at the same time. It's just a theory, but if we are able to limit the program to one user at a time, then we would find out for certain.
Éric MoreauSenior .Net Consultant
Top Expert 2016

Commented:
preventing part of an application from running simultaneously on multiple computers is as complex as preventing the full application.

one thing you might want to do is to split your process. you might have your application (running in as many instances you want) to queue your process into a system of your choice (like a database) and have a process running from a server that handles that queue.
ste5anSenior Developer

Commented:
By the way, the reason I'm doing this is because sometimes when the computer is being added to a group, it fails.  We think it happens when 2 or more people are using the program at the same time. It's just a theory, but if we are able to limit the program to one user at a time, then we would find out for certain.
Defensive programming. Do you test whether it exists before you add it?
But in the end, you need for a bunch of reasons error handling here. Thus extend it to detect a duplicate action here.

Author

Commented:
Yes, I test if the computer is already in the group, if not, it adds it, then a test is done to see if it's in the group.  If it fails, an email is sent to me. When it fails, it really does fail (the computer is never in the group when it fails).

I could have the program write the computername to a folder on a server, then an app on the server could add the computers into the appropriate groups, but I feel that would add more complication and more chances of something going wrong.

After reviewing the suggestions,  I think I should write a file to a share when a person hits submit.  Once the process completes, the file is removed. When the submit button is hit and it sees that the lock file exists, then it checks the creation time (what David suggested). If it's more than 3 minutes old, it recreates the lock file and begins processing. Of course if two instances of the program see an old lock file at the exact same time, then we have a failure. Still, it would make the failures less likely.
Éric MoreauSenior .Net Consultant
Top Expert 2016

Commented:
adding a server to run your queue is surely adding complexity.

your solution of creating a file (with the check for file older then X minutes) seems to be an easy work around for your particular situation
ste5anSenior Developer

Commented:
If it fails, an email is sent to me. When it fails, it really does fail (the computer is never in the group when it fails).
When it fails, I would look at the exception or error message. I would recheck the existence.

btw, how and where do you add that computer exactly? AD replication for example can lead to serious delays (up to 45 minutes).

Author

Commented:
The program adds the computer on the DC and it's immediate and it never fails. Adding the computer to the group never use to fail until recently, but I believe that it's because we have a large number of devices and multiple people using the program at the same time. The error message is not descriptive, just that Add failed.

Author

Commented:
Thanks for all your help!

Commented:
Reposting from duplicate thread:

If your application connects to a database, you could create a session table which will store a lock record.  The lock record would be read by clients attempting to connect.  If a lock is active then the client wont connect.  I would also recommend that your application, so long as it is open, updates a tombstone field periodically to show that it is active.  In case of a dirty shutdown the next client that attempts to connect will compare the tombstone field with the timeout period in order to determine if the active record is stale in order to allow it's own connection.

-saige-

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial