Solved

Close a program in VB6?

Posted on 2003-11-09
21
27,131 Views
Last Modified: 2011-08-18
Is there a way to close a program in VB6 with only knowing the file name "AL-Admin.exe"?

I have a way to close by caption but not by file name.

Public Sub CloseProgram(ByVal Caption As String)
    Dim Handle As Long
    Handle = FindWindow(vbNullString, Caption)
    If Handle = 0 Then Exit Sub
    SendMessage Handle, WM_CLOSE, 0&, 0&
End Sub

   - Marc
0
Comment
Question by:MarcGraff
  • 5
  • 4
  • 3
  • +6
21 Comments
 
LVL 11

Expert Comment

by:bingie
Comment Utility
0
 
LVL 1

Author Comment

by:MarcGraff
Comment Utility
The "Start and Stop Prossess" application can only close an application that it started. I need to close an application that is running.

   - Marc
0
 
LVL 11

Expert Comment

by:bingie
Comment Utility
Marc,

Try this:

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Const WM_CLOSE = &H10

Private Sub Form_Load()
   Dim lngHwnd As Long
   lngHwnd = FindWindow(vbNullString, "MyApp")
   SendMessage lngHwnd, WM_CLOSE, 0, 0
   End
End Sub
0
 
LVL 11

Expert Comment

by:bingie
Comment Utility
You can use this function to send Alt+F4 to the app thus closing it

Private Sub Closeapp(AppName as string)
AppActivate AppName
SendKeys "%{F4}"
End Sub

In the AppName string, include text from the Title bar of an application
0
 
LVL 1

Author Comment

by:MarcGraff
Comment Utility
The application being closed is not visible, therefore I do not know the caption.

   - Marc
0
 
LVL 85

Accepted Solution

by:
Mike Tomlinson earned 500 total points
Comment Utility
Yes it is possible.  Just pass the EXE name to kill into the function KillAppByEXE() and it will return true if it was killed or  false if it wasn't found or if there was some kind of error.  It should work on all versions of windows.

Just paste the code into a module and use the KillAppByExe() function.

Here is an example of how to use:

Private Sub Text1_KeyPress(KeyAscii As Integer)
    If KeyAscii = 13 Then
        If KillAppByEXEName(Trim(Text1.Text)) Then
            MsgBox "Killed!"
        Else
            MsgBox "Unable to find and/or kill"
        End If
        KeyAscii = 0
    End If
End Sub

Here is the code for the module:

Option Explicit

Public Declare Function TerminateProcess Lib "kernel32" ( _
    ByVal hProcess As Long, ByVal uExitCode As Long) As Long

Public Declare Function Process32First Lib "kernel32" ( _
    ByVal hSnapshot As Long, lppe As PROCESSENTRY32) As Long

Public Declare Function Process32Next Lib "kernel32" ( _
    ByVal hSnapshot As Long, lppe As PROCESSENTRY32) As Long

Public Declare Function CloseHandle Lib "Kernel32.dll" _
    (ByVal Handle As Long) As Long

Public Declare Function OpenProcess Lib "Kernel32.dll" _
    (ByVal dwDesiredAccessas As Long, ByVal bInheritHandle As Long, _
    ByVal dwProcId As Long) As Long

Public Declare Function EnumProcesses Lib "psapi.dll" _
    (ByRef lpidProcess As Long, ByVal cb As Long, _
    ByRef cbNeeded As Long) As Long

Public Declare Function GetModuleFileNameExA Lib "psapi.dll" _
    (ByVal hProcess As Long, ByVal hModule As Long, _
    ByVal ModuleName As String, ByVal nSize As Long) As Long

Public Declare Function EnumProcessModules Lib "psapi.dll" _
    (ByVal hProcess As Long, ByRef lphModule As Long, _
    ByVal cb As Long, ByRef cbNeeded As Long) As Long

Public Declare Function CreateToolhelp32Snapshot Lib "kernel32" ( _
    ByVal dwflags As Long, ByVal th32ProcessID As Long) As Long

Public Declare Function GetVersionExA Lib "kernel32" _
    (lpVersionInformation As OSVERSIONINFO) As Integer

