|
|
| The Stories of My Life | Gallery | Projects | Friends and Family | Web Log | Contact |
Perl Code Samples for use in Application Installation
By Bryan A. Thompson
Created 2/2003
Last Updated 4/27/2003
Note: Parts of this page were contributed by Ryan Lantzer.
Typical Install Script written in Perl
use Win32::Registry;
# Note - for reference, this is line 3
# Do not edit anything above this line-----------------------------------------------------------------------
# Change the reference to "ftp" in line 15 to the directory where your product is to be stored on the local drive. This must be a subdirectory of the C:\Source Files directory for file permissions to be correct.
# Change the reference to "wsle_450" in line 16 to the name of your MSI file. Do not enter the file extension (the ".msi" part of this filename).
$msidir="ftp";
$msiname="wsle_450";
# Do not change anything below this line--------------------------------------------------------------------
# Note: This part determines the current directory (where update.pl is located)
# This allows the script and MSI to be moved from location to location without editing the script
$cwd=$0;
@cwd=split(/\\/,$cwd,-1);
$#cwd=$#cwd-1;
$cwd=join("\\",@cwd);
# Note: This changes the current directory to the C: drive.
chdir ("c:\\");
# Note: This part adds the following information to the install log.
print"******************************\n";
print"Installing Custom Application $msiname.msi \n";
print"******************************\n";
print "\n";
print " ********************\n";
print " Copying Source Files\n";
print " ********************\n";
print "\n";
# Note - this part deletes any old MSI that may reside in this location. Then it creates or recreates the directory on the local drive where the MSI file is kept so that the app can self-repair even when detached from the network. Then the MSI file is copied to the new location.
$sourcefilesdir="C:\\Source Files\\$msidir";
system("rmdir \"$sourcefilesdir\" /s /q");
system("mkdir \"$sourcefilesdir\"");
system("xcopy \"$cwd\\*.msi\" \"$sourcefilesdir\"");
# Note - this part adds more info to the install log files
print " **************\n";
print " Installing MSI\n";
print " **************\n";
# This part install the MSI file from the C:\Source Files\<whatever> directory
$sourcefilesmsi="$sourcefilesdir\\$msiname.msi";
$logfile='C:\winnt\system32\umrinst\applogs\\'."$msiname.txt";
$msiproperties='ALLUSERS="1" COMPANYNAME="UMR" USERNAME="UMR" ROOTDRIVE="C:\"';
system("msiexec /qn /i \"$sourcefilesmsi\" /l* \"$logfile\" $msiproperties");
# Note - This part creates the product key required for AFS/ADS login scripts to run
$productlistkey="SOFTWARE\\UMR\\INSTALL\\Product_List";
$productkey="msi_$msiname";
$HKEY_LOCAL_MACHINE->Open("$productlistkey",$hkey);
if ($hkey)
{
$hkey->Create($productkey,$skey);
$skey->Close();
$hkey->Close();
}
Additional Code Samples
Adding Files
The following code can be used to copy all files in a directory to a local drive:
system("xcopy /Q \"$cwd\\*.*\" \"C:\\Source Files\\mcafee451\"");
The above script will not work if the directory is an AFS volume containing an Oldfiles directory. If this situation arises, copy the files to a subdirectory, then run the above script. An alternative is using the copy command instead of the xcopy command.
Adding Shortcuts
Since shortcuts are files, this is similar to adding a file. Create the shortcut file on a test machine. Then follow the procedure above to copy the file through the install script.
Adding Directories
system ('mkdir C:\temp');
Deleting Files and Shortcuts
This code will check to see if the file specified in the $file_to_delete variable exists, and if it does, the script will delete that file. Since shortcuts are files (they have a hidden .lnk file extension), this will work for shortcuts, too:
$file_to_delete='C:\Documents and Settings\all users\desktop\Acrobat Reader 4.0.lnk';
if (-f $file_to_delete)
{
system("del \"$file_to_delete\"");
}
Deleting Directories
This code will delete the directory C:\UMRINST and any subdirectories, and will suppress any system prompts:
system ('rmdir /s /q "C:\umrinst\"');
Moving Files and Directories
This will move the contents of the folder C:\UMRINST\ Boot to the folder C:\WINNT\SYSTEM32\UMRINST:
system ('move /y "C:\umrinst\boot" "C:\winnt\system32\umrinst"');
Changing File Permissions
Some products require certain file permissions to be changed in order to allow the product to work correctly for users who are not administrators or power users. The following code changes permissions on the folder C:\Program Files\AutoCAD 2002 to give the group "everyone" full access to this directory and all subdirectories:
system ("echo y|cacls.exe \"c:\\Program Files\\AutoCAD 2002\" /t /c /e /g everyone:f >NUL");
Changing File Attributes
This code changes the file attributes on the file C:\hiberfile.sys:
system ('attrib -r -s -h c:\hiberfil.sys');
Conditional Installation
Some products depend on other products being installed. In this case, an application script that depends on Oracle checks the registry to see if Oracle client has been installed, and fails to execute if it hasn’t:
$oracle_installed=0;
$reg="Software\\UMR\\INSTALL\\Product_List\\msi_Oracle8i";
$HKEY_LOCAL_MACHINE->Open($reg,$hkey);
if ( $hkey )
{
$oracle_installed=1;
$hkey->Close();
}
$reg="Software\\UMR\\INSTALL\\Product_List\\msi_Oracle9i";
$HKEY_LOCAL_MACHINE->Open($reg,$hkey);
if ( $hkey )
{
$oracle_installed=1;
$hkey->Close();
}
if ($oracle_installed eq 1)
{
#Insert Code to be installed if the
} else {
print "\nThis installation failed because the Oracle client has not been\n";
print "installed.\n";
}
This code will check to see if a machine is a CLC install, and if so, run the application install script:
$HKEY_LOCAL_MACHINE->Open($Register,$hkey)|| die $!;
$hkey->GetKeys(\@key_list);
foreach $key (@key_list)
{
if ($key eq "clc") {
#Insert code to install product here
}
}
$hkey->Close();
Adding Registry Keys
The simplest way to do this is to make the changes to the registry manually on a test machine, then export that key using the export feature of regedit. Save the file with the .reg extension. The contents of the reg file will appear as shown below:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\system]
"dontdisplaylastusername"=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon]
"ShowLogonOptions"=dword:00000000
To install this .reg file, use the following command in the application install script. This command adds the contents of the .reg file to the system registry, overwriting anything that might already be in the locations specified in the .reg file:
system ('regedit /s c:\winnt\system32\umrinst\whatever.reg');
It’s also possible to add a registry key using Perl directly. This method doesn’t require that a .reg file be created first:
$productkey="msi_visual_studio_7";
$HKEY_LOCAL_MACHINE->Open("$productlistkey",$hkey);
if ($hkey)
{
$hkey->Create($productkey,$skey);
$skey->Close();
$hkey->Close();
}
Changing Registry Permissions
This code modifies a list of registry permissions for the keys associated with AutoCAD:
# Grants Everyone full access to Autocad registry keys and files
use Win32::Registry;
$prefix="\\Registry\\Machine";
# 1 Administrators full
# 5 Creator full
# 7 World full
# 17 System Full
$perms="[1 5 7 17]";
$tempfile='c:\temp\t_perms.ini';
@regkeys=(
'SOFTWARE\Classes\AutoCAD.Drawing',
'SOFTWARE\Classes\AutoCAD.Drawing.15',
'SOFTWARE\Classes\CLSID\{83836783-4E7A-11D3-8300-0060B0EF5B11}',
'SOFTWARE\Classes\CLSID\{8E75D913-3D21-11d2-85C4-080009A0C626}',
'SOFTWARE\Autodesk',
);
sub find_keys
# Sends all subkeys (inclusive) of passed parameter to OUTFIL in specified format
{
my($hkey);
my($regkey);
my($i);
my(@key_list);
($regkey)=@_;
$HKEY_LOCAL_MACHINE->Open($regkey,$hkey);
# Some keys may be unopenable; do not include these
if ($hkey)
{
unless ("$prefix\\$regkey" =~ /=/)
# regini has problems with the char '=' in key names
{
print OUTFIL "$prefix\\$regkey $perms\n";
$hkey->GetKeys(\@key_list);
$hkey->Close();
for ($i=0;$i<@key_list;$i++)
{
find_keys($regkey."\\".$key_list[$i]);
}
}
}
}
Changing the System Path and other Environment Variables
This code adds a directory to the end of the System Path environment variable:
# Add a directory to the end of the Machine Path
use Win32::Registry;
$path_to_add='C:\Program Files\Common Files\macromedia';
$environmentkey='System\CurrentControlSet\Control\Session Manager\Environment';
$pathvalue='path';
$HKEY_LOCAL_MACHINE->Open("$environmentkey",$hkey);
if ($hkey)
{
$hkey->GetValues(\%values);
foreach $value (keys %values)
{
if (uc $value eq uc $pathvalue)
{
$oldpath=$values{$value}->[2];
$newpath="$oldpath;$path_to_add";
print "Adding path to Local Machine Path environment variable\n";
undef $undefined;
$hkey->SetValueEx($value,$undefined,REG_EXPAND_SZ,$newpath);
}
}
$hkey->Close();
}
else
{
print "Could not open environment.\n";
}
Changing Local Groups on NT/2000/XP
Sometimes it becomes necessary to add "everyone" to a group to allow an application to function:
system ('net localgroup "Debugger Users" everyone /add');
Changing Windows Service Startup Characteristics
This involves editing a registry key in each case, then rebooting. It is necessary to know the name of the service.
1) Go to the Windows/Control Panel/Services dialog (located in different locations for different OSes).
2) Find the service you wish to start or stop, and double-click it. The service name is shown as "AvSynMgr".
3) To Disable a service at boot (nothing can start this service, even manually), copy this text into a .reg file:
REGEDIT4
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\AvSynMgr]
"Start"=dword:00000004
4) To Start a Service at boot, copy this text into a .reg file:
REGEDIT4
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\AvSynMgr]
"Start"=dword:00000002
5) To set the service to manual at boot (not started, but can be started manually or by another process), copy this text into a .reg file:
REGEDIT4
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\AvSynMgr]
"Start"=dword:00000002
To install this .reg file, use the following command in the application install script. This command adds the contents of the .reg file to the system registry, overwriting anything that might already be in the locations specified in the .reg file:
system ('regedit /s c:\winnt\system32\umrinst\whatever.reg');
Starting and Stopping Windows Services
Sometimes it is necessary to stop an application before it can be updated. The following code will stop a service, execute a script, then start the service again:
system ("net stop avsynmgr");
# Insert script to be run while service is stopped here
system ("net start avsynmgr");
Unless otherwise specified, the text and images in this page are the copyrighted property of Bryan A. Thompson, 1996-2008. All Rights Reserved.