my Installshield “utility belt”

This is a little collection of routines I’ve written to make my life easier when using InstallShield.  Use at your own risk. Modify to your heart’s content.  No warranties expressed or implied.  Etc…

//////////////////////////////////////////////////////////////////////////////
//  File Name:   UsefulScripts.rul
//  Description: Reusable Installshield Scripts
//  Comments:    Scripts that may prove to be handy in other installs
//               would go in this file.
//
//////////////////////////////////////////////////////////////////////////////

//////////////////// installation declarations ///////////////////
// —- script function prototypes —–

// these update the Web.Config
prototype NUMBER ReadKey(HWND, STRING, STRING, byref STRING);
prototype UpdateKey(HWND, STRING, STRING, STRING);
prototype AddKey(HWND, STRING, STRING, STRING);
prototype UpdateCustomErrors(HWND, STRING, STRING);

 // these help working with legacy (orphaned) installs
prototype STRING CheckRegistryForPath(STRING);
prototype STRING CheckRegistryForMSI(STRING);
prototype NUMBER RemoveLegacyInstall(STRING, STRING, STRING);

 // these help working with Virtual Dirs
prototype NUMBER CheckIISExists(HWND);
prototype NUMBER DeleteVirtualDir(HWND, STRING);
prototype NUMBER CheckVirtualDirExists(HWND, STRING); 

 // these help with file manipulation
prototype NUMBER ClearReadOnly(HWND, STRING);

////////////////////////////////////////////////////////////////////////
// Function: ClearReadOnly
// Purpose: Clear the Read Only attribute on all files in or below the
//          directory passed in
////////////////////////////////////////////////////////////////////////
function NUMBER ClearReadOnly(hmsi, svDirectory)
NUMBER nFilesResult;
STRING svMatchingFileName;

begin
nFilesResult = FindAllFiles(svDirectory, “*.*”, svMatchingFileName, RESET);
while(nFilesResult = 0)
SetFileInfo(svMatchingFileName, FILE_ATTRIBUTE, FILE_ATTR_NORMAL, “”);
nFilesResult = FindAllFiles(svDirectory,”*.*”, svMatchingFileName, CONTINUE);
endwhile;

return nFilesResult;
end;

////////////////////////////////////////////////////////////////////////
// Function: ReadKey
// Purpose: Read specific keys in Web.Config, using FileGrep
////////////////////////////////////////////////////////////////////////
function NUMBER ReadKey(hmsi, svFilePath, svFindEntry, svReturnValue)
NUMBER nResult, nvLineNumber;
STRING WebConfigFile, svReturnLine;

 begin
// build the path to the Web.Config
WebConfigFile = svFilePath ^ “web.config”;

  // search the Web.Config for the entry we specify
nResult = FileGrep( WebConfigFile, svFindEntry, svReturnLine, nvLineNumber, RESTART );
switch(nResult)
case 0:
// Since this line normally appears twice in our web.config file, we’re
// checking for the existence of a 2nd match and reading it instead.
// If there is no 2nd match, go ahead and read the one we find.
if ( svFindEntry = “ConnectionString” ) then
nResult = FileGrep( WebConfigFile, “<add key=\”” + svFindEntry + “\””, svReturnLine, nvLineNumber, CONTINUE );
if ( nResult < 0 ) then
FileGrep( WebConfigFile, “<add key=\”” + svFindEntry + “\””, svReturnLine, nvLineNumber, RESTART );
endif;
endif;

svReturnValue = svReturnLine;
return 0;

case -2:
// File Not Found
MessageBox( “Web.Config file not found.”, SEVERE );
return nResult;
case -4:
// EOF reached
MessageBox( svFindEntry + ” key not found.”, SEVERE );
return nResult;
default:
//unknown error
MessageBox( “An unknown error has occurred. The Web.Config file could NOT be read.”, SEVERE );
return nResult;
endswitch;
end;

////////////////////////////////////////////////////////////////////////
// Function: AddKey
// Purpose: Add a key to the Web.Config, using FileGrep
////////////////////////////////////////////////////////////////////////
function AddKey(hmsi, svFilePath, svType, svNewEntry)
NUMBER nResult, nvLineNumber;
STRING WebConfigFile, svReturnLine;

 begin
// build the path to the Web.Config
WebConfigFile = svFilePath ^ “web.config”;

  if svType = “VERB” then
