Installation 如何通过自定义操作读取包代码

Installation 如何通过自定义操作读取包代码,installation,windows-installer,installshield-2012,Installation,Windows Installer,Installshield 2012,是否可以通过自定义操作读取程序包代码,如读取ProductCode和ProductName。我想删除在%LOCALAPPDATA%/Downloaded Installations/GUID中创建的MSI缓存,其中GUID是卸载过程中的程序包代码。让我们详细了解一下。首先,我们必须回答包代码存储在哪里。在第三段中介绍了这一点:“包代码存储在摘要信息流的修订号摘要属性中。好的,那么我们如何读取它呢?上面已经讲过了,从打电话开始。但这段代码将从自定义操作调用,所以让我们验证它是否正常。包括这个。扫描

是否可以通过自定义操作读取程序包代码,如读取ProductCode和ProductName。我想删除在%LOCALAPPDATA%/Downloaded Installations/GUID中创建的MSI缓存,其中GUID是卸载过程中的程序包代码。

让我们详细了解一下。首先,我们必须回答包代码存储在哪里。在第三段中介绍了这一点:“包代码存储在摘要信息流的修订号摘要属性中。好的,那么我们如何读取它呢?上面已经讲过了,从打电话开始。但这段代码将从自定义操作调用,所以让我们验证它是否正常。包括这个。扫描列表时,我们发现没有提到摘要信息函数(除了MsiCreateTransformSummaryInfo,此处不需要)


是的,这是可能的。

您可能想看看我不久前写的这段代码:(整个线程都读得很好)


不删除=“全部”/>
删除=“全部”/>
导出原型PurgeCache(HWND);
函数PurgeCache(hMSI)
结果数;
字符串模式;
字符串根;
字符串szDir;
字符串szPackageCode;
列出列表目录;
开始
szInstallMode=MsiGetCustomActionDataAttribute(hMSI,“/InstallMode=”);
szCacheRoot=MsiGetCustomActionDataAttribute(hMSI,“/CacheRoot=”);
szPackageCode=MsiGetCustomActionDataAttribute(hMSI,“/PackageCode=”);
listDirs=ListCreate(STRINGLIST);
FindAllDirs(szCacheRoot、EXCLUDE_SUBDIR、listDirs);
nResult=ListGetFirstString(listDirs,szDir);
while(nResult!=列表的结尾);
如果(szInstallMode=“Uninstall”| |!(szDir%szPackageCode)),则
DeleteDir(szDir,ALLCONTENTS);
endif;
nResult=ListGetNextString(listDirs,szDir);
结束时;
返回错误\成功;
结束;

为什么要在自定义操作中经历所有这些麻烦?安装程序在安装开始时设置PackageCode属性。是,PackageCode属性在安装/卸载期间可用。我的问题解决了。顺便说一句,套件安装程序能让这更好吗?这是一个很好的观点。我的新辩护是,这种方法应该扩展到一个次要的.msi文件(但OP没有明确要求)。至于使“这个”更好的套房,我不是100%的“这个”是什么,但我不认为他们处理它有什么不同。最基本的问题是,在哪种情况下,你想要清理还是阻止重新下载。你不需要一个虚构的防御。你是一位著名而受人尊敬的专家。我们并不总是完美的。:)“这”是指套件安装人员知道以前缓存的MSI,并根据需要自动清理。克里斯,我已经浏览了你的线程。我创建了一个自定义操作,在卸载过程中通过读取PackageCode删除缓存文件夹,因为我的产品支持多版本。因此,自定义操作仅删除一个文件夹。这是正确的方法吗?在升级过程中,逻辑会删除除当前文件夹之外的所有文件夹。在卸载过程中,它会删除所有folders.PS-可以在此处找到MsiGetCustomActionDataAttribute函数源:ISSetupFilesExtract是在我的项目中执行的第一个操作(将MSI缓存复制到目标计算机)。如何在ISSetupFilesExtract操作之前运行自定义操作,以便在安装开始时删除MSI缓存。在您的项目中,ScheduleReboot.ISSetupFilesExtract不会将MSI缓存复制到目标计算机上。ISSetupFilesExtract将ISSetupFiles表中的任何文件提取到临时目录,然后将SUPPORTDIR属性设置为此目录的位置。Setup.exe将MSI提取到缓存中,然后从那里运行MSI。关键是,MSI在实际调用MSI之前就已经存在了。
<CustomAction Id="PurgeCache_CAD_Install"  Execute="immediate" Property="PurgeCache" Value="/CacheRoot=[CommonAppDataFolder]Downloaded Installations\MyCompany\MyProduct /PackageCode=[PackageCode] /InstallMode=Install"/>
<CustomAction Id="PurgeCache_CAD_Uninstall" Execute="immediate" Property="PurgeCache" Value="/CacheRoot=[CommonAppDataFolder]Downloaded Installations\MyCompany\MyProduct /PackageCode=[PackageCode] /InstallMode=UnInstall"/>
<InstallExecuteSequence>
  <Custom Action="PurgeCache_CAD_Install" After="ScheduleReboot">Not REMOVE="ALL"/>
  <Custom Action="PurgeCache_CAD_Uninstall" After="ScheduleReboot">REMOVE="ALL"/>
</InstallExecuteSequence>

export prototype PurgeCache(HWND);  

function PurgeCache(hMSI)

    number nResult; 
    string szInstallMode;           
    string szCacheRoot;
        string szDir;
        string szPackageCode;
    LIST listDirs;   

begin

    szInstallMode = MsiGetCustomActionDataAttribute( hMSI, "/InstallMode=" );   
    szCacheRoot = MsiGetCustomActionDataAttribute( hMSI, "/CacheRoot=" );
    szPackageCode = MsiGetCustomActionDataAttribute( hMSI, "/PackageCode=" );

    listDirs = ListCreate (STRINGLIST);
    FindAllDirs( szCacheRoot, EXCLUDE_SUBDIR, listDirs );
    nResult = ListGetFirstString (listDirs, szDir);
    while (nResult != END_OF_LIST);  

        if ( szInstallMode = "Uninstall" || !( szDir % szPackageCode )) then
            DeleteDir( szDir, ALLCONTENTS );
        endif;
        nResult = ListGetNextString (listDirs, szDir);

    endwhile;

 return ERROR_SUCCESS;

end;