Nav*_*eev 2 vbscript windows-installer
我正在寻找使用VBScript从MSI外部安装或不安装(无论哪个更快)解析MSI中文件的路径.
我找到了一个使用C#的类似查询而Christopher提供了一个解决方案,如下所示:我如何在C#中解析MSI路径?
我现在正经历着同样的痛苦,但无论如何都要使用VBScript中的WindowsInstaller对象实现这一点,而不是通过MSI来回的SQL表进行无休止的查询来实现相同的目的.虽然任何方向都会受到欢迎,因为我已经尝试过尽我所能,但成功非常有限.
是的,有一个解决方案没有安装msi和使用vbscript.Windows Installer SDK中有一个非常好的例子叫做"WiFilVer.vbs"
使用该示例,我将一个快速示例脚本放在一起,完全满足您的需要.
set installer = CreateObject("WindowsInstaller.Installer")
const READONLY = 0
set db = installer.OpenDataBase("<FULL PATH TO YOUR MSI>", READONLY)
set session = installer.OpenPackage(db, READONLY)
session.DoAction("CostInitialize")
session.DoAction("CostFinalize")
set view = db.OpenView("SELECT File, Directory_, FileName, Component_, Component FROM File,Component WHERE Component=Component_ ORDER BY Directory_")
view.Execute
set record = view.Fetch
do until record is nothing
file = record.StringData(1)
directoryName = record.StringData(2)
fileName = record.StringData(3)
if instr(fileName, "|") then fileName = split(fileName, "|")(1)
wsh.echo(session.TargetPath(directoryName) & fileName)
set record = view.Fetch
loop
Run Code Online (Sandbox Code Playgroud)
只需添加MSI文件的路径即可.
告诉我你是否需要更详细的答案.今晚我将有更多时间详细回答这个问题.
编辑承诺的背景(以及为什么我需要调用ConstFinalize)
naveen实际上MSDN是唯一可以给出明确答案的资源,但你需要知道在哪里以及如何看,因为Windows安装程序是恕我直言,这是一个相当复杂的话题.我真的推荐混合msdn 安装程序函数引用,数据库引用和windows安装程序SDK中的示例(抱歉找不到下载链接,我认为它隐藏在3GB windows SDK中的某处)
首先,您需要MSI的一般知识:
MSI实际上是一个关系数据库.一切都存储在彼此相关的表中.(实际上不是一切,但我会尽量保持简单;))
此数据库由Windows Installer解释,这会创建一个"会话"
某些部分也会动态解析,具体取决于您安装msi的系统,例如类似于环境变量的"特殊"文件夹.例如,msi有一个"ProgramFilesFolder",其中windows通常有%ProgramFiles%.
所有动态内容仅存在于安装程序会话中,而不是数据库本身.
在您的情况下,您需要查看3个表,处理关系并解决它们.
'File'表包含所有文件,'Component'表告诉您哪个文件进入哪个目录,'Directory'表包含有关文件系统结构的所有信息.
使用SQL查询,我可以链接组件和文件表以查找目录名称(或数据库术语中的主键).
但目录表本身具有关系,其结构类似于树.看一下这个示例目录表(取自instEd MSI)
列是Directory,Directory_Parent和DefaultDir
InstEdAllUseAppDat InstEdAppData InstEd
INSTALLDIR InstEdPF InstEd
CUBDIR INSTALLDIR hkyb3vcm|Validation
InstEdAppData CommonAppDataFolder instedit.com
CommonAppDataFolder TARGETDIR .
TARGETDIR SourceDir
InstEdPF ProgramFilesFolder instedit.com
ProgramFilesFolder TARGETDIR .
ProgramMenuFolder TARGETDIR .
SendToFolder TARGETDIR .
WindowsFolder_x86_VC.1DEE2A86_2F57_3629_8107_A71DBB4DBED2 TARGETDIR Win
SystemFolder_x86_VC.1DEE2A86_2F57_3629_8107_A71DBB4DBED2 WindowsFolder_x86_VC.1DEE2A86_2F57_3629_8107_A71DBB4DBED2 System
Run Code Online (Sandbox Code Playgroud)
directory_parent将其链接到目录.DefaultDir包含实际名称.您现在可以自己解析树并替换所有特殊文件夹(在vbscript中会非常繁琐)......
...或者让Windows安装程序处理它(就像安装msi时一样).现在我必须引入一个新东西:动作(和序列):当运行(安装,删除,修复)msi时,执行定义的动作列表.有些动作只是收集信息,有些则改变了实际的数据库.
msi可以执行各种操作的动作列表(称为序列),例如一个用于安装的序列(称为InstallExecuteSequence),一个用于从用户收集信息(MSI的UI:InstallUISequence)或一个用于管理点安装(AdminExecuteSequence) ).
在我们的例子中,我们不希望运行整个序列(可能会改变系统或只需要很长时间),幸运的是,Windows安装程序允许我们在不运行整个序列的情况下运行单个操作.阅读MSDN上的目录表的引用(备注部分),您可以看到您需要的操作:
Directory resolution is performed during the CostFinalize action
Run Code Online (Sandbox Code Playgroud)
把所有这些放在一起脚本更容易阅读*打开msi文件*'解析'它(提供会话)*查询组件和文件表*运行CostFinalize操作来解析目录表(不运行整个MSI)*get具有targetPath函数的已解析路径
顺便说一下,我通过浏览MSDN上的安装程序参考找到了targetPath函数,我只是注意到不需要CostInitialize.如果您想获取文件的sourcePath,则只需要它.
我希望这能使一切更加清晰,很难解释,因为我花了半年的时间来理解它;)
关于PhilmEs的回答:是的,对目录表的解析有更多影响,比如自定义操作.记住这一点,管理安装可能会导致不同的directorys(例如,因为不同的序列可能会持有不同的自定义操作).组件有条件,因此可能根本没有安装文件.我非常确定InstEd也不会考虑自定义操作.
所以是的,没有100%的解决方案.也许一切都是必要的.
| 归档时间: |
|
| 查看次数: |
2336 次 |
| 最近记录: |