How can I kill task manager processes through VBA code? - excel

I'm trying to kill certain processes through VBA. I have a proprietary object that connects to a market data bus. Through RTD I call this object to pub/sub to the bus. However sometimes the connection drops and I need to kill the process via task manager. Is there a way to kill a process through VBA?
Thanks

Try with this code
Dim oServ As Object
Dim cProc As Variant
Dim oProc As Object
Set oServ = GetObject("winmgmts:")
Set cProc = oServ.ExecQuery("Select * from Win32_Process")
For Each oProc In cProc
'Rename EXCEL.EXE in the line below with the process that you need to Terminate.
'NOTE: It is 'case sensitive
If oProc.Name = "EXCEL.EXE" Then
MsgBox "KILL" ' used to display a message for testing pur
oProc.Terminate()
End If
Next

Take a look at one more example:
Sub Test()
If TaskKill("notepad.exe") = 0 Then MsgBox "Terminated" Else MsgBox "Failed"
End Sub
Function TaskKill(sTaskName)
TaskKill = CreateObject("WScript.Shell").Run("taskkill /f /im " & sTaskName, 0, True)
End Function

You can perform it, this way:
Dim oServ As Object
Dim cProc As Variant
Dim oProc As Object
Set oServ = GetObject("winmgmts:")
Set cProc = oServ.ExecQuery("Select * from Win32_Process")
For Each oProc In cProc
'Rename EXCEL.EXE in the line below with the process that you need to Terminate.
'NOTE: It is 'case sensitive
If oProc.Name = "EXCEL.EXE" Then
MsgBox "KILL" ' used to display a message for testing pur
oProc.Terminate 'kill exe
End If
Next

Sub Kill_Excel()
Dim sKillExcel As String
sKillExcel = "TASKKILL /F /IM Excel.exe"
Shell sKillExcel, vbHide
End Sub

Related

How can I solve the Compilation error: syntax error on my VBA sub?

I have this sub that are calling for execute other two subs in the program, but when I try to execute it pops up the Compilation error: syntax error right on the fisrt line of the sub.
Sub MacroPrimaria()
Call SAPOpenSessionFromLogon
Application.Wait Now + TimeValue("00:00:05")
Call executarsap
MsgBox ("PROCESSAMENTO FINALIZADO")
End Sub
Sub SAPOpenSessionFromLogon()
Dim SapGui
Dim Applic
Dim connection
Dim session
Dim WSHShell
Shell "C:\Program Files (x86)\SAP\FrontEnd\SAPgui\saplogon.exe", vbNormalFocus
Set WSHShell = CreateObject("WScript.Shell")
Do Until WSHShell.AppActivate("SAP Logon ")
Application.Wait Now + TimeValue("0:00:01")
Loop
Set WSHShell = Nothing
Set SapGui = GetObject("SAPGUI")
Set Applic = SapGui.GetScriptingEngine
Set connection = Applic.OpenConnection("S/4 HANA - PRODUÇÃO", True)
Set session = connection.Children(0)
session.findById("wnd[0]").maximize
End Sub
Sub executarsap()
Dim Application, SapGuiAuto, connection, session, WScrip
'**IMPORTANTE**: Abaixo daqui, basta colar o scrip gerado pela gravação do SAP, sem retirar nada:
'This sub it's okay and has confidential stuff so its just to know.
End Sub
I'm gettin stuck with this error on the lines:
"Sub MacroPrimaria()"
"Sub SAPOpenSessionFromLogon()"
I'm expecting to get able to execute the macro
Your code isn't giving a compile error for me.
This is the code I use to interact with SAP and it hasn't given me any problems so far (can't remember where I found it on the Internet though).
It may help.
Public Sub Execute_SAP()
'Login details here.
Dim LogInDetail As Variant
LogInDetail = Array("***YOUR USER NAME***", "***YOUR PASSWORD***")
'Open the SAP Log-In screen and wait for it to load.
Shell "C:\Program Files (x86)\SAP\FrontEnd\SAPgui\saplogon.exe", 4
Dim WshShell As Object
Set WshShell = CreateObject("WScript.Shell")
Do Until WshShell.AppActivate("SAP Logon ")
Application.Wait Now + TimeValue("0:00:01")
Loop
Set WshShell = Nothing
Dim SAPGui As Object
Set SAPGui = GetObject("SAPGUI")
Dim Appl As Object
Set Appl = SAPGui.GetScriptingEngine
Dim Connection As Object
Set Connection = Appl.OpenConnection("S/4 HANA - PRODUÇÃO", True)
Dim Session As Object
Set Session = Connection.Children(0)
With Session
'Log-in to the session.
.findById("wnd[0]/usr/txtRSYST-MANDT").Text = "300"
'The next two lines accept the username and password - LogInDetail variant holds those two values.
.findById("wnd[0]/usr/txtRSYST-BNAME").Text = LogInDetail(0)
.findById("wnd[0]/usr/pwdRSYST-BCODE").Text = LogInDetail(1)
.findById("wnd[0]/usr/txtRSYST-LANGU").Text = "EN"
.findById("wnd[0]").maximize
.findById("wnd[0]").SendVKey 0 'ENTER
'Rest of SAP code - each line starts with
' .findById("wnd[0]
'Use SAPs macro recorder to get the detail... is probably what you've got in executearsap()
End With
End Sub
thanks for the help!!
Apparently the file that I created the script was corrupted, when I create a new file the code runs properly.

