Jump to content

cond test for existing instance of software


Recommended Posts

Now I know I can use WMI from vbscript (no flaming PLEASE) to lookup Add Remove Programs (ARP) list and determine if a piece of software is installed.

Say "Adobe Reader 8.1.2"

How does one do this with 'cond' and 'gcond'?

My purpose is to NOT offer a piece of software if it's already installed, via a better test than just picking a file or registry entry at random from what I can see is created uppon test installs.

Also can we have an uninstall checkbox?

or do I have to:

1/ check if software is installed (via cond)

2/ present the uninstaller..

This just doubles my work if I want to be able to use WPI to control what software is and isn't installed.

Link to comment
Share on other sites


I am not familiar with WMI. Do you have an example script you can send me? Maybe I can build it in to WPI and make it a call like:

IsProgramInstalled("Adobe Acrobat 8.0")

Link to comment
Share on other sites

I am not familiar with WMI. Do you have an example script you can send me? Maybe I can build it in to WPI and make it a call like:

IsProgramInstalled("Adobe Acrobat 8.0")

It's trivial to do. JScript version (AFAIK WPI uses JScript but I can post a VBScript version if you prefer) of fairly generic code that shows how you can do it:

try {
strComputer = ".";
SWBemlocator = new ActiveXObject("WbemScripting.SWbemLocator");
objWMIService = SWBemlocator.ConnectServer(strComputer,"root/CIMV2");
colItems = objWMIService.ExecQuery("Select * from Win32_Product");
propEnum = new Enumerator(colItems);
for (;!propEnum.atEnd();propEnum.moveNext()) {
objItem = propEnum.item();
if (objItem.Caption == "Adobe Reader 8.1.2")
{
WScript.Echo("installed!");
}
}
}
catch(e) {
WScript.Echo("exception " + e.number + ": " + e.description);
}

However, the Win32_Product class is BY FAR the slowest one. I mean, it's really excruciatingly SLOW. It's like molasses, in January, going uphill. Don't be surprised if it takes as long as 30 seconds to run (also, by default, that class doesn't work on windows 2003). I sure wouldn't want to be calling this code several times to see if various apps are installed. If you're resorting to use it, then only run it once (keep the results in an array or such).

It would be FAR quicker (I mean, more than 100x faster) to look in the registry, but then again, the path to the [un]install info changes with every build, so it gets tedious for sure.

Link to comment
Share on other sites

I built in a new function: isInstalled() with the above code. Thank you, crahak!

isInstalled("Adobe Reader 8.1.2") returns true or false

As said above: it can be slow. It took 6 seconds to search my install list of 40 programs. Checking the registry would be much better, but, it's here now.

Link to comment
Share on other sites

you guys are ACE..

I'll give the new one a try..

Just a quick thought.. does this work for w2k3? as crahak indicated the wmi lookup didn't work on that system..

Next challenge will be

cond[pn]=['isInstalled("Adobe Reader 8.1.2")'];

cmd1[pn]=[' .... er... wmi lookup the correct product uninstall string .... '];

Better still would there be a posibility of having an 'already installed' Category that auto-populates from ARP? with the uninstall action available as cmd1 ..??

Does this make sense?

If this works, I could then concentrate my efforts on creating valid MSI installers for my noddy apps and reg tweaks using the old free WinINSTALL.

That way the install/uninstall is in a 'standard' method and maintains full portability..

Far, far in the distance, in an astral plane that was never meant to exist...

[[ this worked for other computers withing your LAN (assuming sufficient rights and access).

One screen listed computers in the network and their installed software. Hi-lighting a machine allowed new software to be added from a list. ]]

... there appeared a virtual world, where users knew how to behave and didn't experiment with settings and then blame the chief network support wizard. Expecting him to perform acts of magic on their system.

Link to comment
Share on other sites

Just a quick thought.. does this work for w2k3? as crahak indicated the wmi lookup didn't work on that system..

Unless you already made the necessary changes on your win 2003 box, nope. If you need this to work on every OS reliably, then you don't want to use this WMI class, simple as that.

cmd1[pn]=[' .... er... wmi lookup the correct product uninstall string .... '];

Again, you still have the same issues as above. And that slow WMI class only returns so much infos. Again, you'd be far better off reading from the registry at this point.

However, only a tiny number of apps publish a QuietUninstallString in the registry, the vast majority only add a plain old UninstallString, which will need user interaction to uninstall.

Better still would there be a posibility of having an 'already installed' Category that auto-populates from ARP? with the uninstall action available as cmd1 ..??

Does this make sense?

From ARP? Perhaps we're not thinking about the same thing (Address Resolution Protocol)

One screen listed computers in the network and their installed software. Hi-lighting a machine allowed new software to be added from a list.

There's already plenty of apps and mechanisms to do push installs, installs on-demand and such, of various software and updates. GPO, SMS, logon scripts, etc.

Link to comment
Share on other sites

ARP.. grin.. ok AoRP (Add or Remove Programs)

