VC++启动使用外部软件详解

来源:互联网 发布:大数据考试题目及答案 编辑:程序博客网 时间:2024/06/05 04:21


1调用API: int system(const char *command );

此函数用于调用c++调用shell或者dos命令之用,system(char * )会调用fork()产生子进程,由子进程来调用/bin/sh-c string来执行参数string字符串所代表的命令,此命令执行完后随即返回原调用的进程。在调用system()期间SIGCHLD信号会被暂时搁置,SIGINTSIGQUIT信号则会被忽略。

关联着fork的子进程

你可以传入一命令,启动某个程序。如"ping www.baidu.com", "E:\\QQPlayer\\QQPlayer.exe"等

不过这里有几点要值得注意: 

(1)、它不会立即返回,直到你启动的程序执行完成。

(2)、这个就算是windows程序也会产生 出现console问题

(3)、它的返回值代表是否执行成功以及程序的退出码。

返回结果:system函数返回结果并非command命令的结果返回,而是返回shell的终止状态,而非执行命令字符串的终止状态, 根据具体情况,直接返回结果如下:

1,如果命令错误,这里XXX命令根本不存在。

返回结果为:1 。

2,如果命令正确,但是执行结果错误的话,路径下不存在XXXX文件,

在控制台下 会报” 不是内部或外部命令,也不是可运行的程序或批处理文件。”

3,如果命令正确,执行结果正确,如:cout << system("E:\\QQPlayer\\QQPlayer.exe")<< endl;返回结果为:0;

4,如果system函数在调用fork函数时失败,则返回 -1;

注:‍system函数的返回值要分成两部分来说:

 

1,在程序中,用exit来设置进程的退出值时,虽然该函数的参数类型为int型,但再父进程中只能取到其值的低8位.所以用exit返回值时,高于255的值是没有意义的.

 

2,对于system函数,返回值是由两部分组成的,低8位值表示所执行的脚本在执行过程中所接收到的信号值,其余的位表示的脚本exit退出时所设置的值, 即脚本内exit退出是的值的低8位,在system返回值的低9-16位.

经常性的,我们还是需要得到system函数执行字符串命令后的返回结果,那么请使用下面的几个宏:

WIFEXITED(status)如果子进程正常结束则为非0值。

WEXITSTATUS(status)取得子进程exit()返回的结束代码,一般会先用WIFEXITED来判断是否正常结束才能使用此宏。

WIFSIGNALED(status)如果子进程是因为信号而结束则此宏值为真

WTERMSIG(status)取得子进程因信号而中止的信号代码,一般会先用WIFSIGNALED 来判断后才使用此宏。

WIFSTOPPED(status)如果子进程处于暂停执行情况则此宏值为真。一般只有使用WUNTRACED 时才会有此情况。

WSTOPSIG(status)取得引发子进程暂停的信号代码,一般会先用WIFSTOPPED 来判断后才使用此宏。

从上面的描述中我们可以看到,使用‍WIFEXITED(status)来判断进程是否正常结束,之后使用‍WEXITSTATUS(status)来获得字符串命令返回的结果值,注意:‍若WIFEXITED返回0则用WEXITSTATUS来判断返回值没有意义。

         system("D://Text.txt");

         system("ping www.baidu.com");

         system("Pause");

         system("ipconfig");

         system(" shutdown -s -t3600");

         system("E:\\QQPlayer\\QQPlayer.exe");

         system("D:\\关机.bat");

2、调用API:

 

UINT WINAPI WinExec(

  __in  LPCSTR lpCmdLine,

  __in  UINT uCmdShow  // 参考ShowWindow的参数,就是 窗口的nCmdShow详情查看MSDN

);

Return Value:
If the function succeeds, the return value is greater than 31.

If the functionfails, the return value is one of the following error values.

Return code/value

Description

0

The system is out of memory or resources.

ERROR_BAD_FORMAT

The .exe file is invalid.

ERROR_FILE_NOT_FOUND

The specified file was not found.

ERROR_PATH_NOT_FOUND

