利用匿名管道实现远程调用CMD

源贴地址:http://www.cnblogs.com/thankgoodness/articles/1762596.html

在一个进程里用双管道来回显,代码如下:

#include "windows.h"
#include "stdio.h"
unsigned long WINAPI readFuc(void *p);

HANDLE hReadPipeCmd = NULL;
HANDLE hWritePipeCmd = NULL;
HANDLE hReadPipeShell = NULL;
HANDLE hWritePipeShell = NULL;//shell

int main(int argc, char* argv[])
{
    SECURITY_ATTRIBUTES sa = {0}; 
    STARTUPINFO         si = {0};
    PROCESS_INFORMATION pi = {0};

    sa.nLength = sizeof(sa);
    sa.lpSecurityDescriptor = NULL; 
    sa.bInheritHandle = TRUE;
    //创建管道
    CreatePipe(&hReadPipeCmd,&hWritePipeCmd,&sa,0);
    CreatePipe(&hReadPipeShell,&hWritePipeShell,&sa,0);

    GetStartupInfo(&si);
    si.cb = sizeof(STARTUPINFO);
    si.wShowWindow = SW_HIDE;
    si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
    si.hStdInput = hReadPipeShell;
    si.hStdOutput = si.hStdError = hWritePipeCmd; 

    char strShellPath[256]="\x00";
    GetSystemDirectory(strShellPath, 256);
    strcat(strShellPath,"\\cmd.exe");

    if (!CreateProcess(strShellPath,NULL, NULL, NULL,TRUE,NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi)) 
    {
        //printf("CreateProcess Error!\n");
        CloseHandle(hWritePipeCmd);
        CloseHandle(hReadPipeShell);
    }
    CreateThread(0,0,readFuc,0,0,0);

    char writeBuf[256]="\x00";
    DWORD dwByteWritten;
    char readBuf[4096]="\x00";

    while(1)
    {
        scanf("%s",writeBuf);
        strcat(writeBuf,"\r\n");            //这个是关键,必须加上回车换行!否则不会回显!
        WriteFile(hWritePipeShell,writeBuf,strlen(writeBuf),&dwByteWritten,0);
        printf("写入字节数:%d\n",dwByteWritten);
        memset(writeBuf,0,256);
        //   ReadFile(hMainRead,readBuf,4096,&dwByteRead, NULL);
        //   printf("%s",readBuf);
        Sleep(1000);
    }
}


unsigned long WINAPI readFuc(void *p)
{
    unsigned long   BytesRead = 0;
    char ReadBuff[4096];
    DWORD TotalBytesAvail;
    int i=0;

    while (PeekNamedPipe(hReadPipeCmd,ReadBuff, sizeof(ReadBuff), &BytesRead, &TotalBytesAvail, NULL)) 
    {
        if (TotalBytesAvail <= 0)
            Sleep(600);
        //printf("有数据到来!\n");
        memset(ReadBuff, 0, sizeof(ReadBuff));
        if(BytesRead==TotalBytesAvail)
        {
            ReadFile(hReadPipeCmd, ReadBuff, TotalBytesAvail+100, &BytesRead, NULL);
            // 发送数据
            printf("%s",ReadBuff);//很关键
            memset(ReadBuff, 0, sizeof(ReadBuff)); 
            //   FlushFileBuffers(hReadPipeCmd); 
            //   CloseHandle(hReadPipeCmd);
        }
    }
    printf("thread over!");
    return 0;
}

2015-11-23
重新改写了下代码

#include "windows.h"
#include "stdio.h"

HANDLE hReadPipeCmd = NULL;
HANDLE hWritePipeCmd = NULL;
HANDLE hReadPipeShell = NULL;
HANDLE hWritePipeShell = NULL;//shell
HANDLE hProcessHandle;        //进程句柄

char readBuff[4096]="\x00";
char writeBuff[256]="\x00";
//BOOL initPipeSuccess = FALSE;

void initPipe();
void shell();

int main(int argc, char* argv[])
{   
    while(1)
    {
        scanf("%s",writeBuff);
        strcat(writeBuff,"\r\n");//这个是关键,必须加上回车换行!否则不会回显!
        shell();
        printf("%s",readBuff);//很关键
        memset(readBuff, 0, sizeof(readBuff));
        getchar();
    }
}

void shell()
{
    //if(initPipeSuccess == FALSE)
        initPipe();

    DWORD dwByteWritten;

    WriteFile(hWritePipeShell,writeBuff,strlen(writeBuff),&dwByteWritten,0);//写管道
    printf("写入字节数:%d\n",dwByteWritten);
    memset(writeBuff,0,256);

    //Sleep(1000);

    unsigned long   BytesRead = 0;
    DWORD TotalBytesAvail;

    //检查管道中是否有数据
    while (PeekNamedPipe(hReadPipeCmd,readBuff, sizeof(readBuff), &BytesRead, &TotalBytesAvail, NULL)) 
    {
        if (TotalBytesAvail <= 0)
            Sleep(600);
        else
        {
            //printf("有数据到来!\n");
            memset(readBuff, 0, sizeof(readBuff));
            if(BytesRead==TotalBytesAvail)
            {
                ReadFile(hReadPipeCmd, readBuff, TotalBytesAvail+100, &BytesRead, NULL);
                break;
            }
        }
    }
}
//创建双管道和创建cmd进程
void initPipe()
{
    SECURITY_ATTRIBUTES sa = {0}; 
    STARTUPINFO         si = {0};
    PROCESS_INFORMATION pi = {0};

    sa.nLength = sizeof(sa);
    sa.lpSecurityDescriptor = NULL; 
    sa.bInheritHandle = TRUE;
    //创建管道
    CreatePipe(&hReadPipeCmd,&hWritePipeCmd,&sa,0);
    CreatePipe(&hReadPipeShell,&hWritePipeShell,&sa,0);

    GetStartupInfo(&si);
    si.cb = sizeof(STARTUPINFO);
    si.wShowWindow = SW_HIDE;
    si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
    si.hStdInput = hReadPipeShell;
    si.hStdOutput = si.hStdError = hWritePipeCmd; 
    //找到cmd的绝对路径
    char strShellPath[256]="\x00";
    GetSystemDirectory(strShellPath, 256);
    strcat(strShellPath,"\\cmd.exe");
    //创建cmd进程
    if (!CreateProcess(strShellPath,NULL, NULL, NULL,TRUE,NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi)) 
    {
        //printf("CreateProcess Error!\n");
        CloseHandle(hWritePipeCmd);
        CloseHandle(hReadPipeShell);
        //initPipeSuccess = FALSE;
        return;
    }
    hProcessHandle = pi.hProcess;
    //initPipeSuccess = TRUE;
}

你可能感兴趣的:(c语言)