Code to launch an Internet Explorer window from VBscript.

set IE = WScript.CreateObject("InternetExplorer.Application")

dim ObjTitle

IE.Navigate(“about:blank”)
IE.Document.Title = “Software Update”
IE.FullScreen = 1
IE.Left       = 0
IE.Top        = 0
IE.MenuBar    = 0
IE.Toolbar    = 0
IE.StatusBar  = 0
IE.Width      = 540
IE.Height     = 151
IE.Visible    = 1

Set ObjBody  = IE.Document.Body
strHTML = “<b><h2>Software Update In Progress</H2><br>” &_
“Please do not use your computer during this time.  Thank you</B>”
objBody.InnerHTML = strHTML

My Corporate DNS Server was lying to me, often.

I was trying to copy some files to a group tonormaldnsoperation a computers.  What I’d do is check if the computer is alive first, by doing a network ping.  If the computer answered the Ping, then the computer was alive, so I would then copy files to it.

It mostly worked, except when it didn’t.  Here is the clue which lead me to the answer:

C:\>ping alfred

Pinging ALFRED [192.168.1.5] with 32 bytes of data:
Reply from 192.168.1.5: bytes=32 time<1ms TTL=128

C:\>ping powergirl

Pinging POWERGIRL [192.168.1.5] with 32 bytes of data:
Reply from 192.168.1.5: bytes=32 time<1ms TTL=128

C:\>

The DNS server was returning the same IP address for two different computers.  As POWERGIRL was powered on, it answered the Ping request for ALFRED.  When I tried to copy to ALFRED, it failed as the file copy was trying to verify that ALFRED was at 192.168.1.5, and it wasn’t.

The cause?  The DNS server was retaining IP addresses for 24 hours.  Sometimes a computer’s IP will change more often than that.  So the DNS server ended up with 2 or more DNS computer records with the same IP.
The fix?  Tell the DNS server to only retain DNS records for 2 hours.  (for the more technically minded, we adjusted the Time To Live value).

How I originally detected the DNS server was lying to me?
I pinged the computer (ALFRED) to get it’s IP address (192.168.1.5).
I then asked IP address 192.168.1.5 what it’s computer name was.  In the example above, it was actually POWERGIRL.

The code to do that is in the Reachable function, below:

Continue reading

It’s fairly simple, a bug

is a fault in software, or hardware for that matter, which breaks something.
For example, if you make software which links my Microsoft Calendar to my Google Calendar, and your software duplicates all my calendar entries, it’s a bug.  Not an undocumented feature.

An undocumented feature, is a feature which is undocumented.  Such as the (in)famous Squeaky Lobster performance counter switch in Microsoft Exchange 5.5.  An undocumented feature is not a bug! I will smite the next vendor who uses that term with me.

A Feature, is an element of software, or hardware, which has been tested, publicised, and should work “out of the box”.  It should not require me to spend two hours reverse-engineering code, to unravel the original developer’s “brilliance”.
When I say “brilliance”, I mean a convoluted piece of code crap that even the original developer would disown like the bastard child it surely is.

Bookmark and Share

“A referral was returned from the server”

As I finish up version 1 of InstallRunner, I went to set the UAC setting for “Require Administrator Privileges”.  I did that, and got this error:

A referral was returned from the server

Doing some research*, the cause of the error was that I did this:

Application Mainifest - uiAccess True

By default, uiAccess is false.  I changed it to true.  I’m not sure why, ignorance perhaps 🙂

What does uiAccess do anyway?

Continue reading

Useful programming how-tos I’ve stumbled across.

Event handling in VB.Net

Getting the item under mouse cursor in a Listview control

Add ListView column and insert ListView rows
The Java2s site doesn’t look like much, but it’s helped me with understanding several pieces of Visual Basic code.

How to use a ContextMenuStrip with a ListView control

Timeouts on the HttpWebRequest (and thus SOAP proxies)

Bookmark and Share

Programs which lie about successfully installing.

When you install a program, particularly via an install script (VBscript, PowerShell etc.), it’s always good practice to check the Exit Code the program returns.

Just in case the program didn’t install probably, or even, the user has pressed cancel.

Much to my annoyance, here’s a list of programs which return 0 (Zero ie. I installed ok) when they don’t install:

  • Google Desktop
  • Lanier Printer Drivers
  • LastPass
  • Windows 7 USB/DVD-download tool
    (requires the Imaging API, if it’s not there, it fails and returns 0 anyway).
  • Windows Server 2003 Resource Kit Tools

It’s not an exhaustive list by any means 🙁