// search the file for “</httpHandlers>” and insert ours immediately before it
nResult = FileGrep( WebConfigFile, “</httpHandlers>”, svReturnLine, nvLineNumber, RESTART );
elseif svType = “KEY” then
// search the file for “</appSettings>” and insert ours immediately before it
nResult = FileGrep( WebConfigFile, “</appsettings>”, svReturnLine, nvLineNumber, RESTART );
endif;

switch(nResult)
case 0:
// found it, now put our new key just before it
if ( FileInsertLine( WebConfigFile, svNewEntry, nvLineNumber, BEFORE ) < 0 ) then
// hmmm… we couldn’t insert the new key
MessageBox( “Unable to update Web.Config file.”, SEVERE );
endif;
case -2:
// File Not Found
MessageBox( “Web.Config file not found.”, SEVERE );
case -4:
// EOF reached
MessageBox( “Relevant section not found, unable to insert new entry.”, SEVERE );
default:
//unknown error
MessageBox( “An unknown error has occurred. The Web.Config file has NOT been updated.”, SEVERE );
endswitch;
end;

////////////////////////////////////////////////////////////////////////
// Function: UpdateKey
// Purpose: Update specific keys in Web.Config, using FileGrep
////////////////////////////////////////////////////////////////////////
function UpdateKey(hmsi, svFilePath, svFindEntry, svNewEntry)
NUMBER nResult, nvLineNumber;
STRING WebConfigFile, svReturnLine;

 begin
// build the path to the Web.Config
WebConfigFile = svFilePath ^ “web.config”;

  // search the file for the key we specify
nResult = FileGrep( WebConfigFile, “<add key=\”” + svFindEntry + “\””, svReturnLine, nvLineNumber, RESTART );
switch(nResult)
case 0:
// Since this line normally appears twice in our web.config file, we’re
// checking for the existence of a 2nd match and updating it instead.
// If there is no 2nd match, go ahead and update the one we find.
if ( svFindEntry = “ConnectionString” ) then
nResult = FileGrep( WebConfigFile, “<add key=\”” + svFindEntry + “\””, svReturnLine, nvLineNumber, CONTINUE );
if ( nResult < 0 ) then
FileGrep( WebConfigFile, “<add key=\”” + svFindEntry + “\””, svReturnLine, nvLineNumber, RESTART );
endif;
endif;

// once we find the key, update (replace) it with our new values
if ( FileInsertLine( WebConfigFile, svNewEntry, nvLineNumber, REPLACE ) < 0 ) then
// hmmm… we couldn’t update the value of the key
MessageBox( “Unable to update Web.Config file.”, SEVERE );
endif;
case -2:
// File Not Found
MessageBox( “Web.Config file not found.”, SEVERE );
case -4:
// EOF reached
MessageBox( svFindEntry + ” key not found.”, SEVERE );
default:
//unknown error
MessageBox( “An unknown error has occurred. The Web.Config file has NOT been updated.”, SEVERE );
endswitch;
end;

////////////////////////////////////////////////////////////////////////
// Function: UpdateCustomErrors
// Purpose: Update customErrors in Web.Config, using FileGrep
////////////////////////////////////////////////////////////////////////
function UpdateCustomErrors(hmsi, svFilePath, svNewEntry)
NUMBER nResult, nvLineNumber;
STRING svResult, WebConfigFile, svReturnLine;

 begin

  //build the path to the Web.Config
WebConfigFile = svFilePath ^ “web.config”;  

  // search the file for the key we specify
nResult = FileGrep( WebConfigFile, “<customErrors mode=”, svReturnLine, nvLineNumber, RESTART );
switch(nResult)
case 0:
// once we find customErrors, set it to OFF
if ( FileInsertLine( WebConfigFile, “<customErrors mode=\”” + svNewEntry + “\” />”, nvLineNumber, REPLACE ) < 0 ) then
// hmmm… we couldn’t update it
MessageBox( “Unable to update Web.Config file.”, SEVERE );
endif;
case -2:
// File Not Found
MessageBox( “Web.Config file not found.”, SEVERE );
case -4:
// EOF reached
MessageBox( “customErrors setting not found.”, SEVERE );
default:
//unknown error
MessageBox( “An unknown error has occurred. The Web.Config file has NOT been updated.”, SEVERE );
endswitch;

 end;

 

////////////////////////////////////////////////////////////////////////
// Function: CheckRegistryForPath
// Purpose:  look in the HKEY_LOCAL_MACHINE\SOFTWARE\etc… for a
//           key matching the GUID passed in as a parameter. Returns
//    the location of the installation.
////////////////////////////////////////////////////////////////////////
function STRING CheckRegistryForPath(szProductGUID)
NUMBER nSize, nResult, nType;
STRING szKey, szProductName, szReturn, szInstallLocation;