The specified path was not found.

Security Remarks

The executablename is treated as the first white space-delimited string inlpCmdLine.If the executable or path name has a space in it, there is a risk that adifferent executable could be run because of the way the function parsesspaces. The following example is dangerous because the function will attempt torun "Program.exe", if it exists, instead of "MyApp.exe".

WinExec("C:\\Program Files\\MyApp", ...)

If a malicioususer were to create an application called "Program.exe" on a system,any programthat incorrectly calls WinExec using the Program Files directorywill run this application instead of the intended application.

To avoid thisproblem, use CreateProcess rather thanWinExec. However, if youmust use WinExec for legacy reasons, make sure the application name isenclosed in quotation marks as shown in the example below.

WinExec("\"C:\\Program Files\\MyApp.exe\" -L -S", ...)

3. 调用:ShellExecute

HINSTANCE ShellExecute(      
    HWND hwnd,

    LPCTSTR lpOperation,

    LPCTSTR lpFile,

    LPCTSTR lpParameters,

    LPCTSTR lpDirectory,

    INT nShowCmd

);

hwnd

[in] A handleto the owner window used for displaying a user interface (UI) or errormessages. This value can be NULL if the operation is not associated with awindow.

lpOperation   // 方式

[in] Apointer to a null-terminated string, referred to in this case as averb,that specifies the action to be performed. The set of available verbs dependson the particular file or folder. Generally, the actions available from anobject's shortcut menu are available verbs. The following verbs are commonlyused.

edit

Launches an editorand opens the document for editing. If lpFile is not a document file,the function will fail.

explore

Explores a folderspecified by lpFile.

find

Initiates a searchbeginning in the directory specified by lpDirectory.

open

Opens the itemspecified by the lpFile parameter. The item can be a file or folder.

print

Prints the filespecified by lpFile. If lpFile is not a document file, thefunction fails.

NULL

In systems prior to Microsoft Windows 2000, the defaultverb is used if it is valid and available in the registry. If not, the"open" verb is used.

In Windows 2000 and later, the default verb is used ifavailable. If not, the "open" verb is used. If neither verb isavailable, the system uses the first verb listed in the registry.

lpFile

[in] Apointer to a null-terminated string that specifies the file or object on whichto execute the specified verb. To specify a Shell namespace object, pass thefully qualified parse name. Note that not all verbs are supported on allobjects. For example, not all document types support the "print"verb. If a relative path is used for thelpDirectory parameter do notuse a relative path for lpFile.

lpParameters

[in] If lpFilespecifies an executable file, this parameter is a pointer to a null-terminatedstring that specifies the parameters to be passed to the application. Theformat of this string is determined by the verb that is to be invoked. If lpFilespecifies a document file, lpParameters should be NULL.

lpDirectory

[in] Apointer to a null-terminated string that specifies the default (working) directoryfor the action. If this value is NULL, the current working directory is used.If a relative path is provided atlpFile, do not use a relative path forlpDirectory.

nShowCmd

[in] Theflags that specify how an application is to be displayed when it is opened. IflpFilespecifies a document file, the flag is simply passed to the associatedapplication. It is up to the application to decide how to handle it.

它也有WinExec同样的缺点。

  它虽然传回一个HINSTANCE,但他并不是真正的句柄,我们仅能拿它来做一些错误值检查。

解决1和2 的共同问题 无法调用 默认的程序来使用 打开文档 ,或者一些ping 的命令

Return Value  参考msdn

 

使用

 

::ShellExecute(NULL, NULL, "ping", "www.baidu.com", NULL, SW_SHOWNORMAL);::ShellExecute(NULL, "open", "E:\\QQPlayer\\QQPlayer.exe", NULL, NULL, SW_SHOWMINIMIZED);::ShellExecute(NULL, "explore", "c:",NULL, NULL, SW_SHOWNORMAL);::ShellExecute(NULL, "open", "c:", NULL, NULL, SW_SHOWNORMAL);::ShellExecute(NULL, "open", "www.baidu.com", NULL, NULL, SW_SHOWNORMAL);

 4.CreateProcess