Update 23 May 2010, and these as well:

  • Google Chrome Browser
  • Firefox 3.6.3
  • Skype
  • Thunderbird
  • Paint.Net
  • Picasa 3.6
  • XnView
  • Acrobat Reader 9.3
  • SUPERAntiSpyware
  • uTorrent 2.0
  • Evernote
  • Texter
  • Postbox

Bookmark and Share

“The BackgroundWorker is currently busy and cannot run multiple tasks concurrently”

The BackgroundWorker is currently busy and cannot run multiple tasks concurrently

*sigh*  One step forward, five steps back. 

As in the words of one forum poster:

BackgroundWorker is pretty much "Threading for Dummies" in that it’s an excellent tool to teach a new programmer how to run work on a second thread and is great for simple tasks; but with it’s simplicity comes the price of flexibility.

If you want to run multiple threads, you really need to use the .Net System.Threading class.

Bookmark and Share

So where is that “Break all processes when one process breaks” option?

Not in Visual Studio 2008 Express, that’s for sure.
No option for debugging

  It’s a VS 2008 Professional option only, and it looks like this:
Break all processes when one process breaks - VS 2008

You need the “Break all processes when one process breaks” option when you are trying to step though a background process.  I want to use background processes as I need to do many file downloads in the background.

And background threads are the only way to do it.

I talk (briefly) about background thread processing in “Sew me a Thread or three.

The software application I’m writing is taking up most of my time, which why blog posts have been a bit lean around here.

Bookmark and Share

Grumble grumble – revisiting the WMI fix

I work with some clever people, such as Mark W., who pointed out this Microsoft blog post
WMI Troubleshooting Tips,
which advised against deleting the WMI Repository.

Rebuilding the WMI repository is a destructive operation that can lead to data loss, applications breaking, and a whole host of slow to appear, difficult to diagnose problems.

And guess what?  not deleting the repository actually works out better for me, and the SMS 2003 Client install.

When I say better, I mean that the SMS 2003 Client seems to repair itself better & faster.  “Snap of the fingers” fast.

I’m doing a mass rollout next week of the repair script, so we’ll see how it goes.

The first post in the series, "WMI has stopped working on some remote computers", is here.
The final post in the series, "The WMI fix, which is better", is here.

Bookmark and Share

WMI has stopped working on some remote computers.

And I don’t know why.  My strong guess is that it is related to one of the 10+ recent Microsoft security patches I’ve deployed to the fleet.  (I’m looking at you .Net Framework 2.0)

The fix so far? Rebuild WMI and repair the SMS client.

I do this by:

  • copying wmirebuild.bat and runrepair.vbs to the target computer.
    the purpose of runrepair.vbs is to HIDE the running of wmirebuild.bat, so the end user doesn’t see it.
  • remotely run runrepair.vbs via a PSEXEC command.

Yes, it’s a bit kludgey.  It’s a fast fix.

runrepair.vbs
Dim objFSO,objNet,objShell,drive_status
Dim objWMIService, objProcess, colProcess, strComputer, strProcessKill
Dim sWbemPath,sSystemRoot

On Error Resume Next

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objShell = CreateObject("WScript.Shell")

sSystemRoot = objShell.ExpandEnvironmentStrings("%systemroot%")

'check that system32 directory exists.

If Not objFSO.FolderExists(sSystemRoot) Then
WScript.Quit(99)
End If

If Not objFSO.FileExists("c:\temp\wmirebuild.bat") Then
WScript.Quit(99)
Else
objShell.Run "c:\temp\wmirebuild.bat", 0, True
End If

Set objShell = Nothing
Set objFSO = Nothing

WScript.Quit

wmirebuild.bat
net stop ccmexec
net stop VMAuthdService
net stop winmgmt
c:
cd %systemroot%\system32\wbem
rem rd /S /Q repository

regsvr32 /s %systemroot%\system32\scecli.dll
regsvr32 /s %systemroot%\system32\userenv.dll

mofcomp cimwin32.mof
mofcomp cimwin32.mfl
mofcomp rsop.mof
mofcomp rsop.mfl

for /f %%s in ('dir /b /s *.dll') do regsvr32 /s %%s
for /f %%s in ('dir /b *.mof') do mofcomp %%s
for /f %%s in ('dir /b *.mfl') do mofcomp %%s

net start winmgmt
net start VMAuthdService
net start ccmexec

echo done >>c:\temp\done.txt

Then kick it all off with
psexec \\COMPNAME -s c:\winnt\system32\cscript.exe //B c:\temp\runrepair.vbs

Update: the wmirebuild.bat script I found here: How Do I Rebuild A Corrupt WMI Repository?

The next post in this series is, “Grumble grumble – revisiting the WMI fix”.

Bookmark and Share