begin
RegDBSetDefaultRoot ( HKEY_LOCAL_MACHINE );
szReturn = “”;
szInstallLocation = “”;
nSize = -1;
nType = REGDB_STRING;
szKey = “SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\” + szProductGUID + “\\InstallProperties“;
nResult = RegDBKeyExist (szKey);
if (nResult = 1) then
nResult = RegDBGetKeyValueEx (szKey, “InstallLocation”, nType, szInstallLocation, nSize);
if (nResult = 0) then
szReturn = szInstallLocation;
endif;
endif;
RegDBSetDefaultRoot ( HKEY_CLASSES_ROOT );

  return szReturn;
end;

////////////////////////////////////////////////////////////////////////
// Function: CheckRegistryForMSI
// Purpose:  look in the HKEY_LOCAL_MACHINE\SOFTWARE\etc… for a
//           key matching the GUID passed in as a parameter. Returns
//    the location of the msi file.
////////////////////////////////////////////////////////////////////////
function STRING CheckRegistryForMSI(szProductGUID)
NUMBER nSize, nResult, nType;
STRING szKey, szProductName, szLocalPackage;

begin
RegDBSetDefaultRoot ( HKEY_LOCAL_MACHINE );
szLocalPackage = “”;
nSize = 256;
nType = REGDB_STRING;
szKey = “SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\” + szProductGUID + “\\InstallProperties“;
nResult = RegDBKeyExist (szKey);
if (nResult = 1) then
nResult = RegDBGetKeyValueEx (szKey, “LocalPackage”, nType, szLocalPackage, nSize);
if (nResult != 0) then
MessageBox(“Unable to retrieve MSI location for ” + szProductGUID, INFORMATION);
endif;
endif;
RegDBSetDefaultRoot ( HKEY_CLASSES_ROOT );

  return szLocalPackage;
end;

////////////////////////////////////////////////////////////////////////
// Function: RemoveLegacyInstall
// Purpose:  look in the HKEY_LOCAL_MACHINE\SOFTWARE\etc… for a
//           key matching the GUID passed in as a parameter. If found
//    delete the key.  This should remove it from the
//    Add/Remove Programs applet
////////////////////////////////////////////////////////////////////////
function NUMBER RemoveLegacyInstall(szUninstallGUID, szInstallerGUID, szMSILocation)
NUMBER nSize, nReturn1, nReturn2, nReturn3, nReturn4, nResult, nType, nLocation;
STRING szKey, szDir;

begin
RegDBSetDefaultRoot ( HKEY_LOCAL_MACHINE );

  // remove the Uninstall entry (this should clear it out of Add/Remove Programs)
nReturn1 = FALSE;
nSize = -1;
nType = REGDB_STRING;
szKey = “SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\” + szUninstallGUID;
nResult = RegDBKeyExist (szKey);
if (nResult = 1) then
nResult = RegDBDeleteKey (szKey);
if (nResult = 0) then
nReturn1 = TRUE;
else
MessageBox(“Unable to Remove Uninstall Key for ” + szUninstallGUID + “.”,INFORMATION);
endif;
else
MessageBox(“Unable to Find Uninstall Key for ” + szUninstallGUID + “.”,INFORMATION);
endif;

  // remove the Installer entry (this should keep it from being detected again)
nReturn2 = FALSE;
nSize = -1;
nType = REGDB_STRING;
szKey = “SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\” + szInstallerGUID;
nResult = RegDBKeyExist (szKey);
if (nResult = 1) then
nResult = RegDBDeleteKey (szKey);
if (nResult = 0) then
nReturn2 = TRUE;
else
MessageBox(“Unable to Remove Installer Key for ” + szInstallerGUID + “.”,INFORMATION);
endif;
else
MessageBox(“Unable to Find Installer Key for ” + szInstallerGUID + “.”,INFORMATION);
endif;

  // remove the key under HKLM\SOFTWARE\Classes\Installer\Products
nReturn3 = FALSE;
nSize = -1;
nType = REGDB_STRING;
szKey = “SOFTWARE\\Classes\\Installer\\Products\\” + szInstallerGUID;
nResult = RegDBKeyExist (szKey);
if (nResult = 1) then
nResult = RegDBDeleteKey (szKey);
if (nResult = 0) then
nReturn3 = TRUE;
else
MessageBox(“Unable to Remove Classes\Installer Key for ” + szInstallerGUID + “.”,INFORMATION);
endif;
else
MessageBox(“Unable to Find Classes\Installer Key for ” + szInstallerGUID + “.”,INFORMATION);
endif;

  RegDBSetDefaultRoot ( HKEY_CLASSES_ROOT );

  // remove the key (if any) under HKCR\Installer\Products
