Kyle
Kyle

Reputation: 85

Installshield getting to prompt "Insert Disc 2", etc

I am using a basic MSI setup.

I am trying to get the disc to prompt to say "Please insert next disc" which will then continue for the user to insert the next disc and then continue installation.

Here is my setup:

  1. DVD1: Install
  2. DVD2: Media Content 1 (has content to copy over to the same folder as the Install)
  3. DVD3: Media Content 2

I managed to use the Installshield wizard which allows disc spanning. I set it to Manual, and specified the files where they should be. After going through this process, I am left with Three (3) folders titled "DISC1", "DISC2", and "DISC3".

I burned the first disc, expecting for everything to work fine, and for it to prompt me once it recognizes that there is content attempting to copy over that is not on that disc.. but instead... it throws an error saying that it cannot find the content on the disc (surprise!)

I was wondering what I am doing wrong so far? Anyone have this same problem?

Thanks

Upvotes: 3

Views: 3466

Answers (3)

march_happy
march_happy

Reputation: 450

I'd like to thank girish's hint on old msiexec.exe behaviour. I was trying to install .net Framework SDK 1.1 on Windows ME (kernelex enabled), for figuring out some missing dlls in vc7.1 and hit the same error for inserting new disc.

After running msiexec with /L*v "C:\msi.log, I could clearly see the root cause is a wrong Volume label:

msiexec's log shows the root cause for prompting "insert the disk" error was a wrong label

As this Windows ME install is running inside 86Box, I ejected CD drive, renamed that folder and mount again. Now, the setup coutinues without errors.

Upvotes: 0

girish
girish

Reputation: 61

The issue in older installers was that the upgrade expects to find your installer in the SAME FOLDER on CD media from one installer to another. (It also expects the same .MSI filename.) When the initial installation is done the CD folder is recorded in a MediaPackage registry entry. And when the upgrqade installer looks for that folder and doesn't find it (because it got changed), it pops the Insert Disk 1 dialog so that you can look for it. Annoying.

Don't know whether this has been fixed for newer versions of Windows Installer, since we have kept our workaround in the installers and would have to take it out to really test again.

The first solution is to keep the CD folder name the same -- establish a rock solid media requirement.

If that isn't possible (because the idiots who build your media keep forgetting? -- or there are shifts in media requirements), the next solution is to create a custom action that changes the MediaPackagePath folder entry to the current CD folder and place this early enough in the action sequence so that the installer doesn't complain (before it actually looks up that MediaPackage folder value). AND, create a Rollback Custom action to RESTORE the old MediaPackage value if the user cancels out of the installation.

This isn't simple, since it also involves using the Encrypted product GUID. So you have to have an action that also generates the encryped ID from the standard ProductID.

// For XP/2000/NT MediaPackage is set in two places:
// 1. HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Installer\
// Products\<encrypted prod guid>\SourceList\Media 
// MediaPackage
// 2. HKEY_CLASSES_ROOT\Installer\Products\
// <encrypted prod guid>\SourceList\Media
// MediaPackage

I have three custom actions:

  1. CalculateCompressedProdGUID() -- Placed after ISSetupFilesExtract in the Execute sequence. This calculates the encrypted ID and saves it in a property. This also saves the old MediaPackagePath in a property for purposes of rollback. Placing the action here no doubt works because it occurs before ResolveSource().

  2. ResetMediaPackagePath() -- Placed after SetCompressedProdGUID() in the Execute sequence, since it needs the encrypted ID.

  3. RollbackMediaPackagePath() -- Resets the old MediaPackage value if the user cancels out of the installation. This action has to occure after InstallInitialize() because it is a Rollback action (it engages only during rollback).

The custom actions are conditioned to run with Minor Upgrade only, since major upgrade automatically removes all registration and redoes it, and hence there is no problem. In fact, all this rigamarole is just to SAVE the possibility of doing a minor upgrade while changing the name of the product folder on the CD.

The code is probably going to look like garbage just copied here (improve it if you think it needs to be improved):

***************

function CalculateCompressedProdGUID(hMsi) 
STRING svSubStr, svProductGUID;
STRING szCompressedGUID; // return value 
NUMBER iCount, nBuffer;
begin 

MsiGetProperty(ISMSI_HANDLE, "ProductCode", svProductGUID, nBuffer);

// character 0 of the GUID is {
szCompressedGUID = "";
// first group - reverse order
for iCount = 8 downto 1 
StrSub(svSubStr, svProductGUID, iCount, 1);
szCompressedGUID = szCompressedGUID + svSubStr; 
endfor; 
// second group - reverse order
// character 9 is - 
for iCount = 13 downto 10 
StrSub(svSubStr, svProductGUID, iCount, 1);
szCompressedGUID = szCompressedGUID + svSubStr; 
endfor;
// third group - reverse order
// character 14 is -
for iCount = 18 downto 15 
StrSub(svSubStr, svProductGUID, iCount, 1);
szCompressedGUID = szCompressedGUID + svSubStr; 
endfor;
// fourth group - swap every other
// character 19 is -
for iCount = 20 to 23 step 2
StrSub(svSubStr, svProductGUID, iCount + 1, 1);
szCompressedGUID = szCompressedGUID + svSubStr;
StrSub(svSubStr, svProductGUID, iCount, 1);
szCompressedGUID = szCompressedGUID + svSubStr;
endfor; 
// fifth group - swap every other
// character 24 is -
for iCount = 25 to 36 step 2 
StrSub(svSubStr, svProductGUID, iCount + 1, 1);
szCompressedGUID = szCompressedGUID + svSubStr;
StrSub(svSubStr, svProductGUID, iCount, 1);
szCompressedGUID = szCompressedGUID + svSubStr;
endfor; 
// character 37 of the GUID is } - so ignore 

