18 扩展函数
扩展函数允许你调用动态链接库中的函数,调用Windows APIs,或运行另一个应用程序或安装程序脚本。UseDLL 和 UnUseDLL函数允许你装入一个DLL到内存中或卸载它并使用DLL。LaunchApp 和 LaunchAppAndWait函数允许你仍在执行脚本时运行另一个Windows 或DOS应用程序。
CallDLLFx
从一个外部DLL中调用函数。
Delay
延迟安装程序脚本的执行。
LaunchApp
运行另一个程序。
LaunchAppAndWait
运行另一个程序并等待该程序终止。
UnUseDLL
从内存卸载一个DLL。
UseDLL
把一个DLL装入到内存。
18.1 CallDLLFx
语法:CallDLLFx (szDLL, szFunction, lvValue, svValue);
说明:CallDLLFx函数调用一个指定的DLL中的函数。该函数必须使用下列固定定义,hwnd是InstallShield主窗口的主窗口句柄:
LONG APIENTRY YourFunction (HWND hwnd, LPLONG lpIValue, LPSTR lpszValue);
参数:
szDLL
指定包含要执行的函数的DLL的全限定文件名。
szFunction
指定由szDLL指定的DLL中的函数的名称。
IvValue
指定访问一个DLL函数时传递的长整型变量。
svValue
指定传递给DLL函数的字符串变量。
返回值:
CallDLLFx函数从DLL中的函数返回一个长整型数。
18.2 Delay
语法:Delay (nSeconds);
说明:Delay函数使一个安装程序脚本的执行延迟一个指定的秒数。其它和InstallShield同时运行的任务在InstallShield被延迟时仍正常进行。
参数:
nSeconds
指定程序被延迟的秒数。
返回值:
0:表明函数成功延迟了脚本的执行。
< 0:表明函数未能延迟了脚本的执行。
18.3 LaunchApp
语法:LaunchApp (szCommand, szCmdLine);
说明:LaunchApp函数允许你在脚本内运行另一个应用程序。该应用程序和脚本同时运行。InstallShield对运行的应用程序没有控制权并且不能确定运行的应用程序是否成功运行。运行的应用程序和其它在运行InstallShield时你启动的应用程序一样运行。你可以在InstallShield中运行任何你可以在操作系统中正常运行的应用程序。
参数:
szCommand
指定要运行的应用程序的全限定名。如果你指定一个没有路径的文件名,InstallShield在当前文件夹中,Windows 文件夹中,Windows系统文件夹中和列在环境变量PATH中的文件夹中查找。
如果应用程序的全限定名包括长文件夹名和/或一个长文件名,在把szCommand传递给LaunchAppAndWait之前先把它传递给LongPathToQuote。
szCmdLine
指定传递给szCommand标识的应用程序的命令行参数(如果有)。如果没有参数,则迟到一个空字符串。
返回值:
0:LaunchApp成功运行应用程序。
< 0:LaunchApp未能找到或未能运行应用程序。
注解:
·安装进程在应用程序被运行后继续。应用程序即使在安装脚本终止后仍可以运行。
·你也可以使用FindWindow 和 SendMessage函数来控制或发送消息给运行的应用程序。如果你想要在一个Window中运行一个DOS应用程序,你可以提供一个和DOS应用程序同名的PIF(Program Information File)。在PIF文件中,你指定应用程序运行在其下的一个窗口方式。
·运行一个DOS程序时,你不能确定返回结果DOS_ERRORLEVEL。然而你可以把一个DOS应用程序放进一个批处理文件,让批处理文件来识别错误并创建另一个包含返回错误代码的文件。然后你可以读该文件并确定从DOS应用程序返回的错误代码。
·LaunchApp 使用Windows API 的CreateProcess 来运行应用程序。
18.4 LaunchAppAndWait
语法:LaunchAppAndWait (szProgram, szCmdLine, lWait);
说明:LaunchAppAndWait函数运行由szProgram指定的带有szCmdLine指定的命令行参数的应用程序。第三个参数,lWait指示安装在继续前是否要等待直到运行的应用程序终止。
一个安装程序只能监控由szProgram指定的应用程序;如果该应用程序要运行其它应用程序或进程,安装程序不能监控它们。因此,安装程序将在第一个应用程序结束后继续,即使那时由第一个应用程序运行的其它应用程序仍在运行。注意如果运行的应用程序终止失败,则安装程序将无限等待运行的应用程序完成。
参数:
szProgram
指定要被运行的应用程序的文件名。建议要指定应用程序的完整路径和文件名。如果你不包括一个路径,InstallShield将使用被Windows API 函数CreateProcess使用的相同的查找次序来定位文件。如果文件未能在这些位置找到,函数将失败。
如果应用程序的全限定名包括长文件夹名和/或一个长文件名,在把szCommand传递给LaunchAppAndWait之前先把它传递给LongPathToQuote。
szCmdLine
指定传递给运行的应用程序的命令行参数。为运行没有命令行参数的应用程序,传递一个空字符串。
lWait
指定安装程序在继续前是否要等待运行的应用程序终止。在该参数位置传递下列预定义常量之一:
NOWAIT:指定安装程序在运行应用程序后立即继续,应用程序将和安装程序脚本同时运行。注意使用该参数等效于调用函数LaunchApp。
WAIT:指定安装程序必须等待直到由该函数运行的应用程序终止。
返回值:
1:表明应用程序成功运行。
< 0:表明应用程序未能运行。
注解:
·InstallShield 安装程序使用函数CreateProcess。在InstallShield运行应用程序后,它查找装入的应用程序的窗口句柄。如果它找到窗口句柄,则它在继续前等待直到应用程序窗口消失。
·安装程序不能监控一个不创建窗口的应用程序。如果指定的应用程序没有创建一个窗口,安装程序在运行应用程序后立即继续。注意应用程序的窗口不需要可见,但它必须存在,以便让安装程序等待。
·一些应用程序试图装入DLLs并且当那些DLLs不能被定位时不能正确运行。为确保一个应用程序能找到它需要的DLLs,有必要在调用LaunchAppAndWait前改变到包含可执行应用程序的目录。为改变当前目录,调用ChangeDirectory函数。
·如果运行的应用程序终止失败,则安装程序将无限等待运行的应用程序完成。
·LaunchAppAndWait以一个全屏DOS窗口来运行DOS程序。为以一个不同类型的窗口来运行一个DOS程序,你必须直接调用Windows APIs。
18.5 UnUseDLL
语法:UnUseDLL (szDLLName);
说明:UnUseDLL函数从内存卸载一个DLL。UnUseDLL将该DLL的锁计数减少一。当锁计数等于0时,InstallShield 卸载该 DLL。每一个对UseDLL的调用都必须有一个对应的对UnUseDLL的调用,因而DLLs在它们不再需要时不会留在内存中而浪费系统资源。一旦你卸载了一个DLL,你不能再调用该DLL中的函数。
Microsoft Windows系统 DLLs, 如 User.exe, User32.dll, Gdi.exe, Gdi32.dll, Krnl386.exe, Krnl286.exe, 和 Kernel32.dll,自动由Windows 装入和卸载。不要调用UseDLL 和UnUseDLL 来装入和卸载这些DLLs。
参数:
szDLLName
指定DLL的文件名。该参数不要包含路径。
返回值:
0:表明函数成功解锁和从内存卸载DLL。
< 0:表明函数未能解锁和卸载DLL。
注解:
如果脚本在用UnUseDLL正确卸载DLL前退出或终止,DLL将被锁定在内存。如果你试图再次访问DLL,你的脚本可能失败。你必须通过重启Windows来将DLL从内存中删除。
18.6 UseDLL
语法:UseDLL (szDLLName);
说明:UseDLL函数把一个DLL装入内存。在DLL已经被装入内存后,你的安装程序脚本可以调用该DLL中的函数。注意如果由szDLLName指定的DLL需要其它DLL,那些DLL必须位于某个文件夹中,该DLL试图从这个文件夹装入它们。正常时它是当前目录。为确保那些DLL可以被定位,在调用UseDLL前调用ChangeDirectory来改变当前目录到那些DLL所处的位置。若不能做到这些,则可能DLL不能被正确装入。
每次你将一个DLL装入到内存,该DLL的锁计数增加。锁计数计算使用该DLL的应用程序的数目。你不再使用DLL时,你必须马上调用UnUseDLL来卸载它。如果你不卸载不再需要的DLL,则该DLL在没有应用程序需要它时仍会留在内存中,因而浪费系统资源。在脚本中每个对UseDLL的调用必须有一个相对应的UnUseDLL调用。
Microsoft Windows系统 DLLs, 如 User.exe, User32.dll, Gdi.exe, Gdi32.dll, Krnl386.exe, Krnl286.exe, 和 Kernel32.dll,自动由Windows 装入和卸载。不要调用UseDLL 和UnUseDLL 来装入和卸载这些DLLs。
参数:
szDLLName
指定要装入的DLL名。如果你未指定一个扩展名,InstallShield假定文件扩展名为.dll 或.exe。建议该参数包括一个路径,但只是可选。如果该参数没有指定DLL的路径,InstallShield将使用和Windows API 函数LoadLibrary使用的相同的查找次序来查找DLL。
有关查找次序的更多信息可查看Windows API函数的说明。
为在你的安装中包含DLL,把它添加到安装文件窗格中的Language Independent文件夹的合适的子文件夹中。InstallShield将把它压缩到你的安装中。当Setup.exe执行时,它自动解压缩并把你的安装的内容拷贝到由SUPPORTDIR指定的临时目录中。然后你可以添加DLL文件名到SUPPROTDIR以便指向该DLL,如下所示:
szDLLName = SUPPORTDIR^"MYDLL.DLL";
UseDLL (szDLLName);
如果你不放置你的DLL到你的安装中(通过把它插入到安装文件窗格中的合适文件夹中),你可以把文件和你的应用程序文件一起分散,然后从目标系统装入它。然而,如果你这么做,你必须指定你把DLL安装到的位置使得你的安装程序可以指向它。你也必须确保你的安装程序不会试图在DLL被传输到目标系统之前装入它。
返回值:
0:表明函数成功地把DLL装入内存。
< 0:表明函数未能把DLL装入内存。
注解:
·如果UseDLL失败,最大的可能性是DLL没有找到。如果这样,确保参数szDLLName指定了正确的路径。
·另一个通常的使用DLL的错误原因和DLL的依赖性有关:被你装入的DLL所访问的DLLs。如果你的DLL 访问的DLLs没有被装入或没有找到,你的DLL调用可能失败。如果发生这种情况,确保其它DLL存在于系统上并且它们是可访问的。
·如果脚本在用UnUseDLL正确卸载DLL前退出或终止,DLL将被锁定在内存。如果你试图再次访问DLL,脚本可能失败。你必须通过重启Windows来将DLL从内存中删除。