Windows程序设计(3):程序启动器(CreateProcess)

来源:互联网 发布:数据库人员报表查询 编辑:程序博客网 时间:2024/06/06 02:49

最近要写一个程序去启动另一个程序。

python直接调用os.system("xxx")是可以,但是感觉很low。似乎根本得不到被启动的程序的任何信息。

查了查C语言怎么启动,然后看看python是不是有相似的用法。

注意,这个程序是一个控制台程序!不是MFC程序。

#include <windows.h>#include <stdio.h>int main (int argc,char* argv[]){    char szCommandLine[]="C:/Program Files (x86)/Microsoft Office/Office15/EXCEL.EXE f:/test.xlsx"; // 要开启的程序,以及后面的附加参数    STARTUPINFO si={sizeof(si)};    PROCESS_INFORMATION pi;    si.dwY = 0;//位置    si.dwX = 0;    si.dwXSize = 200;//大小    si.dwYSize = 200;    si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USEPOSITION | STARTF_USESIZE; // 指定启动状态    si.wShowWindow=TRUE; //为真,显示进程的主窗口    BOOL bRet=::CreateProcess(        NULL,//不在此指定可执行文件的文件名        szCommandLine, //命令行参数        NULL,//默认进程的安全性        NULL,//默认线程的安全性        FALSE,//指定当前进程内的句柄不可以被子进程继承        CREATE_NEW_CONSOLE,//为新进程创建一个新的控制台窗口        NULL,//使用本进程的环境变量        NULL,//使用本进程的驱动器和目录        &si,        &pi);    if(bRet)    {        ::CloseHandle(pi.hThread);        ::CloseHandle(pi.hProcess);        printf("新的进程的进程ID号:%d\n",pi.dwProcessId); // 这就是被启动的程序的PID        printf("新进程的主线程ID号:%d\n",pi.dwThreadId);    }    return 0;}



MSDN文档

CreateProcess

The CreateProcess function creates a new process and its primary thread. The new process executes the specified executable file.