MsiSetProperty(ISMSI_HANDLE, "COMPRESSED_PROD_GUID", szCompressedGUID);

return ERROR_SUCCESS;

end; 


*******************

function SetMediaPackagePathRegistryEntry(hMsi)
STRING svDBMediaPackagePath, szCompressedGUID, szKey; 
STRING svIsMinorUpgrade, svPathValue;
NUMBER nBuffer, nReturn, nvPathSize, nvType;
begin 

// For XP/2000/NT MediaPackage is set in two places:
// 1. HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Installer\
// Products\<encrypted prod guid>\SourceList\Media 
// MediaPackage
// 2. HKEY_CLASSES_ROOT\Installer\Products\
// <encrypted prod guid>\SourceList\Media
// MediaPackage

// precaution against using during non-Minor Upgrade 
svIsMinorUpgrade = "0";
nBuffer = 1;
MsiGetProperty (ISMSI_HANDLE, "IS_MINOR_UPGRADE", svIsMinorUpgrade, nBuffer);
if (svIsMinorUpgrade != "1") then
return ERROR_SUCCESS;
endif;

nBuffer = 40;
MsiGetProperty(ISMSI_HANDLE, "COMPRESSED_PROD_GUID", szCompressedGUID, nBuffer);

svPathValue = "\\"; // default
// Save the value for rollback functionality:
if (RegDBGetKeyValueEx ( szKey, "MediaPackage", nvType, svPathValue, nvPathSize ) = 0) then
MsiSetProperty(ISMSI_HANDLE, "MEDIAPACKAGEPATHROLLBACK", svPathValue);
endif; 

nBuffer = 130;
MsiGetProperty(ISMSI_HANDLE, "MEDIAPACKAGEPATH", svDBMediaPackagePath, nBuffer);


// This is the main location MediaPackage is stored on 2000/XP/NT
RegDBSetDefaultRoot(HKEY_CLASSES_ROOT);
szKey = "Installer\\Products\\";
szKey = szKey + szCompressedGUID + "\\SourceList\\Media";
RegDBSetKeyValueEx ( szKey, "MediaPackage", REGDB_STRING, svDBMediaPackagePath, -1 );
// This is the secondary location.
RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE);
szKey = "SOFTWARE\\Classes\\Installer\\Products\\";
szKey = szKey + szCompressedGUID + "\\SourceList\\Media";
RegDBSetKeyValueEx ( szKey, "MediaPackage", REGDB_STRING, svDBMediaPackagePath, -1 );

return ERROR_SUCCESS;

end; 


*************************

function RollbackMediaPackagePathRegistryEntry(hMSI)
STRING svRollbackPackagePath, szCompressedGUID, szKey; 
STRING svIsMinorUpgrade, svPathValue;
NUMBER nBuffer, nvPathSize, nReturn;
begin 

// For XP/2000/NT MediaPackage is set in two places:
// 1. HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Installer\
// Products\<encrypted prod guid>\SourceList\Media 
// MediaPackage
// 2. HKEY_CLASSES_ROOT\Installer\Products\
// <encrypted prod guid>\SourceList\Media
// MediaPackage 

// Remember that we no longer support Windows 98.

nBuffer = 1;
svIsMinorUpgrade = "0";
MsiGetProperty (ISMSI_HANDLE, "IS_MINOR_UPGRADE", svIsMinorUpgrade, nBuffer);
// precaution against use during non-Minor Upgrade
if (svIsMinorUpgrade != "1") then
return ERROR_SUCCESS;
endif;

nBuffer = 40;
MsiGetProperty(ISMSI_HANDLE, "COMPRESSED_PROD_GUID", szCompressedGUID, nBuffer);

// Get the rollback path
nBuffer = 130;
MsiGetProperty (ISMSI_HANDLE, "MEDIAPACKAGEPATHROLLBACK", svRollbackPackagePath, nBuffer);

// Primary location
RegDBSetDefaultRoot(HKEY_CLASSES_ROOT);
szKey = "Installer\\Products\\" + szCompressedGUID + "\\SourceList\\Media";
RegDBSetKeyValueEx ( szKey, "MediaPackage", REGDB_STRING, svRollbackPackagePath, -1 );
// Secondary location 
RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE);
szKey = "SOFTWARE\\Classes\\Installer\\Products\\" + szCompressedGUID + "\\SourceList\\Media";
RegDBSetKeyValueEx ( szKey, "MediaPackage", REGDB_STRING, svRollbackPackagePath, -1 );

return ERROR_SUCCESS;

end;

Upvotes: 2

Michael Urman
Michael Urman

Reputation: 15905

Windows Installer requires the volume name of each disc to match its entry in the Media table. I think these default to DISK1, DISK2, DISK3, etc. (the names you mention for the folders that InstallShield created), so use those unless you've overridden them.

Upvotes: 1

Related Questions