BOOL WINAPI CreateProcess(
  __in_opt     LPCTSTR lpApplicationName,
  __inout_opt  LPTSTR lpCommandLine,
  __in_opt     LPSECURITY_ATTRIBUTES lpProcessAttributes,
  __in_opt     LPSECURITY_ATTRIBUTES lpThreadAttributes,
  __in         BOOL bInheritHandles,
  __in         DWORD dwCreationFlags,
  __in_opt     LPVOID lpEnvironment,
  __in_opt     LPCTSTR lpCurrentDirectory,
  __in         LPSTARTUPINFO lpStartupInfo,
  __out        LPPROCESS_INFORMATION lpProcessInformation
);

 

 

STARTUPINFOStartInfo;

  PROCESS_INFORMATIONpinfo;

  //对程序的启动信息不作任何设定,全部清0

  memset(&StartInfo,0,sizeof(STARTUPINFO));

  StartInfo.cb =sizeof(STARTUPINFO);//设定结构的大小

  BOOL ret=CreateProcess(

   NULL, //启动程序路径名

   "notepad.exe",//参数(当exeName为NULL时,可将命令放入参数前)

   NULL,  //使用默认进程安全属性

   NULL,  //使用默认线程安全属性

   FALSE,     //句柄不继承

   NORMAL_PRIORITY_CLASS,//使用正常优先级

   NULL,  //使用父进程的环境变量

   NULL,  //指定工作目录

   &StartInfo, //子进程主窗口如何显示

   &pinfo); //用于存放新进程的返回信息

  这样在创建成功这后我们就可以从pinfo中找到它的:进程句柄,线程句柄,进程ID,线程ID

  在附件源码中演示了进程序的启动,停止。(实际上我们可以通过很多方式如内存共享、父进程窗体句体传入仍后从消息中获得子进程窗体句柄等,来实现更多的控制。)

其他注意事项:

 

1、定义头文件

 

在头文件stdafx.h中必须定义以下两个头文件:

 

#include<shlobj.h> // 可替换为 windows.h

#include<shellapi.h>

如果定义了头文件 #include<windows.h>的话就不必定义 #include <shlobj.h>了,"windows.h"不光是包含了"shellapi.h",它还定义了许多数据类型,如果没有这些数据类型,shellapi.h本身会出错。

2、定义路径

C++中所表示的路径要用" // "而不是平常所用的" / "

 


// VC++四种启动其它程序的方法.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <Windows.h>#include <iostream>using namespace std;int _tmain(int argc, _TCHAR* argv[]){/*system("D://Text.txt");system("ping www.baidu.com");system("Pause");system("ipconfig");system(" shutdown -s -t 3600");system("E:\\QQPlayer\\QQPlayer.exe");system("D:\\关机.bat");*//*WinExec("ping www.baidu.com", SW_SHOWMAXIMIZED);WinExec("ipconfig", SW_SHOWMAXIMIZED);WinExec("Pause", SW_SHOW); // 暂停 命令没法使用   //system("Pause");WinExec("E:\\QQPlayer\\QQPlayer.exe", SW_SHOWMAXIMIZED);WinExec("D:\\关机.bat", SW_SHOWMAXIMIZED);WinExec("\"E:\\QQPlayer\\QQPlayer.exe\" -L -S", SW_SHOWMAXIMIZED);*/::ShellExecute(NULL, NULL, "ping", "www.baidu.com", NULL, SW_SHOWNORMAL);::ShellExecute(NULL, "open", "E:\\QQPlayer\\QQPlayer.exe", NULL, NULL, SW_SHOWMINIMIZED);::ShellExecute(NULL, "explore", "c:",NULL, NULL, SW_SHOWNORMAL);::ShellExecute(NULL, "open", "c:", NULL, NULL, SW_SHOWNORMAL);::ShellExecute(NULL, "open", "www.baidu.com", NULL, NULL, SW_SHOWNORMAL);printf("Go down!\n"); //main() go down.return 0;}


0 0