我正在使用基本的MSI设置。
我正在尝试让光盘提示说“请插入下一张光盘”,然后将继续让用户插入下一张光盘,然后继续安装。
这是我的设置:
我设法使用允许光盘跨越的Installshield向导。我将其设置为手动,并指定文件应该在哪里。完成此过程后,我留下三(3)个文件夹,标题为“DISC1”,“DISC2”和“DISC3”。
我刻录了第一张光盘,希望一切工作正常,并且一旦它识别出有内容试图复制而不是在光盘上,它就会提示我......但是......它会引发错误说它无法在光盘上找到内容(惊喜!)
我想知道到目前为止我做错了什么?有人有同样的问题吗?
由于
答案 0 :(得分:2)
旧安装程序中的问题是升级期望在CD介质上的相同文件夹中找到从一个安装程序到另一个安装程序的安装程序。 (它还需要相同的.MSI文件名。)初始安装完成后,CD文件夹将记录在MediaPackage注册表项中。当upgrqade安装程序查找该文件夹但未找到它(因为它已更改)时,它会弹出“插入磁盘1”对话框,以便您可以查找它。烦。
不知道这是否已针对较新版本的Windows Installer进行了修复,因为我们已将这些解决方法保留在安装程序中,并且必须将其取出才能再次进行测试。
第一个解决方案是保持CD文件夹名称相同 - 建立坚如磐石的媒体要求。
如果那是不可能的(因为构建媒体的白痴会忘记? - 或媒体要求发生变化),下一个解决方案是创建一个自定义操作,将MediaPackagePath文件夹条目更改为当前CD文件夹并在动作序列中尽早放置,以便安装程序不会抱怨(在它实际查找MediaPackage文件夹值之前)。 AND,创建一个回滚自定义操作,以便在用户取消安装时恢复旧的MediaPackage值。
这并不简单,因为它还涉及使用加密产品GUID。 因此,您必须执行一项操作,该操作还会从标准ProductID生成加密ID。
// 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
我有三个自定义操作:
CalculateCompressedProdGUID() - 放置在执行序列中的ISSetupFilesExtract之后。这将计算加密的ID并将其保存在属性中。这还将旧的MediaPackagePath保存在属性中以进行回滚。放置动作无疑是有效的,因为它发生在ResolveSource()之前。
ResetMediaPackagePath() - 放置在执行序列中的SetCompressedProdGUID()之后,因为它需要加密的ID。
RollbackMediaPackagePath() - 如果用户取消安装,则重置旧的MediaPackage值。此操作必须在InstallInitialize()之后发生,因为它是一个回滚操作(它仅在回滚期间参与)。
自定义操作仅限于使用次要升级运行,因为主要升级会自动删除所有注册并重做它,因此没有问题。实际上,所有这些必须在更改CD上产品文件夹的名称时保留进行小幅升级的可能性。
代码可能看起来像刚刚复制到这里的垃圾(如果你认为需要改进的话就改进它):
***************
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;
答案 1 :(得分:1)
Windows Installer要求每张光盘的卷名与Media表中的条目相匹配。我认为这些默认为DISK1,DISK2,DISK3等(您为InstallShield创建的文件夹提到的名称),所以除非您覆盖它们,否则请使用它们。