BOOL CreateProcess(  LPCTSTR lpApplicationName,                         // pointer to name of executable module  LPTSTR lpCommandLine,  // pointer to command line string。 比如要启动一个exe的话,可以就在这里写那个exe的路径。  LPSECURITY_ATTRIBUTES lpProcessAttributes,  // process security attributes  LPSECURITY_ATTRIBUTES lpThreadAttributes,   // thread security attributes  BOOL bInheritHandles,  // handle inheritance flag  DWORD dwCreationFlags, // creation flags  LPVOID lpEnvironment,  // pointer to new environment block  LPCTSTR lpCurrentDirectory,   // pointer to current directory name  LPSTARTUPINFO lpStartupInfo,  // pointer to STARTUPINFO  LPPROCESS_INFORMATION lpProcessInformation  // pointer to PROCESS_INFORMATION); 

Parameters

lpApplicationName
Pointer to a null-terminated string that specifies the module to execute.

The string can specify the full path and filename of the module to execute or it can specify a partial name. In the case of a partial name, the function uses the current drive and current directory to complete the specification.

The lpApplicationName parameter can be NULL. In that case, the module name must be the first white space-delimited token in thelpCommandLine string. If you are using a long filename that contains a space, use quoted strings to indicate where the filename ends and the arguments begin, otherwise, the filename is ambiguous. For example, consider the string "c:\program files\sub dir\program name". This string can be interpreted in a number of ways. The system tries the possibilities in the following order:

c:\program.exe files\sub dir\program name
c:\program files\sub.exe dir\program name
c:\program files\sub dir\program.exe name
c:\program files\sub dir\program name.exe

The specified module can be a Win32-based application. It can be some other type of module (for example, MS-DOS or OS/2) if the appropriate subsystem is available on the local computer.

Windows NT: If the executable module is a 16-bit application,lpApplicationName should be NULL, and the string pointed to bylpCommandLine should specify the executable module. A 16-bit application is one that executes as a VDM or WOW process.

lpCommandLine
Pointer to a null-terminated string that specifies the command line to execute. The system adds a null character to the command line, trimming the string if necessary, to indicate which file was actually used.

The lpCommandLine parameter can be NULL. In that case, the function uses the string pointed to bylpApplicationName as the command line.

If both lpApplicationName and lpCommandLine are non-NULL, *lpApplicationName specifies the module to execute, and *lpCommandLine specifies the command line. The new process can useGetCommandLine to retrieve the entire command line. C runtime processes can use theargc andargv arguments.

If lpApplicationName is NULL, the first white space-delimited token of the command line specifies the module name. If you are using a long filename that contains a space, use quoted strings to indicate where the filename ends and the arguments begin (see the explanation for the lpApplicationName parameter). If the filename does not contain an extension, .EXE is assumed. If the filename ends in a period (.) with no extension, or the filename contains a path, .EXE is not appended. If the filename does not contain a directory path, the system searches for the executable file in the following sequence:

  1. The directory from which the application loaded.
  2. The current directory for the parent process.
  3. Windows 95 and Windows 98: The Windows system directory. Use theGetSystemDirectory function to get the path of this directory.

    Windows NT: The 32-bit Windows system directory. Use the GetSystemDirectory function to get the path of this directory. The name of this directory is SYSTEM32.

  4. Windows NT: The 16-bit Windows system directory. There is no Win32 function that obtains the path of this directory, but it is searched. The name of this directory is SYSTEM.
  5. The Windows directory. Use theGetWindowsDirectory function to get the path of this directory.
  6. The directories that are listed in the PATH environment variable.

If the process to be created is an MS-DOS - based or 16-bit Windows-based application,lpCommandLine should be a full command line in which the first element is the application name. Because this also works well for Win32-based applications, it is the most robust way to setlpCommandLine.

lpProcessAttributes
Pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes. IflpProcessAttributes is NULL, the handle cannot be inherited.

Windows NT: The lpSecurityDescriptor member of the structure specifies a security descriptor for the new process. IflpProcessAttributes is NULL, the process gets a default security descriptor.

lpThreadAttributes
Pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes. IflpThreadAttributes is NULL, the handle cannot be inherited.

Windows NT: The lpSecurityDescriptor member of the structure specifies a security descriptor for the main thread. IflpThreadAttributes is NULL, the thread gets a default security descriptor.

bInheritHandles
Indicates whether the new process inherits handles from the calling process. If TRUE, each inheritable open handle in the calling process is inherited by the new process. Inherited handles have the same value and access privileges as the original handles.
dwCreationFlags
Specifies additional flags that control the priority class and the creation of the process. The following creation flags can be specified in any combination, except as noted:ValueMeaningCREATE_DEFAULT_ERROR_MODE The new process does not inherit the error mode of the calling process. Instead,CreateProcessgives the new process the current default error mode. An application sets the current default error mode by callingSetErrorMode.

This flag is particularly useful for multi-threaded shell applications that run with hard errors disabled.

The default behavior for CreateProcess is for the new process to inherit the error mode of the caller. Setting this flag changes that default behavior.

CREATE_NEW_CONSOLE The new process has a new console, instead of inheriting the parent's console. This flag cannot be used with the DETACHED_PROCESS flag.CREATE_NEW_PROCESS_GROUP The new process is the root process of a new process group. The process group includes all processes that are descendants of this root process. The process identifier of the new process group is the same as the process identifier, which is returned in the lpProcessInformation parameter. Process groups are used by the GenerateConsoleCtrlEvent function to enable sending a ctrl+c or ctrl+break signal to a group of console processes.CREATE_SEPARATE_WOW_VDM Windows NT: This flag is valid only when starting a 16-bit Windows-based application. If set, the new process is run in a private Virtual DOS Machine (VDM). By default, all 16-bit Windows-based applications are run as threads in a single, shared VDM. The advantage of running separately is that a crash only kills the single VDM; any other programs running in distinct VDMs continue to function normally. Also, 16-bit Windows-based applications that are run in separate VDMs have separate input queues. That means that if one application hangs momentarily, applications in separate VDMs continue to receive input. The disadvantage of running separately is that it takes significantly more memory to do so. You should use this flag only if the user requests that 16-bit applications should run in them own VDM.CREATE_SHARED_WOW_VDM Windows NT: The flag is valid only when starting a 16-bit Windows-based application. If the DefaultSeparateVDM switch in the Windows section of WIN.INI is TRUE, this flag causes theCreateProcess function to override the switch and run the new process in the shared Virtual DOS Machine.CREATE_SUSPENDED The primary thread of the new process is created in a suspended state, and does not run until theResumeThread function is called.CREATE_UNICODE_ENVIRONMENT If set, the environment block pointed to by lpEnvironment uses Unicode characters. If clear, the environment block uses ANSI characters.DEBUG_PROCESS If this flag is set, the calling process is treated as a debugger, and the new process is a process being debugged. The system notifies the debugger of all debug events that occur in the process being debugged.

If you create a process with this flag set, only the calling thread (the thread that calledCreateProcess) can call theWaitForDebugEvent function.

Windows 95 and Windows 98: This flag is not valid if the new process is a 16-bit application.

DEBUG_ONLY_THIS_PROCESS If not set and the calling process is being debugged, the new process becomes another process being debugged by the calling process's debugger. If the calling process is not a process being debugged, no debugging-related actions occur.DETACHED_PROCESS For console processes, the new process does not have access to the console of the parent process. The new process can call theAllocConsole function at a later time to create a new console. This flag cannot be used with the CREATE_NEW_CONSOLE flag.

The dwCreationFlags parameter also controls the new process's priority class, which is used in determining the scheduling priorities of the process's threads. If none of the following priority class flags is specified, the priority class defaults to NORMAL_PRIORITY_CLASS unless the priority class of the creating process isIDLE_PRIORITY_CLASS. In this case the default priority class of the child process isIDLE_PRIORITY_CLASS. One of the following flags can be specified:

PriorityMeaningHIGH_PRIORITY_CLASSIndicates a process that performs time-critical tasks that must be executed immediately for it to run correctly. The threads of a high-priority class process preempt the threads of normal-priority or idle-priority class processes. An example is the Task List, which must respond quickly when called by the user, regardless of the load on the system. Use extreme care when using the high-priority class, because a high-priority class CPU-bound application can use nearly all available cycles.IDLE_PRIORITY_CLASSIndicates a process whose threads run only when the system is idle and are preempted by the threads of any process running in a higher priority class. An example is a screen saver. The idle priority class is inherited by child processes.NORMAL_PRIORITY_CLASSIndicates a normal process with no special scheduling needs.REALTIME_PRIORITY_CLASSIndicates a process that has the highest possible priority. The threads of a real-time priority class process preempt the threads of all other processes, including operating system processes performing important tasks. For example, a real-time process that executes for more than a very brief interval can cause disk caches not to flush or cause the mouse to be unresponsive.


lpEnvironment
Pointer to an environment block for the new process. If this parameter is NULL, the new process uses the environment of the calling process.

An environment block consists of a null-terminated block of null-terminated strings. Each string is in the form:

name=value  

Because the equal sign is used as a separator, it must not be used in the name of an environment variable.

If an application provides an environment block, rather than passing NULL for this parameter, the current directory information of the system drives is not automatically propagated to the new process. For a discussion of this situation and how to handle it, see the following Remarks section.

An environment block can contain Unicode or ANSI characters. If the environment block pointed to bylpEnvironment contains Unicode characters, thedwCreationFlags field's CREATE_UNICODE_ENVIRONMENT flag will be set. If the block contains ANSI characters, that flag will be clear.

Note that an ANSI environment block is terminated by two zero bytes: one for the last string, one more to terminate the block. A Unicode environment block is terminated by four zero bytes: two for the last string, two more to terminate the block.

lpCurrentDirectory
Pointer to a null-terminated string that specifies the current drive and directory for the child process. The string must be a full path and filename that includes a drive letter. If this parameter is NULL, the new process is created with the same current drive and directory as the calling process. This option is provided primarily for shells that need to start an application and specify its initial drive and working directory.
lpStartupInfo
Pointer to a STARTUPINFOstructure that specifies how the main window for the new process should appear.
lpProcessInformation
Pointer to a PROCESS_INFORMATIONstructure that receives identification information about the new process.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, callGetLastError.


关于要这个程序启动时的一些参数,由倒数第二个参数指定,startUpInfo。

STARTUPINFO

The STARTUPINFO structure is used with the CreateProcess function to specify main window properties if a new window is created for the new process. For graphical user interface (GUI) processes, this information affects the first window created by theCreateWindow function and shown by theShowWindow function. For console processes, this information affects the console window if a new console is created for the process. A process can use theGetStartupInfo function to retrieve theSTARTUPINFO structure specified when the process was created.

typedef struct _STARTUPINFO { // si     DWORD   cb;     LPTSTR  lpReserved;     LPTSTR  lpDesktop;     LPTSTR  lpTitle;     DWORD   dwX;     DWORD   dwY;     DWORD   dwXSize;     DWORD   dwYSize;     DWORD   dwXCountChars;     DWORD   dwYCountChars;     DWORD   dwFillAttribute;     DWORD   dwFlags;     WORD    wShowWindow;     WORD    cbReserved2;     LPBYTE  lpReserved2;     HANDLE  hStdInput;     HANDLE  hStdOutput;     HANDLE  hStdError; } STARTUPINFO, *LPSTARTUPINFO;  

Members

cb
Specifies the size, in bytes, of the structure.
lpReserved
Reserved. Set this member to NULL before passing the structure to CreateProcess.
lpDesktop
Windows NT: Pointer to a zero-terminated string that specifies either the name of the desktop only or the name of both the desktop and window station for this process. A backslash in the string pointed to bylpDesktop indicates that the string includes both desktop and window station names. IflpDesktop is NULL, the new process inherits the desktop and window station of its parent process. IflpDesktop is an empty string, the process does not inherit the desktop and window station of its parent process; instead, the system determines if a new desktop and window station need to be created. If the impersonated user already has a desktop, the system will use the existing desktop.
lpTitle
For console processes, this is the title displayed in the title bar if a new console window is created. If NULL, the name of the executable file is used as the window title instead. This parameter must be NULL for GUI or console processes that do not create a new console window.
dwX, dwY
Ignored unless dwFlags specifies STARTF_USEPOSITION. Specifies the x and y offsets, in pixels, of the upper left corner of a window if a new window is created. The offsets are from the upper left corner of the screen. For GUI processes, the specified position is used the first time the new process calls CreateWindow to create an overlapped window if thex parameter ofCreateWindow is CW_USEDEFAULT.
dwXSize, dwYSize
Ignored unless dwFlags specifies STARTF_USESIZE. Specifies the width (dwXSize) and height (dwYSize), in pixels, of the window if a new window is created. For GUI processes, this is used only the first time the new process calls CreateWindow to create an overlapped window if thenWidth parameter ofCreateWindow is CW_USEDEFAULT.
dwXCountChars, dwYCountChars
Ignored unless dwFlags specifies STARTF_USECOUNTCHARS. For console processes, if a new console window is created,dwXCountCharsspecifies the screen buffer width in character columns, anddwYCountChars specifies the screen buffer height in character rows. These values are ignored in GUI processes.
dwFillAttribute
Ignored unless dwFlags specifies STARTF_USEFILLATTRIBUTE. Specifies the initial text and background colors if a new console window is created in a console application. These values are ignored in GUI applications. This value can be any combination of the following values: FOREGROUND_BLUE, FOREGROUND_GREEN, FOREGROUND_RED, FOREGROUND_INTENSITY, BACKGROUND_BLUE, BACKGROUND_GREEN, BACKGROUND_RED, and BACKGROUND_INTENSITY. For example, the following combination of values produces red text on a whilte background:
FOREGROUND_RED | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE 
dwFlags
This is a bit field that determines whether certain STARTUPINFO members are used when the process creates a window. Any combination of the following values can be specified:ValueMeaningSTARTF_USESHOWWINDOWIf this value is not specified, the wShowWindow member is ignored.STARTF_USEPOSITIONIf this value is not specified, the dwX and dwY members are ignored.STARTF_USESIZEIf this value is not specified, the dwXSize and dwYSize members are ignored.STARTF_USECOUNTCHARSIf this value is not specified, the dwXCountChars anddwYCountChars members are ignored.STARTF_USEFILLATTRIBUTEIf this value is not specified, the dwFillAttribute member is ignored.STARTF_FORCEONFEEDBACKIf this value is specified, the cursor is in feedback mode for two seconds afterCreateProcess is called. If during those two seconds the process makes the first GUI call, the system gives five more seconds to the process. If during those five seconds the process shows a window, the system gives five more seconds to the process to finish drawing the window. The system turns the feedback cursor off after the first call toGetMessage, regardless of whether the process is drawing. For more information on feedback, see the following Remarks section.STARTF_FORCEOFFFEEDBACKIf specified, the feedback cursor is forced off while the process is starting. The normal cursor is displayed. For more information on feedback, see the following Remarks section.STARTF_USESTDHANDLESIf this value is specified, sets the standard input of the process, standard output, and standard error handles to the handles specified in thehStdInput,hStdOutput, andhStdError members of theSTARTUPINFO structure. TheCreateProcess function'sfInheritHandles parameter must be set to TRUE for this to work properly. If this value is not specified, the hStdInput, hStdOutput, and hStdError members of the STARTUPINFO structure are ignored.
wShowWindow
Ignored unless dwFlags specifies STARTF_USESHOWWINDOW. The wshowWindow member can be any of the SW_ constants defined in WINUSER.H. For GUI processes,wShowWindow specifies the default value the first timeShowWindow is called. ThenCmdShow parameter ofShowWindow is ignored. In subsequent calls toShowWindow, thewShowWindow member is used if thenCmdShow parameter ofShowWindow is set to SW_SHOWDEFAULT.
cbReserved2
Reserved; must be zero.
lpReserved2
Reserved; must be NULL.
hStdInput
Ignored unless dwFlags specifies STARTF_USESTDHANDLES. Specifies a handle that will be used as the standard input handle to the process if STARTF_USESTDHANDLES is specified.
hStdOutput
Ignored unless dwFlags specifies STARTF_USESTDHANDLES. Specifies a handle that will be used as the standard output handle to the process if STARTF_USESTDHANDLES is specified.
hStdError
Ignored unless dwFlags specifies STARTF_USESTDHANDLES. Specifies a handle that will be used as the standard error handle to the process if STARTF_USESTDHANDLES is specified.

Remarks

If a GUI process is being started and neither STARTF_FORCEONFEEDBACK or STARTF_FORCEOFFFEEDBACK is specified, the process feedback cursor is used. A GUI process is one whose subsystem is specified as "windows." 

这个程序启动以后,它的PID等信息可以由最后一个参数processInfo得到。

PROCESS_INFORMATION

The PROCESS_INFORMATION structure is filled in by the CreateProcess function with information about a newly created process and its primary thread.

typedef struct _PROCESS_INFORMATION { // pi     HANDLE hProcess;  // 这个handle好像不是被启动那个窗口的handle    HANDLE hThread;     DWORD dwProcessId; // 这就是PID    DWORD dwThreadId; } PROCESS_INFORMATION;  

Members

hProcess
Returns a handle to the newly created process. The handle is used to specify the process in all functions that perform operations on the process object.
hThread
Returns a handle to the primary thread of the newly created process. The handle is used to specify the thread in all functions that perform operations on the thread object.
dwProcessId
Returns a global process identifier that can be used to identify a process. The value is valid from the time the process is created until the time the process is terminated.
dwThreadId
Returns a global thread identifiers that can be used to identify a thread. The value is valid from the time the thread is created until the time the thread is terminated. 
注意

但是有个比较坑的地方,我还不知道怎么解决。

假如我要启动cmd.exe,指定它的x、y坐标和cx、cy大小以后,这个黑窗口很听话,位置和大小都是对的。

但是如果启动一个GUI程序,比如计算器calc、记事本notepad,……位置和大小都失效了!暂时不知道怎么办!

阅读全文
0 0
原创粉丝点击