Windows MPs Queue Technology

Source: Internet
Author: User
Windows MPs Queue Technology

Friday, 3. March 2006, 05:58:54

MPs queue

Http://tb.blog.csdn.net/TrackBack.aspx? Postid = 613368

No
Know if you have used this?ProgramThey do not have the decompression function, but call the DOS program PKZIP to decompress the zip package. However, when the program is running, there is no dos Console window
Now, all the information that should have been displayed in DOS is displayed in a text box of the installer. This design is both beautiful and can prevent a few users who are eye-catching from closing your DOS window in advance.
Now let's discuss how to use the anonymous pipeline technology to implement this function.

Pipeline technology has been around for a long time. I believe many people are most familiar with the pipeline technology in the DOS command. When we type a file, we can input it if we want it to be paged.

C: \> type autoexec. Bat | more

Here "|" is the pipeline operator. It uses the type output information as the Reading end and the more input end as the pipeline established by the writing end.

In Windows, a large number of pipelines are also anonymous pipelines, which are created using the createpipe API function.

Bool createpipe (
Phandle hreadpipe, // pointer to the read-side handle
Phandle hwritepipe, // pointer to the write handle
Lpsecurity_attributes lppipeattributes, // pointer to the Security Attribute Structure
DWORD nsize // MPs queue capacity
);

In the preceding parameters, note that hreadpipe, hwritepipe, is the pointer to the handle, rather than the handle (I used it wrong for the first time ). Nsize is generally set to 0 so that the system determines the pipeline capacity. Now let's look at the security attribute structure, security_attributes.

Typedef struct _ security_attributes {// SA
DWORD nlength;
Lpvoid lpsecuritydescriptor;
Bool binherithandle;
} Security_attributes;
Nlength
Is the size of the struct, which is naturally obtained using sizeof. Lpsecuritydescriptor is a security descriptor (a C-style string ).
Binherithandle indicates whether the security description object can be inherited by the newly created process. Don't worry about their specific meaning. You will naturally know it when using it.

Okay. Now let's create a pipeline.

Handle hreadpipe, hwritepipe;
Security_attributes SA;

SA. nlength = sizeof (security_attributes );
SA. lpsecuritydescriptor = NULL; file: // use the default security descriptor of the system.
SA. binherithandle = true; file: // it must be true. Otherwise, the handle cannot be inherited.
Creeatepipe (& hreadpipe, & hwritepipe, & SA, 0 );
OK,
Our pipeline has been built. Of course, this is not the ultimate goal. Our goal is to redirect the output of a program on DOS to the Edit Control of a Windows program. So we need to start
Use a DOS program, and the DOS Console window does not appear (otherwise, it will not be exposed ). We use CreateProcess to create a DOS program process.

bool CreateProcess (
lpctstr lpapplicationname, // C-style string: Application name
lptstr lpcommandline, // C-style string: command
lpsecurity_attributes lpprocessattributes, // process Security Attribute
lpsecurity_attributes lpthreadattributes, // thread Security Attribute
bool binherithandles, // whether to inherit the flag of the handle
DWORD dwcreationflags, // create the flag
lpvoid lpenvironment, // C-style string: Environment setting
lpctstr lpcurrentdirectory, // C-style string: Execution Row directory
lpstartupinfo, // start Information
lpprocess_information lpprocessinformation // Process Information
);
first
do not go, the parameter is a little more, but most do not need to fill in or leave a null parameter. Lpapplication can be used at any time. The lpcommandline command must be carefully written. Let's see how to set lpprocessattributes and lpthreadattributes. Ah? This is the
it was just now. Yes, but it is simpler than just now. Since we only create a process and whether it can be inherited or not, the two values are all null. Binherithandles must also be set to true
because we want to allow new processes to output information to the processes that call it, the new process must inherit the handle of the called process. We have no requirement on the newly created process. The
using dwcreationflags is null. According to your requirements, lpenvironment and lpcurrentdirectory are just a bit.
generally, they are also null. The next lpstartupinfo is the key. Let's take a closer look.

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;
Inverted! If there are so many parameters, one write will surely be exhausted. That's right, Ms has long thought it would be exhausting. Therefore, it provides the life-saving API function getstartupinfo.

Void getstartupinfo (
Lpstartupinfo
);
This function is used to obtain the startupinfo of the current process. The newly created process is basically the same as the startupinfo of the current process. just borrow it. Then you can make a small modification.

Me
There are several changes: CB, dwflags, hstdoutput, hstderror, and wshowwindow. First, let's talk about CB.
The size of startupinfo is sizeof. Besides, wshowwindow sets the actual window state when the new process is created. This attribute is of course set
Sw_hide: Do we need to hide the newly created DoS process. Haha, see hstdoutput and hstderror, standard output and error output handle. Key Points
Now, as long as we set these two handles to hwrite, once the process has a standard output, it will be written into the anonymous pipeline we just created, and we will use the pipeline's hreadpipe handle
If the content is read out and written into the edit control, will it achieve our goal. It's really easy to say. After these key parameters are completed, do not forget dwflags. He is used to develop
The parameter in startupinfo is valid. Now that we use hstdoutput, hstderror, and wshowwindow, dwflags is
Startf_useshowwindow | startf_usestdhandles.

Now, return to the last parameter lpprocessinformation (tired!) of CreateProcess !). You don't need to fill in this parameter. It is the information returned by CreateProcess. You just need to give him the address of the process_information structure case.

Large
With high performance, one end of the pipeline is connected to the standard output end of the new process, and one end can be read by itself using the API function readfile. Wait, no. Our pipeline is still faulty. We set
Hwrite gives hstdoutput and hstderror, a pipeline write end will be opened in the new process when the new process starts, and we use
Createpipe creates an MPS queue, and hwrite is also available in the current process. Well, there is a malformed pipe with two writing ends and one reading end. This
There must be a problem with the pipelines. Since the current process does not use the write end, we must disable the write end of the current process. In this way, our pipeline is truly successful. Let's take a look at the source program written by VC ++.
Order:

/*
* Use the MPs queue technology to change the Dir /? To a cedit control of the MFC application.
* VC ++ 6.0 + WINXP
*
* Detrox, 2003.
*/

Void cpipedlg: onbutton1 ()
{
Security_attributes SA;
Handle hread, hwrite;

SA. nlength = sizeof (security_attributes );
SA. lpsecuritydescriptor = NULL;
SA. binherithandle = true;
If (! Createpipe (& hread, & hwrite, & SA, 0 )){
MessageBox ("error on createpipe ()");
Return;
}
Startupinfo Si;
Process_information PI;
Si. cb = sizeof (startupinfo );
Getstartupinfo (& Si );
Si. hstderror = hwrite;
Si. hstdoutput = hwrite;
Si. wshowwindow = sw_hide;
Si. dwflags = startf_useshowwindow | startf_usestdhandles;
If (! CreateProcess (null, "C: \ WINDOWS \ system32 \ cmd.exe/c dir /? "
, Null, null, true, null, & Si, & PI )){
MessageBox ("error on CreateProcess ()");
Return;
}
Closehandle (hwrite );

char buffer [4096] = {0};
DWORD bytesread;
while (true) {
If (readfile (hread, buffer, 4095, & bytesread, null) = NULL)
break;
m_edit1 + = buffer;
updatedata (false);
sleep (200 );
}< BR >}

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.