VB6 'run-time error '424': Object Required' error - vb6

I am testing code before adding to an existing project. It ran perfectly when it looked like this:
Option Explicit
Dim objShell As Object
Dim m_EngineRun As Object
Sub main()
Set objShell = CreateObject("WScript.Shell")
Set m_EngineRun = objShell.Exec("notepad.exe")
Dim objWMIService As Object
Dim colProcessList As Object
MsgBox m_EngineRun.ProcessID
Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
Set colProcessList = objWMIService.ExecQuery("Select * from Win32_Process Where ProcessID = " & m_EngineRun.ProcessID)
If colProcessList.Count = 1 Then
objShell.run "TASKKILL /F /IM " & m_EngineRun.ProcessID, , True
MsgBox m_EngineRun.ProcessID & (" terminated")
Else
MsgBox m_EngineRun.ProcessID & (" does not exist")
End If
End Sub
Then I added the lines below and it fails with the 424 error.
Option Explicit
Dim objShell As Object
Dim m_EngineRun As Object
'Added this line
Dim m_PID As Object
Sub main()
Set objShell = CreateObject("WScript.Shell")
Set m_EngineRun = objShell.Exec("notepad.exe")
'And this line
Set m_PID = m_EngineRun.ProcessID
Dim objWMIService As Object
Dim colProcessList As Object
'And changed this one
MsgBox m_PID
Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
Set colProcessList = objWMIService.ExecQuery("Select * from Win32_Process Where ProcessID = " & m_EngineRun.ProcessID)
If colProcessList.Count = 1 Then
objShell.run "TASKKILL /F /IM " & m_EngineRun.ProcessID, , True
MsgBox m_EngineRun.ProcessID & (" terminated")
Else
MsgBox m_EngineRun.ProcessID & (" does not exist")
End If
End Sub
It is definitely the Set m_PID = m_EngineRun.ProcessID line that is the troublemaker.
I simply haven't been able to find an answer that pertains my specific issue. I feel like maybe m_PID shouldn't be an object? But if so, what should it be?
Any help is greatly appreciated.

ProcessID isn't an object; it's an integer (the numeric process ID).
Remove the As Object and Set, and just assign directly:
Dim m_PID
'....
m_PID = m_EngineRun.ProcessID
It's probably better to not presume that everything is an object, because the vast majority of things you'll encounter are probably not. I'd start with not expecting an object unless you know otherwise, and then move to trying object if you encounter issues.

Related

How to get running application name by vbscript

I would like to get the name list of running application by vbscript and kill the application by its main window title. Those applications should be listed on Task Manager -> Applications tab
Like this:
After searching from web, I found vbscript like this:
'FUNCTION
Function ListProcessRunning()
'This function can report names from
'TaskManager -> Processes
sComputerName = "."
Set objWMIService = GetObject("winmgmts:\\" & sComputerName & "\root\cimv2")
sQuery = "SELECT * FROM Win32_Process"
Set objItems = objWMIService.ExecQuery(sQuery)
'iterate all item(s)
For Each objItem In objItems
WScript.Echo objItem.Name
Next
End Function
This vbscript list all process names which are under Task Manager -> Processes tag like this:
Which is not what I want.
I also found this:
'FUNCTION
Function ListApplicationRunning()
'This function can report names from
'TaskManager -> Application
Set Word = CreateObject("word.application")
For Each x In Word.Tasks
WScript.Echo x.Name
Next
Word.Quit
Set Word = Nothing
End Function
Which really give me what I want but the problem is the server I am going to run this script has no Word so no word.application for vbscript and I am not able to install one for it.
My question is how to get the application name and kill the application by that name? I am not sure is it possible to do with vbscript only, may be a combination of vbscript and cmd is also okay.
In vbscript we can do something like that just give a try with it :
Option Explicit
Call KillProcessbyName("common-api.jar")
'*********************************************************************************
Sub KillProcessbyName(FileName)
On Error Resume Next
Dim WshShell,strComputer,objWMIService,colProcesses,objProcess
Set WshShell = CreateObject("Wscript.Shell")
strComputer = "."
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colProcesses = objWMIService.ExecQuery("SELECT * FROM Win32_Process")
For Each objProcess in colProcesses
If InStr(objProcess.CommandLine,FileName) > 0 Then
If Err <> 0 Then
MsgBox Err.Description,VbCritical,Err.Description
Else
objProcess.Terminate(0)
End if
End If
Next
End Sub
'**********************************************************************************
FOR /F "usebackq tokens=1-2" %i IN (`tasklist ^|findstr /b "notepad"`) DO taskkill /PID %j

