Batch file to close application then disconnect from the server (1 Viewer)

Rachael2211

Member
Local time
Today, 06:13
Joined
Oct 24, 2013
Messages
33
Hi All,

My split application is used on an RDP in a multi-user environment. Field Access groups when they logon have the application launch then when they close out of it it disconnects them from the server/rdp. To do this I run a batch file just before the application.quit to disconnect user from server BUT...it doesn't kill the instance of MSaccess.exe for that user in the task manager SO...my though is to incorporate the shutting down of MSAccess.exe into the batch file and the "quit" button would just call it instead of calling it then using application.quit which I dont think executes because the batch file disconnects user first.

Heres my closing routine from a button on the menu of my application:

Function IsMember(strDomain As String, strGroup _
As String, strMember As String) As Boolean

Dim grp As Object
Dim strPath As String

strPath = "WinNT://" & strDomain & "/"
Set grp = GetObject(strPath & strGroup & ",group")
IsMember = grp.IsMember(strPath & strMember)
End Function

Function GetCurrentUser() As String
GetCurrentUser = Environ("USERNAME")
End Function

Function GetCurrentDomain() As String
GetCurrentDomain = Environ("USERDOMAIN")
End Function

Private Sub cmdCancel_Click()
On Error GoTo Err_cmdCancel_Click

If IsMember(GetCurrentDomain, "FIELD ACCESS", GetCurrentUser) Then
Shell ("C:\BusiVine\Shutdown.bat")
Application.Quit
Else
Application.Quit
End If

Exit_cmdCancel_Click:
Exit Sub

Err_cmdCancel_Click:
Resume Exit_cmdCancel_Click

End Sub

Here is my thoughts for the batch and getting rid of the application.quit line:

@echo off
taskkill /im MSACCESS.EXE /t /f
Shutdown /l /f

I know the shutdown line works but am unsure about the correctness of the msaccess line, could some awesome expert person please give me the thumbs up that Im on the right track before I try to implement this on the server and give everyone a headache lol

thank you in advance, Rachael
 

arnelgp

..forever waiting... waiting for jellybean!
Local time
Today, 21:13
Joined
May 7, 2009
Messages
19,169
why not directly Kill MSA from your code?
paste this in a Module:
Code:
Option Explicit

' Module Name: ModFindWindowLike
' (c) 2005 Wayne Phillips (http://www.everythingaccess.com)
' Written 02/06/2005
'
' mODIFIED bY aRNELgP FOR x64 aCCESS
'
                 
#If VBA7 Then
    Private Declare PtrSafe Function EnumWindows Lib "USER32" (ByVal lpEnumFunc As LongPtr, ByVal lParam As LongPtr) As Long
    Private Declare PtrSafe Function GetWindowText Lib "USER32" Alias "GetWindowTextA" (ByVal hwnd As LongPtr, ByVal lpString As String, ByVal cch As Long) As Long
       
        'Could use global variables instead, but this is nicer.
        'Custom structure for passing in the parameters in/out of the hook enumeration function
        'Could use global variables instead, but this is nicer.
        Private Type FindWindowParameters
       
            strTitle As String  'INPUT
            hwnd As LongPtr     'OUTPUT
       
        End Type
#Else
                   
    Private Declare Function EnumWindows Lib "user32" _
       (ByVal lpEnumFunc As Long, _
        ByVal lParam As Long) As Long
   
    Private Declare Function GetWindowText Lib "user32" _
        Alias "GetWindowTextA" _
       (ByVal hwnd As Long, _
        ByVal lpString As String, _
        ByVal cch As Long) As Long
        'Could use global variables instead, but this is nicer.
        'Custom structure for passing in the parameters in/out of the hook enumeration function
        'Could use global variables instead, but this is nicer.
        Private Type FindWindowParameters
       
            strTitle As String  'INPUT
            hwnd As Long        'OUTPUT
       
        End Type
#End If

'''experimental''''''''''''''''
Private Const WM_CHAR = &H102
Private Const BM_CLICK As Long = &HF5&

