Recently in VB and VBScript Category

VBScript to Determine a PC's Need for a Reboot

| No Comments | No TrackBacks

From time to time in Windows administration and patch management, it's necessary to know whether a machine you're about to do something to is waiting on a reboot. When an installer program needs to replace a file that's in use, it can't do that, so it places the file on the disk with a temporary name and places a value in the Windows Registry to indicate that the file needs to be renamed at the next reboot. Therefore, if you want to detect whether a given machine needs a reboot in order to complete the work of a previously-applied hotfix, patch, or software install, you can look at that value in the Registry to see if there's any work to be done on the next reboot. If there is, the machine needs a reboot. If there's nothing there, the machine doesn't need a reboot.

The Registry key you need to examine is a MultiString Value called, aptly enough "PendingFileRenameOperations" located on the following Registry path:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager

Below is a sample VBScript to perform a test of the local or a remote machine to see if a reboot is needed based on the PendingFileRenameOperations key. The script must be run with Administrator permission on the system to be checked. If run without Administrator permission, the script will be unable to connect with the remote machine and an error will be displayed.

When executed, the script prompts for the name of a PC on the network, which can be the PC you're using at the time. If no PC name is entered, the script aborts. Otherwise, it makes a Windows Management Instrumentation (WMI) call to the Registry provider on the remote machine and requests the value of the PendingFileRenameOperations key. If an actual value is found, this means that PC requires a reboot. If no value is found or the key isn't there, then the PC does not require a reboot. A message is displayed for the user indicating if the machine in question does or does not need to be rebooted.

I hope you'll find the script useful.

dim oReg

'
' Set a constant we'll use later
'
Const HKEY_LOCAL_MACHINE = &H80000002

'
' Ask the user for a PC name to check and abort if they
' don't give us one.
'
strComputer = InputBox("Which PC do you want to check?",_
                 "Reboot Need Checker")

if strComputer="" then
  wscript.quit
end if

thePC = ltrim(rtrim(strComputer))

'
' Use the Windows Management Instrumentation (WMI) capability
' to connect to the remote computer's Registry provider.
'
on error resume next
set oReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _
           strComputer & "\root\default:StdRegProv")

If Err.Number <> 0 Then
   MsgBox "Could not connect with WMI to PC " & strComputer & _
          "'s Registry.", vbOKOnly, "ERROR!"
   wscript.quit
End If

'
' Use the WMI Registry Provider to look up the reboot status in
' the remote PC's Registry. Display an error if we can't do it.
'
strvalue = "NOTHING"
strKeyPath = "SYSTEM\CurrentControlSet\Control\Session Manager"
strValueName = "PendingFileRenameOperations"

oReg.GetMultiStringValue HKEY_LOCAL_MACHINE,_
                         strKeyPath,_
						 strValueName,_
						 arrValues

If Err.Number <> 0 Then
     MsgBox "Could not read reboot status for the PC " & _
	        strComputer, vbOKOnly, "ERROR!"
     wscript.quit
End If
    
'
' If arrValues returns a non-zero value below, then there are filenames in
' the PendingFileRenameOperations key, and therefore a reboot
' is needed to complete those rename operations.
'
if arrvalues > 0 then

   msgbox strComputer & " requires a reboot at this time. ", _
          vbokonly,"Reboot Needed"

else

   msgbox strComputer & " does not require a reboot. ", _
          vbokonly,"No Reboot Needed"
   wscript.quit

end if

Create a Desktop Shortcut with VBScript

| No Comments | No TrackBacks

If you're trying to sort out how to create a Windows Shortcut on the desktop from within VBScript (or VB6) the following code should do the trick for you.  It creates a shortcut on your desktop that launches the Notepad application.  With some modification, it should allow you to create any desktop shortcut you need.

Set WSHShell = WScript.CreateObject("WScript.Shell")

' Use WshSpecialFolders object to get to the Desktop
DesktopPath = WSHShell.SpecialFolders("Desktop")

' Use the Shell to create a shortcut to Notepad on the desktop
Set theShortcut = WSHShell.CreateShortcut(DesktopPath & "\Shortcut to notepad.lnk")

' Set shortcut object properties and save it
theShortcut.TargetPath = WSHShell.ExpandEnvironmentStrings("%windir%\notepad.exe")
theShortcut.WorkingDirectory = WSHShell.ExpandEnvironmentStrings("%windir%")
theShortcut.WindowStyle = 4
theShortcut.IconLocation = WSHShell.ExpandEnvironmentStrings("%windir%\notepad.exe, 0")
theShortcut.Save

In the last installment of this series, we looked at how you gain access to the HTML code of a web page using the Visual Basic 6 WebBrowser object.   That's a good first step toward doing something a bit more interesting, which is completing a web form using the VB6 WebBrowser object.

Last time around we wrote a simple program that took a look at my home page and showed you the HTML. Now, we're going to use the information we learned there to figure out how to automatically search my site for anything mentioning Visual Basic.

The first step is to identify the form used on my site for the search function. As it turns out, the search form on my site is contained in the following code:

<FORM action=index.php
method=post>
<DIV class=searchblock
id=searchblock>Enter Keywords: <INPUT class=inputbox
onblur="if(this.value=='') this.value='search...';"
style="WIDTH: 128px" onfocus="if(this.value=='search...')
this.value='';" size=15 value=search... name=searchword>
<INPUT type=hidden value=search name=option
<DIV
align=left><INPUT class=button style="WIDTH: 35px"
type=submit value=GO> </DIV></DIV> </FORM>

