Brian
asked on
VB.net program that only allows one user to open the program at a time
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?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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?
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?
ASKER
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.
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.
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.
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.
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.
ASKER
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.
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.
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
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
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).
ASKER
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.
ASKER
Thanks for all your help!
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-
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-
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.