Public Type PROCESSENTRY32
    dwSize As Long
    cntUsage As Long
    th32ProcessID As Long           ' This process
    th32DefaultHeapID As Long
    th32ModuleID As Long            ' Associated exe
    cntThreads As Long
    th32ParentProcessID As Long     ' This process's parent process
    pcPriClassBase As Long          ' Base priority of process threads
    dwflags As Long
    szExeFile As String * 260       ' MAX_PATH
End Type

Public Type OSVERSIONINFO
    dwOSVersionInfoSize As Long
    dwMajorVersion As Long
    dwMinorVersion As Long
    dwBuildNumber As Long
    dwPlatformId As Long           '1 = Windows 95   2 = Windows NT
    szCSDVersion As String * 128
End Type

Public Const PROCESS_QUERY_INFORMATION = 1024
Public Const PROCESS_VM_READ = 16
Public Const MAX_PATH = 260
Public Const TH32CS_SNAPPROCESS = &H2&
Public Const hNull = 0

Public Function StrZToStr(s As String) As String
    StrZToStr = Left$(s, Len(s) - 1)
End Function

Public Function getVersion() As Long
    Dim osinfo As OSVERSIONINFO
    Dim retvalue As Integer
    osinfo.dwOSVersionInfoSize = 148
    osinfo.szCSDVersion = Space$(128)
    retvalue = GetVersionExA(osinfo)
    getVersion = osinfo.dwPlatformId
End Function

Public Function KillAppByEXEName(NameOfEXE As String) As Boolean
    NameOfEXE = UCase(NameOfEXE)
    KillAppByEXEName = False ' Assume the worst
    Select Case getVersion()
        Case 1 'Windows 95/98
            Dim f As Long, sname As String
            Dim hSnap As Long, Proc As PROCESSENTRY32
            Dim ProcFromprocid As Long
            hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
            If hSnap = hNull Then
                Exit Function
            End If
            Proc.dwSize = Len(Proc)
            ' Iterate through the processes
            f = Process32First(hSnap, Proc)
            Do While f
                sname = StrZToStr(Proc.szExeFile)
                sname = UCase(Trim(sname))
                If InStr(sname, NameOfEXE) > 0 Then
                    ProcFromprocid = OpenProcess(PROCESS_QUERY_INFORMATION Or _
                        PROCESS_VM_READ, 0, Proc.th32ProcessID) ' get
                    Call TerminateProcess(ProcFromprocid, 0)
                    KillAppByEXEName = True
                    Exit Function
                End If
                f = Process32Next(hSnap, Proc)
            Loop

        Case 2 'Windows NT
            Dim cb As Long
            Dim cbNeeded As Long
            Dim NumElements As Long
            Dim ProcessIDs() As Long
            Dim cbNeeded2 As Long
            Dim NumElements2 As Long
            Dim Modules(1 To 200) As Long
            Dim lRet As Long
            Dim ModuleName As String
            Dim nSize As Long
            Dim hProcess As Long
            Dim i As Long
            'Get the array containing the process id's for each process object
            cb = 8
            cbNeeded = 96
            Do While cb <= cbNeeded
                cb = cb * 2
                ReDim ProcessIDs(cb / 4) As Long
                lRet = EnumProcesses(ProcessIDs(1), cb, cbNeeded)
            Loop
            NumElements = cbNeeded / 4

            For i = 1 To NumElements
                'Get a handle to the Process
                hProcess = OpenProcess(PROCESS_QUERY_INFORMATION _
                    Or PROCESS_VM_READ, 0, ProcessIDs(i))
                'Got a Process handle
                If hProcess <> 0 Then
                    'Get an array of the module handles for the specified
                    'process
                    lRet = EnumProcessModules(hProcess, Modules(1), 200, _
                        cbNeeded2)
                    'If the Module Array is retrieved, Get the ModuleFileName
                    If lRet <> 0 Then
                        ModuleName = Space(MAX_PATH)
                        nSize = 500
                        lRet = GetModuleFileNameExA(hProcess, Modules(1), _
                            ModuleName, nSize)
                           
                        ModuleName = UCase(Trim(ModuleName))
                        If InStr(ModuleName, NameOfEXE) > 0 Then
                            Call TerminateProcess(hProcess, 0)
                            KillAppByEXEName = True
                            Exit Function
                        End If
                    End If
                End If
                'Close the handle to the process
                lRet = CloseHandle(hProcess)
            Next
    End Select