Get hard disk serial number on Windows Server with VBA

I want to get hard disk serial number on Windows Server with VBA.
My code works just perfect on regular Windows but I get a Run-Time error 1004 with the message - Invalid number of arguments - when i'm trying to run it on a Windows Server OS.
This is the code:
Dim oWMI As Object
Dim oItems As Object
Dim oItem As Object
Dim IndexNumber As Integer
IndexNumber = 0
Set oWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
Set oItems = oWMI.ExecQuery("Select * from Win32_DiskDrive")
For Each oItem In oItems
If oItem.Index = IndexNumber Then
Msgbox Application.Trim(oItem.SerialNumber)
Exit For
End If
Next
Any ideas how to make it work ?
One alternative to try:
Sub Tester()
Dim s As String, arr, e
s = ExecShellCmd("wmic diskdrive get serialnumber")
Debug.Print "----------------------------"
Debug.Print s
arr = Split(s, vbLf)
Debug.Print "----------------------------"
Debug.Print arr(1)
End Sub
Public Function ExecShellCmd(FuncExec As String) As String
ExecShellCmd = VBA.CreateObject("WScript.Shell") _
.exec("cmd.exe /c " & FuncExec).stdout.readall
End Function

How do I close an Excel spreadsheet in VBA code?

I have the following routine below that is meant to open an Excel spreadsheet and then go row by row to import the results into a table that is passed in. It works fine but the problem is if I try to open that same spreadsheet a second time I get a message that the file is in use and I have to Ctrl-Alt-Del to shut down Excel before I can use it again. I thought that the Set mySheet=Nothing and Set xlApp=Nothing would release the file but apparently not. What more can I do to make sure that Access lets go of the Excel file? Thanks in advance!
Public Sub MakeTempTable(strFilePath As String, tablename As String)
Dim mySheet As Object
Dim xlApp As Object
Dim rs As DAO.Recordset
Dim sql As String
sql = "DELETE * FROM " & tablename
DoCmd.RunSQL sql
Set rs = CurrentDb.OpenRecordset(tablename)
Set xlApp = CreateObject("Excel.Application")
Set mySheet = xlApp.Workbooks.Open(strFilePath).Sheets(1)
xlApp.Visible = False
Set mySheet = xlApp.Sheets("Input")
Dim dRows As Double
dRows = 1
Dim dRow As Double, dCol As Double
dRow = 2
On Error GoTo ERR
Do
dCol = 1
rs.AddNew
If mySheet.cells(dRow, 3) = "" Then Exit Do
Do
If mySheet.cells(dRow, dCol).Value <> "_END_" Then
rs.Fields(dCol).Value = Nz(mySheet.cells(dRow, dCol).Value, "")
dCol = dCol + 1
Else
Exit Do
End If
Loop
rs.Update
dRow = dRow + 1
Loop
EXITSUB:
Set mySheet = Nothing
Set xlApp = Nothing
Exit Sub
ERR:
If ERR.Number = 3265 Then MsgBox "The species selected are incompatible. Canceling import.", vbCritical, "IMPORT ERROR"
GoTo EXITSUB
End Sub
Try using
xlApp.Quit
When you set xlApp to nothing you are only clearing the object within the procedure, you aren't doing anything to the actual Excel instance. All that setting XXX = nothing allows you to do is then reuse that object.
You will need to legally close the workbooks that are open as in
xlApp.Workbooks.Close
EXITSUB:
This will close the instances that are open.
Prior to this, kill all the instances or reboot your machine to clear all the instances that are open.

objProcess.Terminate not Found specific to iexplore.exe