nSize = -1;
nType = REGDB_STRING;
szKey = “Installer\\Products\\” + szInstallerGUID;
nResult = RegDBKeyExist (szKey);
if (nResult = 1) then
nResult = RegDBDeleteKey (szKey);
endif;

  // delete the appropriate MSI file since we don’t need it anymore
nResult = DeleteFile(szMSILocation);
if (nResult = 0) then
nReturn4 = TRUE;
else
nReturn4 = FALSE;
MessageBox(“Unable to delete MSI file for ” + szMSILocation + “.”,INFORMATION);
endif;

// only return TRUE if all results are TRUE
if ((nReturn1 = TRUE) && (nReturn2 = TRUE) && (nReturn3 = TRUE) && (nReturn4 = TRUE)) then
return TRUE;
else
return FALSE;
endif;

end;

////////////////////////////////////////////////////////////////////////
// Function: DeleteVirtualDir
// Purpose:  Pass in the name of a virtual directory and this function
//    will delete it and return TRUE. If it can’t delete it, or
//    the virtual directory isn’t there, function returns FALSE
////////////////////////////////////////////////////////////////////////
function number DeleteVirtualDir(hmsi, sVDirName)
NUMBER nReturn;
OBJECT objIIS_Root;

 begin
set objIIS_Root = CoGetObject(“IIS://localhost/W3SVC/1/Root”, “”);
if (IsObject(objIIS_Root)) then
try
objIIS_Root.Delete(“IISWebVirtualDir”, sVDirName);
nReturn = TRUE;
catch
// VDir doesn’t exist.
nReturn = FALSE;
endcatch;
else
// objIIS_Root has not been assigned a reference to a valid object.
nReturn = FALSE;
endif;

  return nReturn;
end;

////////////////////////////////////////////////////////////////////////
// Function: CheckIISExists
// Purpose:  Checks for the existence (and major version) of IIS
//    Returns -1 if not found OR major version number if found
//    Example:  Server 2003 would return 6 if IIS is installed
////////////////////////////////////////////////////////////////////////
function number CheckIISExists(hmsi)
NUMBER  nvType, nResult, nvIISVer, nvSize;
STRING  szKey, szIISVersion;

 begin
RegDBSetDefaultRoot ( HKEY_LOCAL_MACHINE );

nvIISVer = -1;
nvType = REGDB_NUMBER;
szKey = “\\SOFTWARE\\Microsoft\\InetStp“;
nResult = RegDBKeyExist(szKey);
if (nResult = 1) then
nResult = RegDBGetKeyValueEx(szKey, “MajorVersion”, nvType, szIISVersion, nvSize);
if (nResult = 0) && (szIISVersion != “”) then
StrToNum(nvIISVer, szIISVersion);
endif;
endif;

RegDBSetDefaultRoot (HKEY_CLASSES_ROOT);
return nvIISVer;
end;

////////////////////////////////////////////////////////////////////////
// Function: CheckVirtualDirExists
// Purpose:  Checks for the existence of a specific virtual directory
//
// NOTE:  THIS FUNCTION DOES NOT WORK ON SERVER 2003.  XP ONLY!!
//    DeleteVirtualDir does not need this function to be called.
////////////////////////////////////////////////////////////////////////
function number CheckVirtualDirExists(hmsi, sVDirName)
NUMBER  nType, nvSize, nReturn, nResult;
STRING  svReturn, VDir;

 begin
VDir     = “/” + sVDirName;
nType    = REGDB_STRING;
nvSize   = MAX_PATH;

  RegDBSetDefaultRoot ( HKEY_LOCAL_MACHINE );
nResult = RegDBGetKeyValueEx(“
\\SYSTEM\\CurrentControlSet\\Services\\W3SVC\\Parameters\\Virtual Roots\\”, VDir, nType, svReturn, nvSize );
RegDBSetDefaultRoot ( HKEY_CLASSES_ROOT );

if (nResult < 0) then
// The Virtual Directory does not exist
nReturn = FALSE;
MessageBox(“VirtualDir ” + sVDirName + ” not found, or does not exist.”, INFORMATION);
else
// The Virtual Directory does exist
nReturn = TRUE;
MessageBox(“VirtualDir ” + sVDirName + ” exists.”, INFORMATION);
endif;

  return nReturn;
end;

Tinggalkan komentar