cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Simple way to get GUIDs?

I'm looking for a way to export or collect all of the GUIDs Package, Product, Ugrade that are in the MSI's I have. Is there a tool in Admin Studio that can do that? or does anyone know of a command line program that can?

Thank you in advance.
(9) Replies
I think ConflictSolver displays these codes for MSI packages you import...
It does, but I have not been able to locate a way to export that information so I can use it external to conflict solver.
There are some other tools that I have seen, but none that allow me to select the information I want to see. It's an all or nothing, and none of it allows me to export the data simply.

Thanks for the reply.
How are you at scripting? It would probably be pretty easy to write a script that loops through all your MSI and does MSI SQL queries and stoves them off to an access database.

If you havn't already, check out the MSI SDK and look at WiSQL.vbs for examples on how to query information in an MSI.
Thank you. Just downloaded it and was looking through it. Although the WISQL.vbs isnt' there, there are few others that are. I write a lot of Perl and WSH scripts so I'm not bad at it. Just hand't found a way to query the info yet. now I might be able to get somewhere.
Sorry, it's WiRunSQL.vbs. It should be in the \samples\SysMgmt\Msi\Scripts folder.
Thanks again. Seems that I need to refresh my SQL knowledge now though...

🙂
This DevLetter tip has a few examples: http://www.installshield.com/news/newsletter/0302-articles/msiaccess.asp.

Including one that might apply to your question:

SELECT `Value` FROM `Property` WHERE `Property`='ProductCode'
using the code from the VBS script, I was able to make a script for in Perl that does what I wanted.
@value = qw(ProductName UninstallCode ProcductCode);
foreach $value(@value){
"SELECT `Value` FROM `Property` WHERE `Property`='$value'

}

that worked for what I needed. I'm at home, so I'll post the full code up on Monday...
Might be helpful to somone else. The VBS takes too much work to get the same results, so I went to Perl...
This is the Perl Code that I'm using. Hope it will help others that are looking for the same...
[CODE]
#!perl
use Win32::OLE;
use strict;
use constant msiOpenDatabaseModeReadOnly => 0;
use constant msiOpenDatabaseModeTransact => 1;
my ($param, $argCount, $file);
$argCount = @ARGV;
if (($argCount < 1)) {
print "\n\t#############################################################
Windows Installer utility to execute SQL queries against an installer database.
This returns the Product Name, Product code, and Upgrade code of all MSI files
given in the path or the file specified on the command line.
The 1st argument specified can be the path to search or the file you want info from.
\n\tExample: MSI_Properties.pl \"\\path\\share\\\" or \"\\path\\share\\msifile.msi\"\n
\t#############################################################
";
exit (1);
}

my $openMode = msiOpenDatabaseModeReadOnly;

# Connect to Windows installer object
my $installer = undef;
$installer = Win32::OLE->new('WindowsInstaller.Installer');
CheckError();
$param = $ARGV[0];
if ($param =~/(\.msi)/ || (-d $param)){
$file = $1;
}else{
die "Need MSI file or directory!\n";
}
my (@msis, $cmd);
# Open database
my $databasePath = $ARGV[0]."\\*.msi";
if ($file){
@msis = ($ARGV[0]);
}else{
$cmd = "dir \"$databasePath\" /b /s";
print "$cmd\n";
@msis = qx($cmd);
}
my ($ctr, %msiData);
my $output = "MSI-Value";
&Name;
$output = $output.".xls";
open OUT, ">$output";
print OUT "Product Name\tUpgrade Code\tProduct Code\tFile - Path\n"; #header row
for (@msis){
chomp;
$ctr++;
my $database = $installer->OpenDatabase($_, $openMode);
CheckError();
my ($value, $query, $view, $record, $message, $rowData, $columnCount, $delim, $column);
my @query_value = qw(ProductName UpgradeCode ProductCode);
foreach $value(@query_value){
$message;
$query = "SELECT \`Value\` FROM \`Property\` WHERE \`Property\`=\'$value\'";
$view = $database->OpenView($query);
CheckError();
$view->Execute();
CheckError();
if (uc(substr($query, 0, 6)) eq 'SELECT') {
while (1) {
$record = $view->Fetch;
last if !($record->{FieldCount});
$columnCount = $record->FieldCount;
$rowData = "";
$delim = ' ';
for my $column (1 .. $columnCount) {
if ($column eq $columnCount) {
#$delim = vbLf;
}
$rowData = $rowData . $record->StringData($column) . $delim;
}
$message = $rowData;
chomp $message;
$msiData{$ctr}{$value} = $message;

}
}
$msiData{$ctr}{'PATH'} = $_;
if (defined($message)) {
print "$msiData{$ctr}{$value}\n";
print OUT "$msiData{$ctr}{$value}\t";

}

}
print OUT "$msiData{$ctr}{'PATH'}";
print "\n";
print OUT "\n";
$database->Close();
}
print "$ctr records added to $output\n";
close OUT;
exit (0);

sub CheckError {
my ($message, $errRec);
return if (0 + Win32::OLE::LastError()) == 0;
$message = ' ' . sprintf("%x", (0 + Win32::OLE::LastError())) . ': ' . ('' . Win32::OLE::LastError());

if (!($installer)) {
$errRec = $installer->LastErrorRecord;
if (!($errRec)) {
$message = $message . $errRec->FormatText;
}
}
Fail($message);
}

sub Fail {
my($message) = @_;
print "$message";
exit (2);
}
sub Name {
if (-e "$output.xls"){
my ($p1, $nctr) = split(/_/, $output);
$nctr++;
$output = join("_", $p1, $nctr);
&Name;
}else{
return;
}

}
[/CODE]

This will take a path or .msi file and return the Product name, Upgrade code, and Product Code from the msi. If it's a path, then it will run on all of them within the folder you specify. It dumps this out to a file called msi-values.xls (tab delimited). This file will increment as if it's already there...

Good luck and thanks for the help.