开始时通过CreateProcess(\\windows\\wceload.exe........)来自动安装一个cab包,后来发现要安装多个,但是,createprocess这个函数必须在主函数返回后才会安装cab包,main函数都返回了,没法再安装第二个cab包了。
后来在网上一查,原来mobile的sdk中有个样例,其实很简单,只需要新建一个cab工程,将一个exe和一个dll还有要安装的cab放到你新建的cab包中,然后修改一下注册表搞定。做起来简单,理解起来还是要费点脑子哈。。。
windos mobile 6SDK中的例子(Program Files/Windows Mobile 6 SDK/Samples/Common/CPP/Win32/multicabinstall)
英文文档MultiCab Whitepaper.doc,这里简单翻译一下:
安装一个cab包中的多个cab包(cab包链)
微软公司
应用于:
Microsoft® VisualStudio® 2005
Microsoft Windows Mobile 5.0 SDK for Smartphone
Microsoft WindowsMobile 5.0 SDK for Pocket PC
Microsoft .NET Compact Framework version 2.0
概述:安装一个cab包中多个cab包(有时叫做cab包链)不会起作用除了windows mobile设备上。本文给出了安装多cab包的示例代码以及处理的过程。
这个白皮书演示了通过一个cab包安装和部署多个cab包(也就是我们所知的连续安装多cab包)的过程。这个描述看起来很简单,但是确实需要一些代码和工作量。然而,不要怕,白皮书提供的示例就是为了让你通过修改最少的代码很轻易地区创建一个你自己的连续安装的cab包。
这个到底怎么用呢?一个很好的连续安装cab包的例子就是将你的应用程序以及他的.NET2.0平台部署到windows mobile5.0的设备上。
这里我们感兴趣的技术关键点是解压cab包后里面的‘setup.dll’的作用,wceload 程序负责解压工作,这里面有我们创建的一个新的可执行文件,叫做MultiCab.exe。首先让我们讨论一下wceload.exe 。
wceload.exe在 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wcepbguide5/html/wce50lrfWceloadTool.asp这里以及其他可以很容易访问到的地方有描述。它执行的核心功能就是安装或者移除你指定目录中的cab包。如果你没有指定一个具体位置,cab包将会被安装在默认的位置,或者从默认的位置被移除。这个默认的位置就是你的目标设备上的 ProgramFiles 文件目录。
setup.dll 导出了 wceload.exe 在解压一个cab文件的不同时候所调用的函数,这些库函数可以在cab包安装过程中的不同阶段被编码去执行相应的操作。 在http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dv_evtuv/html/etgrfsetupdllfilesfordevices.asp这里至少可以看到一个扩展的文档。
导出的函数是:
Install_Init
Install_Exit
Uninstall_Init
Uninstall_Exit
这些函数所叫的名字就是你所认为的函数功能(更多细节可以查看MSDN文档)。Setup.dll的示例代码将会在我们的MCSetup的工程中应用。Dll的名字不是必须叫做setup.dll,而是在 ubercab包中所指定的名字。在这里我们创建这个dll并将它命名为MCSetup.dll.
MultiCab.exe也是作为这篇文章的一部分我们将要创建的一个可执行的文件,并且Uninstall_Exit 将会被引用。
这里是这些文件如何从一个cab包中连续安装多个cab包的一个高度概括,或者叫做 uber cab,打包了要安装的多个cab包。
下面我们就按照这些一步一步做。这里我将会演示在vs2005上市如何操作的,另外比较早一些版本的vs步骤也是相似的。
i. 在工程名字上右键然后 View(视图)->Registry(注册表)
就应该是这么做的。将uber cab部署到设备或者模拟器上,然后执行它。在它解压自己的时候就会立刻解压其内部的cab包。注意这里cab包将会按照上面注册表上的数字顺序进行解压安装。另外,由于.NetCFcab包安装完后需要重启设备,所以这里注意一定要将它放到最后安装。如果有多个cab安装完后需要重启,那么后面的cab将不会被安装。如果安装完后面的cab不需要重启,我们还可以添加其他的cab包,他们也会成功解压并被安装的。
在这个过程中MultiCab.exe 将会删除用过的注册表键,但是它不会删除自己,这也是为了以后的扩展以及留给用户查看。
重新使用这个示例cab安装工具是相当没有意义的。需要代码修改的只是在mcsetup.cpp 和 MultiCab.cpp 中,这里你你要指出你所希望的注册表的路径。
请看mcsetup.cpp 的51行以及在MultiCab.cpp中的124行,并且适合地替换 “Software\\ChainedCabSample”:
constTCHAR c_szAppRegPath[] = TEXT("Software\\ChainedCabSample")
你也必须去设置 在#4d步骤中%YourPath%\MultiCab\InstallCabName的值去命名你的uber cab的名字。 这个程序逻辑上假设uber cab 将 MultiCab.exe 安装到 \ProgramFiles\%YourCabName%\MultiCab.exe. (你也可以看到,示例中用 “UberCab” 作为名字)
其实,只需要按照#4e在智能设备项目指定要连续安装的cab包。然后按照上面的只是,编译修改过的setup.dll 和 MultiCab.exe。
注意相比改变少许代码就能实现安装而去改变MultiCab.exe的名字,或者改变一些程序的设定是相当没有意义的。
现在深入地理解 MultiCab.exe和 MCSetup.dll 究竟做了什么.
MCSetup.dll
代码这里为MultiCab.exe建立了路径然后调用ShellExecuteEx卸载MultiCab.exe.这个例子(在mcsetup.cpp中)建立了这样的路径:
1. 在HKEY_CURRENT_USER\Software\Microsoft\Multicab(这里 MultiCab是在c_szMultiCabApp设置的MultiCab.exe应用的名字) 中找到InstallCabName的注册表值(see line 68 and74). 这种情况想InstallCabName就是 “UberCab” 用于组建文件路径
2. 83行组建文件路径:
\ProgramFiles\UberCab\MultiCab.exe
3. 调用#2(94行)ShellExecuteEx
MultiCab.exe
注意: MultiCab.exe利用uber cab 创建的注册表来枚举所有的cab包,然后解压, 并且最终做一些简单的清理注册表的操作,这些逻辑是在multicab.cpp中。
1. WaitOnLoader (38行)是一个辅助函数用来等待wceload.exe结束. 这是必须的,因为,在安装下一个cab包之前,必须要等前一个完成以后,否则下一个cab包将会安装失败。
2. HostExec (98行) 是一个辅助函数用来执行多个cab包的解压
3. 选择124行你的注册表键的路径:
const TCHAR c_szAppRegPath[] = TEXT("Software\\ChainedCabSample");
const TCHAR c_szAppName[] =TEXT("MultiCab");
const TCHARc_szKeyValue[] =TEXT("InstallCabName");
4. HKEY_USERS_ROOT\Software\ChainedCabSample\Multicab保存了cab列表的子路径。
5. Using the registry value “” retrievedfrom step #4,用UberCab从#4获得的注册表的值HKEY_USERS_ROOT\Software\ChainedCabSample\Ubercabis构建. 这个键的句柄在179行打开并且一些内部包含的cab包通过181行的 RegQueryInfoKey获得
6. 用#5获得的句柄,这个循环从191行开始,枚举cab的注册表。
while(dwKey<= cKeyValues)
7. 每一个cab包将会在循环的地205行被执行,.WaitOnLoader是在继续安装下一个cab包之前等待上一个cab包安装完毕.
if (HostExec(szRegKeyValue,&hProcess))
{
WaitOnLoader();
}
8. 所有的cab包安装完以后,这个程序做一些注册表的清理机退出操作
刚搞定,就匆匆忙忙写了这篇翻译,有些不合适的地方,以后再修改吧。我倒感觉有这几幅图,很容易完成多cab包的安装,但是要深入理解,还是要看代码。
注意这里仅仅是做了一个cab包,这个cab包和普通的不一样,普通的就直接安装了,而这个可以连续安装cab包里面的多个cab包。
而我们可以简单的通过wceload.exe去加载这个cab包,来实现多cab连续安装的的功能。