End Function

Regards,

Idle_Mind
0
 
LVL 16

Expert Comment

by:Richie_Simonetti
Comment Utility
hearing...
0
 
LVL 1

Author Comment

by:MarcGraff
Comment Utility
Thanks, sorry for the wait...

   - Marc
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
Comment Utility
No Problem....Glad I could help.
0
 

Expert Comment

by:JoceRakower
Comment Utility
Comment for Idle_Mind - brilliant, returns the "Killed!" message box no problems - but appears that application to be killed is still running quite happily (?) Excel in this case .... I've copied your code from above and used it "raw" so where have I lost the plot?  Cheers & thanks.  Joce
0
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 
LVL 85

Expert Comment

by:Mike Tomlinson
Comment Utility
Haven't tried it with excel...let me see if I can kill it on my system.
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
Comment Utility
I just killed Excel on my system with "excel.exe".  How are you using it?
0
 

Expert Comment

by:JoceRakower
Comment Utility
I've added a new module to a standard VB project and added and run from within the Visual Studio the following sub main - it comes back with the message but the excel app is still running ?

thanks :-)

Public Sub main()

Dim appName As String

appName = "Excel.exe"

        If KillAppByEXEName(appName) Then
            MsgBox "Killed!"
        Else
            MsgBox "Unable to find and/or kill"
        End If

End Sub
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
Comment Utility
Interesting...I'm running Office XP (Excel 2002 10.5815.4219 SP-2) on Win ME.

What are you running?

Have you tried killing something simple like calculator (calc.exe) to determine if the code even works correctly on your system?

Idle_Mind
0
 

Expert Comment

by:JoceRakower
Comment Utility
Hello

I'm running O2K on W2K pro (latest service packs for both) - I've tried and get the same results with the calculator - I really appreciate you help - thanks

Joce
0
 

Expert Comment

by:btsai
Comment Utility
i had the same problem with trying to kill an ActiveX EXE process that was started by Set XXX = New ActiveXEXE.className

it wasn't terminating until i added:

Private Const PROCESS_TERMINATE = (&H1)
in the declarations and changed the line

              hProcess = OpenProcess(PROCESS_QUERY_INFORMATION _
                    Or PROCESS_VM_READ, 0, ProcessIDs(i))

to

              hProcess = OpenProcess(PROCESS_TERMINATE  or PROCESS_QUERY_INFORMATION _
                    Or PROCESS_VM_READ, 0, ProcessIDs(i))

if doing this with an ActiveX EXE process, make sure to set the object declaration to Nothing after killing the process otherwise you will not be able to instantiate it again.
0
 

Expert Comment

by:JoceRakower
Comment Utility
OK will try, thanks :-)
0
 

Expert Comment

by:alanvranian
Comment Utility
I wasn't part of the original conversation, but this was really really helpful even now, thanks!
Alan
0
 

Expert Comment

by:pithhelmet
Comment Utility


Posted answer fails under win2k3

anyone have a workaround?

0
 

Expert Comment

by:alanvranian
Comment Utility
now thats not good news....  thanks for the heads up pith
0
 

Expert Comment

by:steve_jw
Comment Utility
             hProcess = OpenProcess(PROCESS_TERMINATE  or PROCESS_QUERY_INFORMATION _
                    Or PROCESS_VM_READ, 0, ProcessIDs(i))

Works on XP sp2


Thanks Steve
0

Featured Post

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
VB6 convert MSHFlexgrid1 cells 7 51
Window placement 17 64
Help in WHSCRIPT 9 41
vb6 connector to SQL Server 2 32
The debugging module of the VB 6 IDE can be accessed by way of the Debug menu item. That menu item can normally be found in the IDE's main menu line as shown in this picture.   There is also a companion Debug Toolbar that looks like the followin…
Background What I'm presenting in this article is the result of 2 conditions in my work area: We have a SQL Server production environment but no development or test environment; andWe have an MS Access front end using tables in SQL Server but we a…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now