登录 用户中心() [退出] 后台管理 注册
   
您的位置: 首页 >> 程序员学前班[不再更新,只读] >> 主题: 如何正确使用CreateProcess和_beginthreadex函数?     [回主站]     [分站链接]
标题
如何正确使用CreateProcess和_beginthreadex函数?
clq
浏览(0) + 2010-10-12 11:27:14 发表 编辑

关键字:

来自 http://www.lvxuef.com/article.asp?id=202

没看到这篇文章以前我一直奇怪,为什么子窗口会将 printf 输出显示在父进程中.

clq
2010-10-12 11:28:26 发表 编辑

如何正确使用CreateProcess和_beginthreadex函数? 

(1) LPCTSTR   lpApplicationName   
  想运行的可执行文件的名字的字符串(应含扩展名)。如果找不到该文件,CreateProcess运行失败。应该设为NULL。   
  (2) LPTSTR   lpCommandLine   
  传递给新进程的命令行字符串,应当为非常量字符串的地址。可以设定一个完整的命令行,如果第一个标记没有扩展名,CreateProcess将其假设为.exe。如果找不到该文件,CreateProcess按环境设置目录搜索运行。   
  (3) LPSECURITY_ATTRIBUTES     
  设定进程对象的安全性。可以为这些参数传递NULL,在这种情况下,系统为这些对象赋予默认安全性描述符。   (不明白)   
  (4) LPSECURITY_ATTRIBUTES   lpThreadAttributes   
  设定线程对象的安全性。可以为这些参数传递NULL,在这种情况下,系统为这些对象赋予默认安全性描述符。   (不明白)   
  (5) BOOL   bInheritHandles   
  决定子进程对父进程继承性,一般设为FALSE。   
  (6) DWORD   dwCreationFlags   
  用于标识标志,以便用于规定如何来创建新进程。   
  标志 说明   
  EBUG_PROCESS 父进程想要调试子进程和子进程将来生成的任何进程。当任何子进程(被调试进程)中发生某些事件时,将情况通知父进程。   (不明白)   
  DEBUG_ONLY_THIS_PROCESS 与DEBUG_PROCESS标志相类似,调试程序只被告知紧靠父进程的子进程中发生的特定事件。   (不明白)   
  Create_SUSPENDED 新进程被创建,但是,它的主线程则被挂起。   
  DETACHED_PROCESS 阻止基于CUI的进程对它的父进程的控制台窗口的访问,并告诉系统将它的输出发送到新的控制台窗口。   
  Create_NEW_CONSOLE 为新进程创建一个新控制台窗口。如果同时设定Create_NEW_CONSOLE和DETACHED_PROCESS标志,就会产生一个错误。   
  Create_NO_WINDOW 不为应用程序创建任何控制台窗口。   
  Create_NEW_PROCESS_GROUP 修改用户在按下Ctrl+C或Ctrl+Break键时得到通知的进程列表。   
  Create_DEFAULT_ERROR_MODE 不继承父进程使用的错误模式。   
  Create_SEPARATE_WOW_VDM 只能当你在Windows2000上运行16位Windows应用程序时使用。告诉系统创建一个单独的DOS虚拟机(VDM),并且在该VDM中运行16位Windows应用程序。   (不明白)   
  Create_SHARED_WOW_VDM 只能当你在Windows2000上运行16位Windows应用程序时使用。在系统的共享VDM中运行16位Windows应用程序。   (不明白)   
  Create_UNICODE_ENVIRONMENT 告诉系统,子进程的环境块应该包含Unicode字符。按照默认设置,进程的环境块包含的是ANSI字符串。   
  Create_FORCEDOS 强制系统运行嵌入16位OS/2应用程序的MOS-DOS应用程序。   
  Create_BREAKAWAY_FROM_JOB 使作业中的进程生成一个与作业相关联的新进程   (不明白)。   
  IDLE_PRIORITY_CLASSBELOW_NORMAL_PRIORITY_CLASSNORMAL_PRIORITY_CLASSABOVE_NORMAL_PRIORITY_CLASSHIGH_PRIORITY_CLASSREALTIME_PRIORITY_CLASS 空 闲低于正常(Windows2000)正常高于正常(Windows2000)高实时   
  对于大多数应用程序来说不应该设定优先级类。   
  (7) LPVOID   lpEnvironment   
  指 向包含新进程将要使用的环境字符串的内存块。在大多数情况下,为该参数传递NULL,使子进程能够继承它的父进程正在使用的一组环境字符串。也可以使用 GetEnvironmentStrings函数当不再需要该内存块时,应该调用FreeEnvironmentStrings函数将内存块释放。   
  (8) LPCTSTR   lpCurrentDirectory   
  设置子进程的当前驱动器和目录。如果本参数是NULL,则新进程的工作目录将与生成新进程的应用程序的目录相同。如果本参数不是NULL,那么必须指向包含需要的工作驱动器和工作目录的以0   结尾的字符串。注意,必须设定路径中的驱动器名。   
  (9) LPSTARTUPINFO   lpStartupInfo   
  使用时应首先进行初始化。   
  成员 窗口/控制台 作用   
  cb 两者兼有 用作版本控制手段。必须初始化为sizeof(STARTUPINFO)   
  lpReserved 两者兼有 保留。必须初始化为NULL   (不为NULL也可以)   
  lpDesktop 两者兼有 标识启动应用程序所在桌面的名字。如果桌面不存在,便创建一个带有默认属性的桌面,并使用为新进程指定的名字。其值为NULL时,与当前桌面相关联。   (不明白)   
  lpTitle 控制台 设定控制台窗口的名称。其值为NULL,则把可执行文件的名字用作窗口名。   
  dwXdwY 两者兼有 设定应用程序窗口在屏幕上的位置(以像素为单位)。只有当子进程用CW_USEDEFAULT作为CreateWindow的x参数来创建它的第一个重叠窗口时,才使用这两个坐标。   
  dwXSizedwYsize 两者兼有 设定应用程序窗口的宽度和长度(以像素为单位)只有当子进程将CW_USEDEFAULT用作CreateWindow的nWidth参数来创建它的第一个重叠窗口时,才使用这些值。   
  dwXCountCharsdwYCountChars 控制台 设定子应用程序的控制台窗口的宽度和高度(以字符为单位)   
  dwFillAttribute 控制台 设定控制台窗口的文本和背景颜色   
  dwFlags 两者兼有 后面以表格说明。   
  wShowWindow 窗口 设定如果子应用程序初次调用的ShowWindow将SW_SHOWDEFAULT作为nCmdShow参数传递时,该应用程序的第一个重叠窗口应该如何出现。   
  cbReserved2 两者兼有 保留。必须被初始化为0   (非0也可以)   
  lpReserved2 两者兼有 保留。必须被初始化为NULL   (为什么)   
  hStdInputhStdOutputhStdError 控制台 设定控制台输入输出缓存的句柄。照默hStdInput标识键盘缓存,hStdOutput和hStdError标识控制台窗口缓存。   
  dwFlags使用方法:   
  标志 含义   
  STARTF_USESIZE 使用dwXSize和dwYSize成员   
  STARTF_USESHOWWINDOW 使用wShowWindow成员   
  STARTF_USEPOSITION 使用dwX和dwY成员   
  STARTF_USECOUNTCHARS 使用dwXCountChars和dwYCountChars成员   
  STARTF_USEFILLATTRIBUTE 使用dwFillAttribute成员   
  STARTF_USESTDHANDLES 使用hStdInput、hStdOutput和hStdError成员   
  STARTF_RUN_FULLSCREEN 强制在x86计算机上运行的控制台应用程序以全屏幕方式运行   
  STARTF_FORCEONFEEDBACK 启动进程时,临时将系统的箭头光标改为沙漏箭头光标。   
  STARTF_FORCEOFFFEEDBACK 启动进程时,不将光标改为沙漏。   
  (10) LPPROCESS_INFORMATION   lpProcessInformation   
  新 进程的返回信息。hProcess为新进程内核对象的句柄;hThread为新线程内核对象的句柄。在使用后应当用CloseHandle释放,使该内核 的使用计数减一。dwProcessId新进程ID号;dwThreadId新线程ID号。0不能为ID号。虽然系统不会同时有相同的ID号,但是当一个 进程的内核句柄被释放后其ID号又可能被新的进程使用。若要确保进程ID或线程ID不被重复使用,唯一的方法是保证进程或线程的内核对象不会被撤消。如果 刚刚创建了一个新进程或线程,只要不关闭这些对象的句柄,就能够保证进程对象不被撤消。一旦应用程序结束使用该ID,那么调用CloseHandle就可 以释放内核对象,要记住,这时使用或依赖进程ID,对来说将不再安全。如果使用的是子进程,将无法保证父进程或父线程的有效性,除非父进程复制了它自己的 进程对象或线程对象的句柄,并让子进程继承这些句柄。   