Close an open OneNote application using VBS

I'm trying to close an open OneNote application on a user's computer using VB Script. However, I cannot seem to get it to work. I need to close any open OneNotes before I run the rest of the VBS file. So far I've tried this, but doesn't work for OneNote.
Set oNote= CreateObject("WScript.Shell")
oNote.Exec "onenote"
oNote.Terminate
This is another code I've tried. Neither work.
Set oNote= CreateObject("onenote")
oNote.Quit
You can try like this way to kill Onenote.exe process
Option Explicit
Dim Process
Process = "Onenote.exe"
Call Kill(Process)
'****************************************************
Sub Kill(Process)
Dim Ws,Command,Execution
Set Ws = CreateObject("Wscript.Shell")
Command = "cmd /c Taskkill /F /IM "& Process &""
Execution = Ws.Run(Command,0,True)
Set Ws = Nothing
End Sub
'****************************************************
Or by this way :
Option Explicit
Dim objWMIService, objProcess, colProcess
Dim strComputer, strProcessKill
strComputer = "."
strProcessKill = "'Onenote.exe'"
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" _
& strComputer & "\root\cimv2")
Set colProcess = objWMIService.ExecQuery _
("Select * from Win32_Process Where Name = " & strProcessKill )
For Each objProcess in colProcess
objProcess.Terminate(1)
Next

Attempting to extract printers from users machine and then outputting to a text fill.

I am attempting to extract the printers from a users machine and then output to a text file but when I run the test I get a invalid procedure call or argument for this specific line of code.
Set objOutputFile = objFSO.OpenTextFile(outFile, ForAppending, True)
I have attempted to change OpenTextFileto CreateTextFile but I need the lines to appended to file as it will be running as a log on script.
I have done some research and used the Microsoft developer articles to help me debug the issue in the code but I don't have much experience in Visual Basic.
I have added the entire script to give context to the what is going on.
dim objComputerName, ObjNetwork , strText , objfile, StrComputer
dim wshnetwork
Set wshnetwork = CreateObject ("Wscript.network")
StrComputer = WshNetwork.ComputerName
If IsEmpty(StrComputer) Then Wscript.Quit
Set WshNetwork = CreateObject("WScript.Network")
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colInstalledPrinters = objWMIService.ExecQuery("Select * from Win32_Printer")
Set colItems = objWMIService.ExecQuery("Select * from Win32_ComputerSystem",,48)
Set WshShell = WScript.CreateObject("WScript.Shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")
outFile = "C:\scripts\Printers" & StrComputer
Set objOutputFile = objFSO.OpenTextFile(outFile, ForAppending, True)
For Each objPrinter in colInstalledPrinters
strTest = Left(objPrinter.Name, 2)
objOutputFile.WriteLine(objPrinter.Name)
objfile.close
Next
Set objPrinter = WshNetwork.EnumPrinterConnections
'Set objOutputFile = objFSO.OpenTextFile (filOutput, ForAppending, True)
If objPrinter.Count = 0 Then
WScript.Echo "No Printers Mapped "
else
For intDrive = 0 To (objPrinter.Count -1) Step 2
intNetLetter = IntNetLetter +1
printer = "UNC Path " & objPrinter.Item(intDrive) & " = " & objPrinter.Item(intDrive +1) & " Printer : " & intDrive
objOutputFile.WriteLine(printer)
Next
end if
objOutputFile.Close``*
Invalid procedure call or argument
You passed an invalid parameter in your procedure call. This could be because the parameter was out of range, or contained invalid data. Alternately, you may have invoked a procedure at an unexpected time.
To correct this error
Verify that the parameters being passed to the procedure are valid.
Verify that you are calling the function at an appropriate time.
My guess is this line is an ilegal filename.
outFile = "C:\scripts\Printers" & StrComputer
On my computer this is c:\scripts\PrintersSerenity which is probably not right that your text file is called PrintersSerenity without an extension.