''' close the window
Private Const WM_SYSCOMMAND = &H112
Private Const SC_CLOSE = &HF060

#If VBA7 Then
Private Declare PtrSafe Function SendMessageBynum Lib "USER32" Alias "SendMessageA" (ByVal hwnd As LongPtr, ByVal wMsg As Long, ByVal wParam As LongPtr, lParam As Any) As LongPtr
Private Declare PtrSafe Function PostMessage Lib "USER32" Alias "PostMessageA" (ByVal hwnd As LongPtr, ByVal wMsg As Long, ByVal wParam As LongPtr, ByVal lParam As LongPtr) As Long

#Else
private Declare Function SendMessageBynum Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As any) As Long
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
#End If
'''''''''''''''''''''



#If VBA7 Then
Public Function FnFindWindowLike(strWindowTitle As String) As LongPtr

#Else
Public Function FnFindWindowLike(strWindowTitle As String) As Long
#End If
   
    'We'll pass a custom structure in as the parameter to store our result...
    Dim Parameters As FindWindowParameters
    Parameters.strTitle = UCase(strWindowTitle) ' Input parameter
   

#If VBA7 Then
    Call EnumWindows(AddressOf EnumWindowProc, VarPtr(Parameters))
#Else
    Call EnumWindows(AddressOf EnumWindowProc, VarPtr(Parameters))
#End If
    FnFindWindowLike = Parameters.hwnd
   
End Function

#If VBA7 Then
Private Function EnumWindowProc(ByVal hwnd As LongPtr, _
                               lParam As FindWindowParameters) As LongPtr
#Else
Private Function EnumWindowProc(ByVal hwnd As Long, _
                               lParam As FindWindowParameters) As Long
#End If
   Dim strWindowTitle As String

   strWindowTitle = Space(260)
   Call GetWindowText(hwnd, strWindowTitle, 260)
   strWindowTitle = UCase(TrimNull(strWindowTitle)) ' Remove extra null terminator
                                         
   If strWindowTitle Like lParam.strTitle Then
 
        lParam.hwnd = hwnd 'Store the result for later.
        EnumWindowProc = 0 'This will stop enumerating more windows
 
   Else

        EnumWindowProc = 1

   End If
                         
End Function

Private Function TrimNull(strNullTerminatedString As String)

    Dim lngPos As Long

    'Remove unnecessary null terminator
   
    lngPos = InStr(strNullTerminatedString, Chr$(0))
 
    If lngPos Then
        TrimNull = Left$(strNullTerminatedString, lngPos - 1)
    Else
        TrimNull = strNullTerminatedString
    End If
   'Debug.Print TrimNull
End Function




Public Function killWindow(ByVal strWindowTitle As String)
#If VBA7 Then
    Dim hwnd As LongPtr
#Else
    Dim hwnd As Long
#End If
    hwnd = FnFindWindowLike(strWindowTitle & "*")
   
    If hwnd <> 0 Then
        SendMessageBynum hwnd, WM_SYSCOMMAND, SC_CLOSE, 0&
    End If
End Function
change your code:
Code:
Private Sub cmdCancel_Click()
On Error GoTo Err_cmdCancel_Click

If IsMember(GetCurrentDomain, "FIELD ACCESS", GetCurrentUser) Then

'arnelgp'
KillWindow "*database*"

'Shell ("C:\BusiVine\Shutdown.bat")
Application.Quit
Else
Application.Quit
End If

Exit_cmdCancel_Click:
Exit Sub

Err_cmdCancel_Click:
Resume Exit_cmdCancel_Click

End Sub
 

Rachael2211

Member
Local time
Today, 06:13
Joined
Oct 24, 2013
Messages
33
;) thank you so much for your reply will give it a try
 

arnelgp

..forever waiting... waiting for jellybean!
Local time
Today, 21:13
Joined
May 7, 2009
Messages
19,169
please do try first.
 

arnelgp

..forever waiting... waiting for jellybean!
Local time
Today, 21:13
Joined
May 7, 2009
Messages
19,169
on second thought, since you Terminate MSA, you cannot call the batch file to Shutdown the PC.

