Solved

Close a program in VB6?

Posted on 2003-11-09
21
27,267 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 4
  • 3
  • +6
21 Comments
 
LVL 11

Expert Comment

by:bingie
ID: 9710618
0
 
LVL 1

Author Comment

by:MarcGraff
ID: 9710688
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
ID: 9710704
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
Revamp Your Training Process

Drastically shorten your training time with WalkMe's advanced online training solution that Guides your trainees to action.

 
LVL 11

Expert Comment

by:bingie
ID: 9710728
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
ID: 9710795
The application being closed is not visible, therefore I do not know the caption.

   - Marc
0
 
LVL 86

Accepted Solution

by:
Mike Tomlinson earned 500 total points
ID: 9710991
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
ID: 9714778
hearing...
0
 
LVL 1

Author Comment

by:MarcGraff
ID: 9726694
Thanks, sorry for the wait...

   - Marc
0
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 9726838
No Problem....Glad I could help.
0
 

Expert Comment

by:JoceRakower
ID: 10061724
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
 
LVL 86

Expert Comment

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

Expert Comment

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

Expert Comment

by:JoceRakower
ID: 10073656
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 86

Expert Comment

by:Mike Tomlinson
ID: 10074388
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
ID: 10102874
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
ID: 10143583
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
ID: 10148328
OK will try, thanks :-)
0
 

Expert Comment

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

Expert Comment

by:pithhelmet
ID: 14131840


Posted answer fails under win2k3

anyone have a workaround?

0
 

Expert Comment

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

Expert Comment

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

Works on XP sp2


Thanks Steve
0

Featured Post

PeopleSoft Has Never Been Easier

PeopleSoft Adoption Made Smooth & Simple!

On-The-Job Training Is made Intuitive & Easy With WalkMe's On-Screen Guidance Tool.  Claim Your Free WalkMe Account Now

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
VBA filters 2 81
message box in access 4 55
Zip Folders Using Chilkat Routines 1 86
Sub or Function is not defined 6 59
When trying to find the cause of a problem in VBA or VB6 it's often valuable to know what procedures were executed prior to the error. You can use the Call Stack for that but it is often inadequate because it may show procedures you aren't intereste…
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 Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

739 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