I'm developing VB.Net application and i wanted to block users from open another session of the program while they already has one
so i made a value in my DB that changes from Offline to Online and reverse according to the status of the log in
Program Started = Online (In Form Load Event)
Program Closed = Offline (In Form Closing Event)
The problem is : some times the program hang or windows ..... etc so the program don't change the DB value for that user from Online to Offline and this prevent him from opening the application
so how i can handle the unexpected shut down of my program to deal with this case?
I think you're talking about user session management here. If I understand you correctly, you want to stop any one user from logging in to two instances at the same time rather than there being two copies of your application open at one time (obviously with different users logged into each). If this is the case then it isn't actually that difficult to implement something very basic.
When your user logs on, perform a check to see if they already have a record in your session table. If not, then create one and issue that user with the session id. This id must then be supplied during all operations so that you can check it is valid. So far, so good.
If there is already a record in that session table then invalidate it (delete it, change the status - whatever) so that the old session id can't be used and issue a new one. That way, if your user already has a logged in copy of the app open then start another, the first one will no longer actually do anything useful (don't forget to inform users that an invalid session id is the reason why they can't do anything).
Obviously you will need to persist that session id for the life of the application, but for the love of all that is good, don't put it in a global variable: Pass it as part of the constructor to any object you instantiate which will perform any DB actions. Maybe even wrap it in a class of it's own if you need functionality and that variable or object can be private to your main class.
For example, lets say your main class is a form called frmMain which spawns a login dialog when it starts to capture username and password:
Public Class SessionManagerClass _dal As New DAL Private _sessionId As Int Private _userName As String Public Sub New(ByVal UserName As String, ByVal Password As string) _sessionId = _dal.Login(UserName, Password) End Sub End Class Partial Class frmMain Private _session As SessionManagerClass Public Sub frmMain_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim loginForm As New dlgLogin loginForm.ShowDialog() _session = New SessionManagerClass(loginForm.UserName, loginForm.Password) loginForm.Dispose() End Sub Public Sub btnLaunchChildForm_Click(ByVal sednder As Object, ByVal e As EventArgs) Handles btnLaunchChildForm.Click Dim frm As New frmChildForm(_session) frm.ShowDialog() End Sub End Class Partial Class frmChildForm _session As SessionManagerClass _dal As New DAL Public Sub New(ByVal Session As SessionManagerClass) _session = Session End Sub Private Sub DoSomething() If _dal.SaveValues(_session.SessionId, Value1, Value2, Value3) Then 'All Good Else 'Something went wrong. Maybe invalid session ID or perhaps you didn't validate your data. Whatever. Handle the problem if you can. End If End Sub End Class
This is in no way working code, just an example of how you might go about it to get you started.
You should attempt to remove the lock from the database when your application exits, but you can't stop someone going into task manager and ending the process. In this case your application does not get any notification of a shutdown and so can't write to the database.
We handle this occurrence by getting users to request an
unlock code a secret code which allows them to clear the logged in flag. The unlock code changes each day so if they want one tomorrow they have to ask for another one.
you could simply use the built in functionality
Single instance application by clicking on your project and on application check
Make Single instance application as the screen shot shows
Review your entire approach: you can use the
Process class instead.
Dim list() As Process = Process.GetProcessesByName(Process.GetCurrentProcess.ProcessName) If list.Length > 1 Then Application.Exit() End If
Well, I've created a new solution another field should be created with name currentsession when the user open the program it takes a number and when UN-expected shutdown occur i made a patch to change the current status to offline and the session id to the next number then I've created a check sub in each save button to check for the current session and if it matches the one in the database it will continue and if not it will shutdown the program