|
invoke_application随想!
WinRunner作为一个自动化测试工具,他的脚本引擎封装了一些window底层函数,然后实现相应的功能!api中有三个函数有启动应用程序的功能,我们分别来看看
1)WinExec() 函数原型:
UINT WinExec(LPCSTR lpCmdLine,UINT uCmdShow);
参数说明:(激活的意思是能接受焦点,即标题栏变成蓝色)
lpCmdLine:以0结尾的字符串,命令行参数。
uCmdShow:新的应用程序的运行方式。其取值如下:
SW_HIDE 隐藏
SW_MAXIMIZE 最大化
SW_MINIMIZE 最小化,并把Z order顺序在此窗口之后(即窗口下一层)的窗口激活
SW_RESTORE 激活窗口并还原为初始化大小 SW_SHOW 以当前大小和状态激活窗口
SW_SHOWDEFAULT 以默认方式运行
SW_SHOWMAXIMIZED 激活窗口并最大化
SW_SHOWMINIMIZED 激活窗口并最小化
SW_SHOWMINNOACTIVE 最小化但不改变当前激活的窗口
SW_SHOWNA 以当前状态显示窗口但不改变当前激活的窗口
SW_SHOWNOACTIVATE 以初始化大小显示窗口但不改变当前激活的窗口
SW_SHOWNORMAL 激活并显示窗口,如果是最大(小)化,窗口将会还原。第一次运行程序
时应该使用这个值
比如说,我想要用记事本打开"C:\HDC.TXT",以正常方式运行:
WinExec("notepad c:\\hdc.txt",SW_SHOWNORMAL);
如果调用成功,这个函数会返回一个不小于31的值,否则调用失败,其返回值的意义如
下:
0 系统内存或资源不足
ERROR_BAD_FORMAT .EXE文件格式无效(比如不是32位应用程序)
ERROR_FILE_NOT_FOUND 指定的文件设有找到
ERROR_PATH_NOT_FOUND 指定的路径没有找到
这个函数和system()非常类似,只能运行.EXE文件,这样在WINDOWS中有它不尽人意的地
方,比如不能用此方法通过关联的方法打开文件,例如WinExec("1.html",SW_SHOWNA);
就不能打开此文档。
2)ShellExecute()
函数原型:
HINSTANCE ShellExecute( HWND hwnd, LPCTSTR lpOperation, LPCTSTR lpFile, LPCT
STR lpParameters, LPCTSTR lpDirectory, INT nShowCmd );
参数说明:
hwnd 窗口的句柄
lpOperation 进行的操作,如"open","print","explore"分别对应"打开","打印","游览
", 也可以为空(""),此时表示进行默认的操作。
lpFile 要操作的文件。
lpParameters 如果lpFile指定的是一个可执行文件则表示参数
lpDirectory 操作进行的目录 nShowCmd 程序的运行方式,其取值见上例。
如果这个函数调用成功,将返回实例的句柄,如果不成功,返回值包含错误信息,
类型比较多,详见WinApi的帮助。
这样,上面的例子就可以改变为(假设窗口的句柄为Handle)
ShellExecute(Handle,"open","notepad","c:\\hdc.txt","",SW_SHOWNORMAL);
其实不用那么复杂,因为.TXT的关联程序就是记事本,所以只要这样就可以了
ShellExecute(Handle,"","c:\\hdc.txt","","",SW_SHOWNORMAL);
最后一个nShowCmd的参数类型可以参看WinExec的显示参数!
从上面可看出,ShellExecute的功能要强得多,并且可以完全替代WinExec(),事实上,
WinExec()也是为了和以前版本兼容而保留,所以,我们要尽量使用ShellExecute()。
介绍一个功能强大的API函数 ShellExecute
3)CreateProcess最复杂,一共有十个参数,不过大部分都可以用NULL代替,它可以指定进程的安全属性,继承信息,类的优先级等等.来看个很简单的 Example:
STARTUPINFO stinfo; //启动窗口的信息
PROCESSINFO procinfo; //进程的信息
CreateProcess(NULL,_T("notepad.exe"),NULL,NULL.FALSE, NORMAL_PRIORITY_CLASS,NULL,NULL, &stinfo,&procinfo);
利用CreateProcess函数来创建一个进程去执行其他程序,而且可以设置该进程的优先级。CreateProcess函数的原型是:
BOOL CreateProcess(
LPCTSTR lpAppliciatonName
LPTSTR lpCommandLine
LPSECURITY_ATTRIBUTES lpProcessAttributes
LPSECURITY_ATTRIBUTES lpThreadAttributes
BOOL bInheritHandles
DWORD dwCreationFlags
LPVOID lpEnvironment
LPCTSTR lpCurrentDirectory
LPSTARTUPINFO lpStartupInfo
LPPROCESS_INFORMATION lpProcessInformation
);
当系统调用CreateProcess时,会创建一个进程内核对象,其初始使用计数是1。该进程内核对象不是进程本身,而是操作系统管理进程时使用的一个较小的数据结构。然后,系统为新进程创建一个虚拟地址空间,并将可执行文件或任何必要的DLL文件的代码和数据加载到该进程的地址空间中。接着,系统为新进程的主线程创建一个线程内核对象(其使用计数为1)。与进程内核对象一样,线程内核对象也是操作系统用来管理线程的小型数据结构。通过执行C/C++运行期启动代码,该主线程便开始运行,它最终调用WinMain、wWinMain、main或wmain函数。如果系统成功创建了新进程和主线程,CreateProcess便返回True。
PszApplicationName和pszCommandLine参数分别用于设定新进程将要使用的可执行文件的名字和传递给新进程的命令行字符串。PszApplicationName的参数可以是NULL,表示系统将使用全路径来查看可执行文件,并且不再搜索这些目录;如果参数不是NULL可以将地址传递给pszApplicationName参数中包含可运行的文件的名字字符串。当系统找到了可执行文件后,就创建一个新进程,并将可执行文件的代码和数据映射到新进程的地址空间中。
PsaProcess和psaThread参数分别设定进程对象和线程对象需要的安全性。可以为这些参数传递NULL,这种情况下,系统为这些对象赋予默认安全性描述符;也可以指定两个SECURITY_ATTRIBUTES结构,并对它们进行初始化,以便创建自己的安全性权限,并将它们赋予进程对象和线程对象。将SECRURITY_ATTRIBUTES 结构用于psaProcess和psaThread参数的另一个原因是,父进程将来生成的任何子进程都可以继承这两个对象句柄中的任何一个。本程序除了创键调用ANSYS计算模块的进程外,无需再创建其它进程,因而,psaProcess和psaThread参数都为NULL。同理,binheritHandles参数为FALSE。
fdwCreate参数用于标识标志,以便用于规定如何来创建新进程,fdwCreate参数也可以用来设定优先级类,不过对于大多数应用程序来说不应该这样做,因为系统会为新进程赋予一个默认优先级。
PszCurDir参数允许父进程设置子进程的当前驱动器和目录。如果本参数为NULL,则新进程的工作目录将与生成新进程的应用程序的目录相同;若不为空,则必须指向包含需要的工作驱动器和工作目录的以0结尾的字符串。课题中该参数选择为NULL就可以了。
PsiStartInfo参数用于指向一个STARTUPINFO结构。当Windows创建新进程时,它将使用该结构的有关成员。大多数应用程序将要求生成的应用程序仅仅使用默认值。至少应该将该结构中的所有成员初始化为零,然后将cb(cb为STARTUPINFO结构成员)设置为该结构的大小。STARTUPINFO结构的其他具体成员参见VC++6.0帮助系统MSDN。
PpiProcInfo参数用于指向你必须指定的PROCESS_INFORMATION结构。CreateProcess在返回之前要对该结构的成员进行初始化。该结构的形式如下面所示:
Typedef struct _PROCESS_INFORMATION{
HANDLE hProcess;
HANDLE hThread;
DWORD dwProcessId;
DWORD dwThreadId;
}PROCESS_INFORMATION;
CreateProcess在返回之前打开进程对象和线程对象,并将每个对象的与进程相关的句柄放入PROCESS_INFORMATION结构的hProcess和hThread成员中。
综上所述,课题创建进程的关键程序如下:
STARTUPINFO StartupInfo;
PROCESS_INFORMATION ProcessInfo;
memset(&StartupInfo,0,sizeof(STARTUPINFO)); //分配内存
StartupInfo.cb=sizeof(STARTUPINFO); // 初始化
StartupInfo.dwFlags=STARTF_USESHOWWINDOW;
StartupInfo.wShowWindow=SW_SHOWMAXIMIZED;
if(!::CreateProcess(NULL,d:\\ProgramFiles\\Ansys
Inc\\ANSYS61\\bin\\intel\\AnsysB”,NULL,NULL,FALS E,0,NULL,NULL,&StartupInfo,&ProcessInfo))
{
AfxMessageBox("error!");
GetLastError();
} // 创建进程
上边简单的分析了win32 api中调用程序的启动函数, |
|