本帖最后由 xiaoyu8995 于 2014-08-06 22:25:53 编辑

解决方案 »

  1.   

    你讲的进程间通信吧
    1,共享内存
    2,消息队列
    3,套接字
    4,管道以下为消息队列的:
    1.消息结构模板
    strut msgbuf
    {
    long int  mtype;//消息类型
    char mtext[1];//消息内容
    }2.msgget创建消息
    #include <sys/msg.h>
    int msgget(key_t key, int flag);
    此函数返回key指定消息的标识符
    key 一般有ftok函数产生 ,该函数为key_t ftok(const char *pathname, int proj_id);
    该函数把从pathname导出的信息与id低8位组合成一个整数IPC键, 调用时pathname必须存在,若不存在ftok调用失败,返回-1,成功返回该整数IPC键值
    flag 为该消息队列的读写权限组合,可以与IPC_CREAT 或IPC_EXCL相与,其中创建对列时都要使用IPC_CREAT,其中IPC_CREAT|IPC_EXCL含义是若已有该队列则返回错误
    此函数成功时,返回非负队列标识符;失败时返回-1#include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/msg.h>
    main()
    {
        key_t lKey;
        int nMsgId;
        if((lKey = ftok("/etc/profile",1)) == -1)
        {
            perror("ftok");
            exit(1);
        }
    //带参数IPC_CREAT和IPC_EXCL,如果队列不存在则创建队列,已存在则返回EEXIST
        if((nMsgId = msgget(lKey,IPC_CREAT|IPC_EXCL|0666)) == -1)
        {
            if(errno != EEXIST)//创建失败且不是由于队列已存在
            {
                perror("msgget");
                exit(2);
            }
            if((nMsgId = msgget(lKey,0)) == -1)//已存在
            {
                perror("msgget");
                exit(3);
            }
        }
        printf("MsgID=%d\n",nMsgId);
        return 0;
    }
    3.msgsnd消息发送
    int msgsnd(int msqid, const void *ptr, size_t length, int flag);
    此函数发送消息到指定的消息对列
    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/msg.h>
    #include <string.h>
    typedef struct
    {
        long int nType;
        char szText[256];
    }MSG;
    main()
    {
        key_t lKey;
        int nMsgId;
        MSG msg;
        if((lKey = ftok("/etc/profile",1)) == -1)//生成键值
        {
            perror("ftok");
            exit(1);
        }
        if((nMsgId = msgget(lKey,IPC_CREAT|IPC_EXCL|0666)) == -1)//创建消息队列
        {
            if(errno != EEXIST)
            {
                perror("msgget");
                exit(2);
            }
            if((nMsgId = msgget(lKey,0)) == -1)
            {
                perror("msgget");
                exit(3);
            }
        }
        memset(&msg,0x00,sizeof(MSG));//清空队列
        msg.nType = 2;//指定消息类型为2
        memcpy(msg.szText,"123456",6);//指定消息内容
        if(msgsnd(nMsgId,(const void *)&msg,strlen(msg.szText),IPC_NOWAIT) < 0)//非阻塞发送消息
        {
            perror("msgsnd");
        }
        return 0;
    }队列中已经有一条消息,长度6字节4.msgrcv消息发送
    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/msg.h>
    #include <string.h>
    typedef struct
    {
        long int nType;
        char szText[256];
    }MSG;
    main()
    {
        key_t lKey;
        int n,nMsgId;
        MSG msg;
        if((lKey = ftok("/etc/profile",1)) == -1)
        {
            perror("ftok");
            exit(1);
        }
        if((nMsgId = msgget(lKey,0)) == -1)
        {
            perror("ftok");
            exit(2);
        }
        memset(&msg,0x00,sizeof(MSG));
        if((n = msgrcv(nMsgId,(void *)&msg,sizeof(msg.szText),2L,0)) < 0)//从队列接收消息,读出以后就不存在了
        {
            perror("msgrcv");
        }
        else
        {
            printf("msgrcv return length=[%d] text=[%s]\n",n,msg.szText);//输出
        }
        return 0;
    }
    输出:
    msgrcv return length=[6] text=[123456]5.msgctl控制消息
    int msgctl(int msqid, int cmd, struct msqid_ds *buf);
    消息队列控制函数
    其中msqid为消息队列描述符
    cmd有以下三种:
    IPC_RMID:删除msgid指定的消息队列,当前在该队列上的任何消息都被丢弃,对于该命令,buf参数可忽略
    IPC_SET:设置消息队列msgid_ds结构体的四个成员:msg_perm.uid,msg_perm_gid,msg_perm.mode和msg_qbytes。它们的值来自由buf指向的结构体中的相应成员。
    IPC_STAT:给调用者通过buf返回指定消息队列当前对应msgid_ds结构体
    函数执行成功返回0,失败返回-1#include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/msg.h>
    #include <string.h>
    typedef struct
    {
        long int nType;
        char szText[256];
    }MSG;
    main()
    {
        key_t lKey;
        int n,nMsgId;
        MSG msg;
        struct msqid_ds qds;
        if((lKey = ftok("/etc/profile",1)) == -1)
        {
            perror("ftok");
            exit(1);
        }
        if((nMsgId = msgget(lKey,0)) == -1)
        {
            perror("ftok");
            exit(2);
        }
        memset(&qds,0x00,sizeof(struct msqid_ds));
        if(msgctl(nMsgId,IPC_STAT,&qds) < 0)//获取消息队列属性,获取状态放pds中
        {
            perror("msgctl IPC_STAT");
            exit(3);
        }
        printf("msg_perm.mode=%d\n",qds.msg_perm.mode);
        qds.msg_perm.mode &= (~0222);//去除消息队列的写权限
        if(msgctl(nMsgId,IPC_SET,&qds) < 0)//设置消息队列权限
        {
            perror("msgctl IPC_SET");
            exit(4);
        }
        memset(&msg,0x00,sizeof(MSG));
        msg.nType = 2;
        memcpy(msg.szText,"12345",5);
        if(msgsnd(nMsgId,(void *)&msg,5,0) < 0)//发送消息
        {
            perror("msgsnd");
        }
        if(msgctl(nMsgId,IPC_RMID,NULL) < 0)//删除消息
        {
            perror("msgctl IPC_RMID");
            exit(5);
        }
        return 0;
    }
    说明: (~0222)取反后做与实际上就是去除其他用户的写权限,在C语言中,八进制常用用前缀表示
      

  2.   

    用CreateProcess来创建cmd进程,然后带参数应该就可以了,其实参数LPSTARTUPINFO lpStartupInfo可以设置进程不否隐藏
    简单的例子可能是这样CreateProcess(_T("cmd.exe"), _T("ping 192.168.10.25").......)
      

  3.   

      cmd可以一直在后台运行吗?我要给它发送好多命令,都是上下有关联的
      

  4.   

      一直搞不清WinExec和CreatProcess,好像还有其他的,有什么区别。
      

  5.   

    有上下关联的那应得用到管道了
    http://blog.sina.com.cn/s/blog_6cadcce70101apwv.html
      

  6.   

    CreatProcess:http://msdn.microsoft.com/en-us/library/ms682425.aspx
    WinExec:http://msdn.microsoft.com/query/dev10.query?appId=Dev10IDEF1&l=ZH-CN&k=k(%22WINBASE%2fWINEXEC%22);k(WINEXEC);k(DevLang-%22C%2B%2B%22);k(TargetOS-WINDOWS)&rd=true
      

  7.   

    有上下关联的那应得用到管道了
    http://blog.sina.com.cn/s/blog_6cadcce70101apwv.html  用管道的话是不是CMD可以一直读取、执行管道里写入的命令,知道判断管道内没有命令?这说明CMD一直在后台运行吗?我现在只可以根据这个例子执行一个命令,不知道怎么再继续输入命令(必须是在第一个命令的基础上执行)  谢谢
      

  8.   

    大家能不能给我说一下,因为我要持续给CMD发命令,又只能用按键的形式触发这些命令传送给CMD,不知道在用CreatProcess()处理这些命令时是相当于CMD一直在后台运行、以按键形式不断往里面输命令,还是CMD并不是一直在后台运行,而是来一个命令处理一个或者我理解的都不对啊!!我希望是CMD一直在后台运行的,因为发送的这些命令前后是有关连的,不过这一点在哪句代码中可以体现?请给我个示例
      

  9.   

        指定新进程的主窗口特性时,STARTUPINFO si;
        一般用语句si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES
        查了一下资料,STARTF_USESTDHANDLES使用hstdInput、hstdOutput和hstdError成员:HANDLE hStdInput用于设定供控制台输入和输出用的缓存的句柄。按照默认设置,hstdInput 用于标识键盘缓存,hstdOutput和hstdError用于标识控制台窗口的缓存。
          而我不想用键盘输入命令,是不是问题出在这里啊?
      

  10.   

    LZ是否可以参看:关于C++中用ShellEcexute打开一个应用程序???http://bbs.csdn.net/topics/390861587
      

  11.   

    仅供参考:
    #pragma comment(lib,"user32")
    #include <stdio.h>
    #include <windows.h>
    int main() {
        SECURITY_ATTRIBUTES sa          = {0};
        STARTUPINFO         si          = {0};
        PROCESS_INFORMATION pi          = {0};
        HANDLE              hPipeOutputRead  = NULL;
        HANDLE              hPipeOutputWrite = NULL;
        HANDLE              hPipeInputRead   = NULL;
        HANDLE              hPipeInputWrite  = NULL;
        BOOL                bTest = 0;
        DWORD               dwNumberOfBytesRead = 0;
        DWORD               dwNumberOfBytesWrite = 0;
        CHAR                szMsg[100];
        CHAR                szBuffer[256];    sa.nLength = sizeof(sa);
        sa.bInheritHandle = TRUE;
        sa.lpSecurityDescriptor = NULL;    // Create pipe for standard output redirection.
        CreatePipe(&hPipeOutputRead,  // read handle
                &hPipeOutputWrite, // write handle
                &sa,      // security attributes
                0      // number of bytes reserved for pipe - 0 default
                );    // Create pipe for standard input redirection.
        CreatePipe(&hPipeInputRead,  // read handle
                &hPipeInputWrite, // write handle
                &sa,      // security attributes
                0      // number of bytes reserved for pipe - 0 default
                );    // Make child process use hPipeOutputWrite as standard out,
        // and make sure it does not show on screen.
        si.cb = sizeof(si);
        si.dwFlags     = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
        si.wShowWindow = SW_HIDE;
        si.hStdInput   = hPipeInputRead;
        si.hStdOutput  = hPipeOutputWrite;
        si.hStdError   = hPipeOutputWrite;    CreateProcess (
              NULL, "cmd.exe",
              NULL, NULL,
              TRUE, 0,
              NULL, NULL,
              &si, &pi);    // Now that handles have been inherited, close it to be safe.
        // You don't want to read or write to them accidentally.
        CloseHandle(hPipeOutputWrite);
        CloseHandle(hPipeInputRead);    // Now test to capture DOS application output by reading
        // hPipeOutputRead.  Could also write to DOS application
        // standard input by writing to hPipeInputWrite.
        sprintf(szMsg, "dir *.txt /b\nexit\n");
        WriteFile(
              hPipeInputWrite,      // handle of the write end of our pipe
              &szMsg,               // address of buffer that send data
              18,                   // number of bytes to write
              &dwNumberOfBytesWrite,// address of number of bytes read
              NULL                  // non-overlapped.
              );    while(TRUE)
        {
           bTest=ReadFile(
              hPipeOutputRead,      // handle of the read end of our pipe
              &szBuffer,            // address of buffer that receives data
              256,                  // number of bytes to read
              &dwNumberOfBytesRead, // address of number of bytes read
              NULL                  // non-overlapped.
              );      if (!bTest){
              sprintf(szMsg, "Error #%d reading pipe.",GetLastError());
              MessageBox(NULL, szMsg, "WinPipe", MB_OK);
              break;
          }      // do something with data.
          szBuffer[dwNumberOfBytesRead] = 0;  // null terminate
          MessageBox(NULL, szBuffer, "WinPipe", MB_OK);
        }    // Wait for CONSPAWN to finish.
        WaitForSingleObject (pi.hProcess, INFINITE);    // Close all remaining handles
        CloseHandle (pi.hProcess);
        CloseHandle (hPipeOutputRead);
        CloseHandle (hPipeInputWrite);    return 0;
    }
      

  12.   

        我应该是要用CreatProcess()向CMD传送命令吧
      

  13.   

    用CreatProcess,用ShellEcexute都可以的!
      

  14.   

    @zhao4zhong1
         你给我参考的代码是要通过键盘,向输入 hPipeInputWrite输入命令吗?STARTF_USESTDHANDLES是不是限制了只能通过键盘输入命令?
        能不能做成一个按键响应发送一个命令行给CMD的形式?
      

  15.   

         我现在可以往CMD发送一个命令执行,但是想让CMD在执行完上一个命令的时候不关闭,可以继续另一个命令,不知道这一步该怎么做
      

  16.   

         我现在可以往CMD发送一个命令执行,但是想让CMD在执行完上一个命令的时候不关闭,可以继续另一个命令,不知道这一步该怎么做那试试可以一起传过去
      

  17.   

      @chenlycly
       恐怕不行,我需要一个消息响应对应一个命令或两三个命令,应该会有好多个消息响应,而全部的命令都应该是相关的,也就是说CMD需要一直在执行。。这个可以实现吗?
      

  18.   

    主要是CMD是系统的程序,我们无法介入去控制
      

  19.   

      我本来还想着可不可以CMD一直在后台运行,然后在VS中按一个键相当于把一个命令输入给CMD,在CMD中可以执行并将结果返回VS界面。。这么说,这个方法是行不通的??