When terminating internet explorer within VBA I'm using the following code sourced (more or less) from stackoverflow:
Sub IE_Sledgehammer()
Dim objWMI As Object, objProcess As Object, objProcesses As Object
Set objWMI = GetObject("winmgmts://.")
Set objProcesses = objWMI.ExecQuery( _
"SELECT * FROM Win32_Process WHERE Name = 'iexplore.exe'")
MsgBox "iexplore.exe processes = " & objProcesses.Count
For Each objProcess In objProcesses
Call objProcess.Terminate
Next
Set objProcesses = Nothing: Set objWMI = Nothing
End sub
The number of processes returned is "2" (which is correct) but in the first iteration of the For loop, when the first iexplore.exe is terminated that also terminates the second process and so in the second loop iteration a 'not found' error occurs. I understand that this is because closing one iexplorer.exe process closes all iexplore.exe tasks.
My question is, how can I reference and terminate only the first 'objprocess' in the objprocesses list OR force the For loop to exit after one iteration?
Do you mean you want to close the first tab or IE window?
I suggest you create an object of Shell and loop through IE windows.
You can close the first IE window and exit the loop or you can match the title of the IE window and close that specific IE window.
You need to add the reference to Microsoft Shell Controls and Automation and Microsoft Internet Controls.
Code:
Sub demo()
Dim oShellWin As Shell
Dim oWin As Object
Dim objIE As InternetExplorer
Set oShellWin = New Shell
For Each objIE In oShellWin.Windows
If TypeName(objIE.Document) = "HTMLDocument" Then
'Debug.Print objIE.Document.Title
If objIE.Document.Title = "Bing" Then 'User can modify the title here...
objIE.Quit
Exit For
End If
End If
Next objIE
End Sub
Output:
Further, you can try to modify the code as per your requirement.

swbemobjectex class ghost/hidden methods (eg. .Terminate)

Dim objList As WbemScripting.SWbemObjectSet
Set objList = GetObject("winmgmts:").ExecQuery("select * from win32_process where name='iexplore.exe'")
This code returns a collection of SWbemObjectEx objects
relating to all the running processes "iexplore.exe" (as seen in task manager).
I read on the web that I can run the method .Terminate of these objects to kill them.
However, neither the Locals window while in breakmode nor the Object Browser for the "SWbemObjectEx" class, nor the official doc at https://learn.microsoft.com/it-ch/windows/win32/wmisdk/swbemobjectex, show this method .Terminate.
And what surprises me is that it works, although not for all the objects...
Why? and how could I see all these hidden(?) methods for this class?
try this code:
Option Explicit
Sub funTaskTerminate()
Dim objTask As Object
Dim objProcesses As Object
Dim objProcess As Object
' Set the object for Task Manager
Set objTask = GetObject("winmgmts:")
' Set the object for all the processes in query
Set objProcesses = objTask.ExecQuery("select * from win32_process where name='iexplore.exe'")
' Loop for all processes in query
For Each objProcess In objProcesses
' In my test, there were 3 processes, but the first Terminate () killed all the others, therefore,
' in the second Terminate () the process no longer existed,
' which caused an error, so the use of "Resume Next".
'------------------------------------------
On Error Resume Next
Call objProcess.Terminate ' Terminate the process
On Error GoTo 0
Next
Set objTask = Nothing
Set objProcesses = Nothing
Set objproces = Nothing
End Sub
The .Terminate method is part of the Win32_Process class. Put a breakpoint onCall objProcess.Terminateand add a watch onobjProcess. That will show you a.Methods_collection, where second item is.Terminate.
Also note the.Properties_collection to get infos on that process (e.g handle).
This sub prints the collections to the immediate window, just call it inside the loop throughobjProcesses, e.g.
...
For Each objProcess In objProcesses
PrintPropertiesAndMethods objProcess
...
Private Sub PrintPropertiesAndMethods(Process As WbemScripting.SWbemObjectEx)
With Process
Debug.Print vbCrLf & "Properties_ collection:"
Dim Prop As WbemScripting.SWbemProperty
For Each Prop In .Properties_
With Prop
Debug.Print .Name & " " & .Value
End With
Next
Debug.Print vbCrLf & "Methods_ collection:"
Dim Method As WbemScripting.SWbemMethod
For Each Method In .Methods_
With Prop
Debug.Print Method.Name
End With
Next
End With
End Sub
You have to be carefull when terminateiexploror.exeas it has a main process (x64 - C:\Program Files\Internet Explorer), that creates a child process (x86 - C:\Program Files (x86)\Internet Explorer) for each tab (check in task-manager). If you terminate the main process, all childs will terminate too. Too get a second main process for testing, use Run as Admin.

Resources