- 匿名管道没有名称,所以只能在父进程中调用CreateProcess函数创建子进程时,将管道的读、写句柄传递给子进程。
- 匿名管道只能实现本地机器上两个进程间的通信,而不能实现跨网络的通信。
1. 过程:
- a. createpipe得到hWrite和hRead两句柄
- b. 将hWrite和hRead通过createprocess传递给子进程
- c. 子进程通过GetStdHandle获取 hWrite和hRead
- d. 你读我写
2. api详细说明
read:
char buf[100];
DWORD dwRead;
if(!ReadFile(hRead,buf,100,&dwRead,NULL))
write:
char buf[]="匿名管道测试程序";
DWORD dwWrite;
if(!WriteFile(hWrite,buf,strlen(buf)+1,&dwWrite,NULL))
BOOL CreatePipe(
PHANDLE hReadPipe,
PHANDLE hWritePipe,
LPSECURITY_ATTRIBUTES lpPipeAttributes,
DWORD nSize
);
typedef struct _SECURITY_ATTRIBUTES {
DWORD nLength;
LPVOID lpSecurityDescriptor;
BOOL bInheritHandle;
} SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;
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
);
-
lpApplicationName
指定某路径下exe,若路径包括空格,则语义改变。 -
lpCommandLine
参数,也可将lpApplicationName设为Null,此lpCommandLine指定name,
eg.
“c:\program fileslsub dir\program name”=>
c:lprogram.exe fileslsub dirlprogram name
…
Windows将按照如下顺序寻找这个可执行文件:
1.当前应用程序的目录。
2.父进程的目录。
3. Windows 95:Windows系统目录,可以使用 GetSystemDirectory函数获得。
Windows NT:32位Windows系统目录。可以使用GetSystemDirectory函数获得,目录名是SYSTEM32。
4. 在Windows NT中:16位Windows系统目录。不可以使用Win32函数获得这个目录,但是它会被搜索,目录名是SYSTEM。
5.Windows目录。可以使用 GetWindowsDirectory函数获得这个目录。
6.列在PATH环境变量中的目录。
-
bInheritHandles
子进程是否从父进程继承句柄 -
dwCreationFlags
值:DEBUG_PROCESS
如果这个标志被设置,调用进程将被当作一个调试程序,并且新进程会被当作被调试的进程。系统把被调试程序发生的所有调试事件通知给调试器。如果你使用这个标志创建进程,只有调用进程(调用CreateProcess函数的进程)可以调用WaitForDebugEvent函数。
值:DEBUG_ONLY_THIS_PROCESS
含义:如果此标志没有被设置且调用进程正在被调试,新进程将成为调试调用进程的调试器的另一个调试对象。如果调用进程没有被调试,有关调试的行为就不会产生。
值:DETACHED_PROCESS
含义:对于控制台进程,新进程没有访问父进程控制台的权限。新进程可以通过AllocConsole函数自己创建一个新的控制台。这个标志不可以与CREATE_NEW_CONSOLE标志一起使用。
还可表示进程优先级
- lpStartupInfo
typedef struct _STARTUPINFO
{
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;
用于决定新进程的主窗体如何显示的STARTUPINFO结构体
- LPPROCESS_INFORMATION lpProcessInformation
子进程的句柄数据
typedef struct _PROCESS_INFORMATION {
HANDLE hProcess;
HANDLE hThread;
DWORD dwProcessId;
DWORD dwThreadId;
} PROCESS_INFORMATION;
dwProcessId,dwThreadId需要程序员手动CloseHandle
在创建一个新进程时,系统会为该进程建立一个进程内核对象和一个线程内核对象,而内核对象都有一个使用计数,系统会为这两个对象赋予初始的使用计数:1,当CreateProcess 函数在其内部打开这些对象时,每个对象的使用计数就变为2
【引用】
- 代码 https://github.com/thefistlei/os/tree/main/processCommunication/anonymousPipe
- VC++ 深入详解 孙鑫
- CreatePipe function (namedpipeapi.h)https://docs.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-createpipe