Hmm yes there are several good ways to install apps on a domain.. I personally like GPO pushing MSI installers. I just have to remember to select the advanced option and tick the "uninstall when falls out of scope". and one does have to 'fiddle' with the MSI's occasionally to get them to install properly.

but this falls down when the plank of a user installs something like 'smiley central'. Removal requires a visit to the machine in question, whether phisicaly or via remote software.

If I was using WPI during startup, from a central folder, I could force off the system anything not on the list.. Yes the user may end up calling the helpdesk when he gets a prompt (if software uninstall is not silent), but we've got him/her by the 'sphericals' at that point. "So why did you install this unauthorised software?"

A selection (WPI calling method) can be used to include software we permit.

This would also work for workgroups..

Hyena get's close, lists the software, but won't allow you to do anything with it..

Expensive support tools like Kaseya can (with effort) be configured similarly and can uninstall unwanted software.. But a £10k startup cost it's not cheap..

I just love this tool (WPI) and want to get the max from it..

Link to comment
Share on other sites

If I was using WPI during startup, from a central folder, I could force off the system anything not on the list.. Yes the user may end up calling the helpdesk when he gets a prompt (if software uninstall is not silent), but we've got

him/her by the 'sphericals' at that point. "So why did you install this unauthorised software?"

Well, the user could just hit cancel and keep his unauthorized apps... I thought you intended to use that to uninstall an old version of an app, prior to installing the newer one (silently), where user interaction isn't typically desired.

We tend to deal with this differently. We keep lists of generally authorized apps (those just get ignored), list of apps with licenses only for some workstations or users, and everything else not on those, gets spit out to an excel sheet, that someone looks at. New apps get either added to the old list of authorized apps (like say, a driver package), or the user gets a phone call/visit from someone (e.g. game found on their computer), and often the user's local admin rights are pulled (assuming they had them in the first place). But I guess every place has its own ways to deal with this.

As for other apps that we don't push via GPO or such, we tend to include links in their start menu (for the apps they need/are authorized to use), that launch a script instead of the app. The first time they run it, the script installs the app. The script also checks for updates before starting the app. It's not perfect, but it's simple, it works reliably and it costs nothing.

This would also work for workgroups..

Most places I've seen using workgroups were pretty small (especially when you can throw together a domain controller out of a old/spare box with linux + samba in mere minutes for free), so it wasn't too much of a problem managing the few computers by hand. YMMV...

Link to comment
Share on other sites

You are spot on.. I will stick to just using this to pull prior versions of software, when installing later versions.

The trick will be to get the uninstall string..

Hmm.. I bet I can parse the software name to a CMD script and use some (semi) inteligent scripting to locate the uninstaller..

I could even have some option stuff preset for some software I know of that needs silent switches..

That could work..

but my guess is that IsProgramInstalled("Adobe Acrobat") would not work (match) as the package is "Adobe Acrobat 6", or "Adobe Acrobat 6.0.1"...

Hmm..

Edited by Nobby Barnes
Link to comment
Share on other sites

The trick will be to get the uninstall string..

That's easy to do, both using the previous, excruciatingly slow and non-win2003 friendly WMI way, and reading from the registry.

WMI wise, the Win32_Product class doesn't have a property for the uninstall string, but it has a Uninstall method. You call that, and it gets uninstalled.

Registry wise, it's only a matter of enumerating the keys for each installed app, and in each keys looking at the right values -- QuietUninstallString or UninstallString, for each app (DisplayName being the app name).

You could probably do it with a .cmd file, but that would be truly fugly (using reg.exe and "for /f" a LOT)

You could also use things like the WindowsInstaller.Installer object directly, but the end result is the same (the Win32_Product WMI class is merely a different way to use it).

my guess is that IsProgramInstalled("Adobe Acrobat") would not work (match) as the package is "Adobe Acrobat 6", or "Adobe Acrobat 6.0.1"...

I haven't looked at the code used by WPI, but if it tries to do a plain old string comparison (appname == "some app"), indeed that wouldn't work. You'd have to use the .indexOf method instead.

Edited by crahak
Link to comment
Share on other sites

@Nobby Barnes,

I have a lot of luck checking the HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall Key for Add/Remove Programs. Below is a sample of my condition and gcondition that I use for checking whether an app is installed AND available for install on my disk or network store.

prog[pn]=['Notepad++ v4.0.2'];
ordr[pn]=[170];
uid[pn]=['NOTEPAD402'];
dflt[pn]=['no'];
cat[pn]=['Commercial Applications'];
forc[pn]=['no'];
cond[pn]=['FileExists("%root%\\Applications\\Commercial\\Notepad++ v4.0.2\\npp.4.0.2.Installer.exe")'];
gcond[pn]=['RegKeyExists("HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Notepad++\\DisplayName")'];
cmd1[pn]=['"%root%\\Applications\\Commercial\\Notepad++ v4.0.2\\npp.4.0.2.Installer.exe" /S'];
pn++;

Hope this helps.

-Tony

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...