使用方法与CreateThread函数相同,只是调用参数类型需要转换。   



[本日志由 admin 于 2009-05-11 03:08 PM 编辑]

clq
2010-10-12 11:31:27 发表 编辑

应当将默认 dwCreationFlags 修改为新建立一个控制台,这样才是符合大家的普遍感受.

    DWORD dwCreationFlags = 0;
    dwCreationFlags = CREATE_NEW_CONSOLE;//DETACHED_PROCESS;


//执行一个程序//返回的是进程 ID//以后要加自动设置工作目录的功能
long ExecuteProc(const std::string fn, bool show)
{
    //得到文件路径
    std::string child_path = extract_file_path(fn);

    STARTUPINFOA si;  
    ::ZeroMemory(&si, sizeof(si));  
    si.cb = sizeof(STARTUPINFOA);
    si.dwFlags = STARTF_USESHOWWINDOW;//没有这个的话 wShowWindow 不起作用
    //si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
   
    //dwCreationFlags 创建标识,可用于建立新控制窗口//如果调用 CreateProcess 的程序是一个 windows gui 窗口则 不设置 dwCreationFlags 的情况下 dos 窗口会隐藏
    //如果不设置又是 dos 类型程序,则子进程会使用父亲窗口的控制台来打印输出信息
    //如果设置为 DETACHED_PROCESS 则关闭自己的控制台不会导致子进程也关闭[默认是会的 - 如果子进程也是控制台程序的话]
    DWORD dwCreationFlags = 0;
    dwCreationFlags = CREATE_NEW_CONSOLE;//DETACHED_PROCESS;
   
    if (show == true)
    {
        si.wShowWindow = SW_SHOW;
    }
    else
    {
        si.wShowWindow = SW_HIDE;  
    }

    //si.wShowWindow = SW_SHOW;
    //si.wShowWindow=SW_SHOWMINIMIZED;//test
   
    PROCESS_INFORMATION pi;
    ::ZeroMemory(&pi, sizeof(pi));

    //::CreateProcessA(NULL, (char *)fn.c_str(), NULL, NULL, FALSE, 0,             NULL, NULL,               &si, &pi);
    //::CreateProcessA(NULL, (char *)fn.c_str(), NULL, NULL, FALSE, 0,             NULL, child_path.c_str(), &si, &pi);
    //::CreateProcessA(NULL, (char *)fn.c_str(), NULL, NULL, TRUE,  0,             NULL, child_path.c_str(), &si, &pi);
    ::CreateProcessA(NULL, (char *)fn.c_str(), NULL, NULL, FALSE, dwCreationFlags, NULL, child_path.c_str(), &si, &pi);

    //return pi.dwProcessId;

    //Result :=   $FFFFFFFF   else   begin 
    //WaitforSingleObject(ProcessInfo.hProcess,INFINITE); 
    //GetExitCodeProcess(ProcessInfo.hProcess,Result); 
    //end;  


    //--------------------------------------------------
    //写入进程 id
    std::string path = extract_file_path(GetAppFilename());
    lines fns;
    std::string proc_fn = path + "\\proc_ids.txt";
    FILE * f = NULL;
    f = fopen(proc_fn.c_str(), "a+b");
    if (f != NULL)
    {
        fprintf(f, "%d\r\n", pi.dwProcessId);
        fclose(f);
    }
   
   

    return pi.dwProcessId;
}

//--------------------------------------------------


总数:2 页次:1/1 首页 尾页  
总数:2 页次:1/1 首页 尾页  


所在合集/目录



发表评论:
文本/html模式切换 插入图片 文本/html模式切换


附件:



NEWBT官方QQ群1: 276678893
可求档连环画,漫画;询问文本处理大师等软件使用技巧;求档softhub软件下载及使用技巧.
但不可"开车",严禁国家敏感话题,不可求档涉及版权的文档软件.
验证问题说明申请入群原因即可.

Copyright © 2005-2020 clq, All Rights Reserved
版权所有
桂ICP备15002303号-1