Since this is the first form in this particular web document, we should be able to access it as "Forms(0)" through the WebBrowser.Document object's "Forms()" collection. (If it had been the second form to appear on the page, we'd use "Forms(1)", etc.)   To see if this is the case, we add the following code to the WebBrowser1_DocumentComplete event to read as follows:

Private Sub
WebBrowser1_DocumentComplete(ByVal pDisp As Object, URL As
Variant)
 If URL <> txtURL.Text Then Exit Sub 
If pDisp <> WebBrowser1.Object Then Exit Sub
txtHTMLDisplay.Text = WebBrowser1.Document.Body.innerhtml
txtURL.Text = WebBrowser1.LocationURL
WebBrowser1.Document.Forms(0).Item(0).Value = "Visual Basic"
End Sub

VBScript to Make M3U Files from Directories

| No Comments | No TrackBacks
I've been organizing my MP3 collection, off and on, for several months now.  A while ago I managed to get them all organized by artist and album, weed out duplicates, get the ID3v2 tags in place, etc.  (Then, of course, my MP3 player went south on me, but that's another story.)  The first thing I noticed when I started listening to some of them was that I didn't have a playlist file (*.m3u) for some of them.  I didn't really care to make one of those by hand, so it was time to make a script!

That led me to develop the following script (for Windows systems with VBScript installed, which is most of them after Windows 98):

Const WINDOW_HANDLE = 0
Const OPTIONS = 0

Set fso = CreateObject("Scripting.FileSystemObject")
Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.BrowseForFolder _
    (WINDOW_HANDLE, "Select a folder:", OPTIONS, "")

If objFolder Is Nothing Then
    Wscript.Quit
End If

Set objFolderItem = objFolder.Self
objPath = objFolderItem.Path

Set theFolder = fso.GetFolder(objPath)
Set filecoll = theFolder.Files
Set m3u = fso.CreateTextFile(objpath & "\" & theFolder.Name & ".m3u",vbTrue)

for each thisfile in filecoll
   theFile = thisFile.name
   If Instr(1,theFile,".mp3") > 0 THEN 
      m3u.WriteLine(theFile)
   End if
next

m3u.Close

The script works like this... Double-click it and you're presented with a Folder Selection Dialog box by Windows.  Use this dialog to navigate until you have selected a directory that contains a group of MP3s you want in the same playlist.  The script will parse the MP3 files out of that directory and build a playlist file for them.  The playlist file will be named to match the parent directory.

For example, imagine that I had a directory named "They Might Be Giants - No!" which contained the various tracks from the album "No!" by They Might Be Giants.  When I select that directory with the script, I'll end up with a file named "They Might Be Giants - No!.m3ui" which contains a playlist with all the MP3 files' names in it.  That M3U file will be compatible with Windows Media Player and (hopefully other media players, too).  Because I've designed the script to use just the filenames (instead of the whole path) it should work even if you move your MP3 directories around.  If you rename your files, it'll break.

Enjoy.  Use at your own risk.

The following Visual Basic 6.0 (VB6) subroutine will show you how to write data into Microsoft Excel spreadsheet cells from your program.

As with all my sample code, it's provided as-is without warranty or support.  Use at your own risk.

VBScript Function to Determine if a Registry Entry Exists

| No Comments | No TrackBacks

The following function, when called with the path to a Windows Registry entry, will attempt to tell you if that entry exists in the Registry of the system it's running on.

For example, you might call it as follows:

theEntry = "HKLM\Software\Microsoft\Internet Explorer\Main\Start Page"
if regEntryExists(theEntry) then
   msgbox "That Registry Entry exists."
else
   msgbox "That Registry Entry doesn't exist."
endif

The function returns a true or false Boolean response.  True if the Registry entry exists, False if it doesn't.

VBScript "Sleep" Function

| No Comments | No TrackBacks

Sometimes during a VBScript, you need the system to "go to sleep" for a little while so that you can wait for something to happen.  For example, you might want to start a process running and give it 30 seconds to finish before you do something else, or you might want check a given directory for a file every minute or so. 

This VBScript function returns an array when given a line of tab-delimited text.

To use it, write a line of code like the following:

Dim theArray()
theText = "something tab delimited"
theArray = tabsplit(theText)

As with all my script code, this is provided as-is without warranty or support.  Use at your own risk.

Send an Email Via Outlook from VB or VBScript

| No Comments | No TrackBacks

The VBScript code below will send an email message through Microsoft Outlook (the Exchange Server version, it probably won't work with Outlook Express) when you call it from your script.  Using this subroutine you can customize the subject and content of the mail message as well as its recipients.

To use it, the syntax is:

  mailThisMessage toAddress, bccList, ccList, subjectLine, theMessage

where:

toAddress is the email address you want to send the message to (use ";" for multiple addresses)

bccList is the list of email addresses you want to "bcc" the mail message to via Outlook

ccList is the list of email addresses you want to copy the mail message to via Outlook

subjectLine is the subject line of the message you're sending via Outlook

theMessage is a text field containing the actual message you want to send, in HTML format, via Microsoft Outlook mail

As with all my scripts and code, this is provided without warranty or support.  Use at your own risk.