another alternative is to create a VBscript that will terminate MSA from outside:
Code:
'https://stackoverflow.com/questions/52231543/how-to-close-terminate-kill-an-instance-of-a-application-with-vbs
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

Set colProcessList = objWMIService.ExecQuery _
    ("Select * from Win32_Process Where Name = 'msaccess.exe'")

For Each objProcess in colProcessList
    objProcess.Terminate()
Next
save it as KillMSA.vbs
you add it to the batch file:

Call path\KillMSA.vbs
shutdown /l /f

same, thing with ur orig, call the batch file from msa.
 

Rachael2211

Member
Local time
Today, 06:13
Joined
Oct 24, 2013
Messages
33
Thanks arnelgp, so you think my original idea is not a good one? I will try your second idea too, thank you for taking the time to help :)
 

arnelgp

..forever waiting... waiting for jellybean!
Local time
Today, 21:13
Joined
May 7, 2009
Messages
19,169
have not tried your first code.
it's only a suggestion, if your first code works, go for it.
 

Isaac

Lifelong Learner
Local time
Today, 06:13
Joined
Mar 14, 2017
Messages
8,738
Hi All,

My split application is used on an RDP in a multi-user environment. Field Access groups when they logon have the application launch then when they close out of it it disconnects them from the server/rdp. To do this I run a batch file just before the application.quit to disconnect user from server BUT...it doesn't kill the instance of MSaccess.exe for that user in the task manager SO...my though is to incorporate the shutting down of MSAccess.exe into the batch file and the "quit" button would just call it instead of calling it then using application.quit which I dont think executes because the batch file disconnects user first.

Heres my closing routine from a button on the menu of my application:

Function IsMember(strDomain As String, strGroup _
As String, strMember As String) As Boolean

Dim grp As Object
Dim strPath As String

strPath = "WinNT://" & strDomain & "/"
Set grp = GetObject(strPath & strGroup & ",group")
IsMember = grp.IsMember(strPath & strMember)
End Function

Function GetCurrentUser() As String
GetCurrentUser = Environ("USERNAME")
End Function

Function GetCurrentDomain() As String
GetCurrentDomain = Environ("USERDOMAIN")
End Function

Private Sub cmdCancel_Click()
On Error GoTo Err_cmdCancel_Click

If IsMember(GetCurrentDomain, "FIELD ACCESS", GetCurrentUser) Then
Shell ("C:\BusiVine\Shutdown.bat")
Application.Quit
Else
Application.Quit
End If

Exit_cmdCancel_Click:
Exit Sub

Err_cmdCancel_Click:
Resume Exit_cmdCancel_Click

End Sub

Here is my thoughts for the batch and getting rid of the application.quit line:

@echo off
taskkill /im MSACCESS.EXE /t /f
Shutdown /l /f

I know the shutdown line works but am unsure about the correctness of the msaccess line, could some awesome expert person please give me the thumbs up that Im on the right track before I try to implement this on the server and give everyone a headache lol

thank you in advance, Rachael
taskkill /im MSACCESS.EXE /t /f
... that code did work for me, so seems like it's good.
 

Rachael2211

Member
Local time
Today, 06:13
Joined
Oct 24, 2013
Messages
33
Thank you all for replying!

Isladogs, thank you, that is exactly what i was looking for and you can use the command lines directly in the shell? didn't know that, cheers, will test it now. And the /t for timer makes sense allowing access to quit before the shell command shutsdown the server, cheers ;)
 

isladogs

MVP / VIP
Local time
Today, 13:13
Joined
Jan 14, 2017
Messages
18,186
Hi
Yes you can use any of the functions as part of your standard module code.
All have been successfully tested and used in apps with various clients.
I've never tried using them where someone is remotely connecting to another PC.
I see no reason why they wouldn't work but it would be good to have your feedback.

The timer switch is important and you may need to experiment with the delay to ensure success.
Do remember once started the code can't be interrupted so it is important to warn end users first
 

Users who are viewing this thread

Top Bottom