close hta file with vbs not working?

Im trying to close a *.hta file ussing vbs but i cant get it to close I thoght the following would be the right way about ?
Set ws=CreateObject("WScript.Shell")
ws.Run "TASKKILL.exe /F /IM 1846.hta"
The image name of a running .hta is mshta.exe, because this program host the script. You'll have to think about identifying the desired process if there are more than one .hta running.
Perhaps doing something like that :
Option Explicit
Call FindProcessbyName("1846.hta")
'**********************************************************************************************
Sub FindProcessbyName(FileName)
On Error Resume Next
Dim WshShell,strComputer,objWMIService,colProcesses,objProcess
Set WshShell = CreateObject("Wscript.Shell")
strComputer = "."
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colProcesses = objWMIService.ExecQuery("SELECT * FROM Win32_Process")
For Each objProcess in colProcesses
If InStr(objProcess.CommandLine,FileName) > 0 Then
If Err <> 0 Then
MsgBox Err.Description,VbCritical,Err.Description
Else
objProcess.Terminate(0)
End if
End If
Next
End Sub
'**********************************************************************************************

Find Users E-Mail via SID using VBScript and Active Directory

I am parsing log messages about changes to user accounts on a windows system.
I want to notify the user about the changes so I need to retrieve their personal
information (First,Last, E-Mail) from Active Directory.
I already found a way to retrieve the username but that is only via WMI and not ADSI:
Function FindUser(Message)
Dim objWMIService
Dim strAccountRegex
Dim objRegex
Dim objMatch
Dim strComputer
Dim objUser
Dim objShell
strAccountRegex = "(\%\{[A-Z,0-9,\-]*\})"
strComputer = "."
Wscript.StdOut.writeLine "Querying WMI to retrieve user-data"
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set objShell = WScript.CreateObject("WScript.Shell")
Set objRegex = new RegExp
objRegex.Pattern= strAccountRegex
for each objMatch in objRegex.Execute(Message)
REM Wscript.StdOut.writeLine "Found an Account ID: " & objMatch.value
Dim strSID
strSID=NormalizeSID(objMatch.value)
REM Wscript.Echo "SID after escaping: " & strSID
Set objUser = objWMIService.Get _
("Win32_SID.SID='" & strSID & "'")
next
FindUser=objUser.ReferencedDomainName & "\" & objUser.AccountName
End Function
It works fine, but I would like to do it via Active Directory instead of going via WMI.
Can you help me?
OK. I found a way to do this via Active Directory.
For compeleteness here is the code:
REM Converts the SID into a from, that can be processed by WMI
Function NormalizeSid(strSidToNormalize)
Dim regEx,strReplace
strReplace=""
' Create regular expression.
Set regEx = New RegExp
regEx.Global = True
regEx.Pattern = "(%|{|})"
regEx.IgnoreCase = True
' Make replacement.
NormalizeSid = regEx.Replace(strSidToNormalize, strReplace)
End Function
REM Searches for a SID the in the Message that was passed as argument
REM SID returned will be of the form %{S-1-5-21-3968247570-3627839482-368725868-1110}
REM NOTE: Neither WMI nor ADSI will accept this. Use NormalizeSid like in FindUser
Function FindSidInMessage(Message)
Dim strAccountRegex
Dim objRegex
Dim objMatch
Dim strSID
strAccountRegex = "(\%\{S\-[,0-9,\-]*\})"
Set objRegex = new RegExp
objRegex.Pattern= strAccountRegex
for each objMatch in objRegex.Execute(Message)
REM Wscript.StdOut.writeLine "Found an Account ID: " & objMatch.value
strSID=objMatch.value
next
FindSidInMessage=strSID
End Function
REM Searches Directory for the User matching the SID passed as parameter
Function FindUser(userSID)
Dim normalizedSID
Dim objUser
normalizedSID=NormalizeSid(userSID)
Wscript.Echo "SID after escaping: " & normalizedSID
Wscript.StdOut.writeLine "Querying AD to retrieve user-data"
Set objUser = GetObject("LDAP://<SID="& normalizedSID & ">")
FindUser=objUser.EmailAddress
End Function
Hope this will be useful to others.

Resources