zoukankan      html  css  js  c++  java
  • 重定位本进程的标准输出(非子进程)

    PS:标准输入/标准错误 ,参考这个来弄吧。

    环境:Win7(32位/64位),VC6

    1、

     1 int main()
     2 {
     3     printf("*stdin : %x
    ", *stdin);
     4     printf("*stdout : %x
    ", *stdout);
     5     printf("*stderr : %x
    ", *stderr);
     6 
     7     printf("stdin : %x
    ", stdin);
     8     printf("stdout : %x
    ", stdout);
     9     printf("stderr : %x
    ", stderr);
    10 
    11     printf("GetStdHandle(STD_INPUT_HANDLE) return : %x
    ", GetStdHandle(STD_INPUT_HANDLE));
    12     printf("GetStdHandle(STD_OUTPUT_HANDLE) return : %x
    ", GetStdHandle(STD_OUTPUT_HANDLE));
    13     printf("GetStdHandle(STD_ERROR_HANDLE) return : %x
    ", GetStdHandle(STD_ERROR_HANDLE));
    14 
    15     return 0;
    16 }

    得到的结果为:

    *stdin : 429620
    *stdout : 0
    *stderr : 0
    stdin : 425a30
    stdout : 425a50
    stderr : 425a70
    GetStdHandle(STD_INPUT_HANDLE) return : 3
    GetStdHandle(STD_OUTPUT_HANDLE) return : 7
    GetStdHandle(STD_ERROR_HANDLE) return : b

    2、

    http://bbs3.driverdevelop.com/read.php?tid-98473-page-e.html 中 五楼说到:

    SetStdHandle 仅仅是对 Peb->ProcessParameters里的 StandardInput 、StandardOutput 、StandardError 3个变量的赋值而已。

    printf内部实现类似于
      sprintf(buf,format,arglist)
      fwrite(stdout,buf);

    其中stdout为CRT内部变量,在初始化时已经被设置为 stdout=GetStdHandle(STD_OUTPUT_HANDLE);
    (具体看CRT代码,ioinit()),所以,即使你在程序里改变了Peb->ProcessParameters里的 StandardOutput ,stdout没有变化

    想重定向PRINTF之类标准库函数,想办法改变stdout吧

    2.1、

    我看了 _ioinit() 里面条用了 宏stdhndl,确实 在_ioinit()中,有 “GetStdHandle(STD_INPUT_HANDLE);”、“GetStdHandle(STD_OUTPUT_HANDLE);”、“GetStdHandle(STD_ERROR_HANDLE);”,但是 是如何 赋值给 stdin、stdout、stderr 的  这个没看出来...

    2.2、

    printf 

    2.3、

    关于上面说到的 “Peb->ProcessParameters里的 StandardInput 、StandardOutput 、StandardError”,可以使用 WinDBG查看相关结构中的相关属性值,但是暂时还未自己亲手查看验证过...

     3、

    PS:测试代码:

     1 #include <windows.h>
     2 #include <stdio.h>
     3 
     4 #include <io.h>
     5 #include <Fcntl.h>
     6 
     7 int main()
     8 {
     9     printf("*stdin : %x
    ", *stdin);
    10     printf("*stdout : %x
    ", *stdout);
    11     printf("*stderr : %x
    ", *stderr);
    12     printf("
    ");
    13 
    14     printf("GetStdHandle(STD_INPUT_HANDLE) return : %x
    ", GetStdHandle(STD_INPUT_HANDLE));
    15     printf("GetStdHandle(STD_OUTPUT_HANDLE) return : %x
    ", GetStdHandle(STD_OUTPUT_HANDLE));
    16     printf("GetStdHandle(STD_ERROR_HANDLE) return : %x
    ", GetStdHandle(STD_ERROR_HANDLE));
    17     printf("
    ");
    18 
    19     STARTUPINFO si = {0};
    20     si.cb = sizeof(STARTUPINFO);
    21 
    22         GetStartupInfo(&si);
    23         printf("si.hStdOutput(1) : %x
    ", si.hStdOutput);
    24 
    25         SetStdHandle(STD_OUTPUT_HANDLE, (void*)100);
    26 
    27         GetStartupInfo(&si);
    28         printf("si.hStdOutput(2) : %x
    ", si.hStdOutput);
    29 
    30 
    31     printf("
    ");
    32 
    33     printf("*stdin : %x
    ", *stdin);
    34     printf("*stdout : %x
    ", *stdout);
    35     printf("*stderr : %x
    ", *stderr);
    36     printf("
    ");
    37 
    38     printf("GetStdHandle(STD_INPUT_HANDLE) return : %x
    ", GetStdHandle(STD_INPUT_HANDLE));
    39     printf("GetStdHandle(STD_OUTPUT_HANDLE) return : %x
    ", GetStdHandle(STD_OUTPUT_HANDLE));
    40     printf("GetStdHandle(STD_ERROR_HANDLE) return : %x
    ", GetStdHandle(STD_ERROR_HANDLE));
    41 
    42     return 0;
    43 }

    控制台输出:

     1 *stdin : 4285e0
     2 *stdout : 0
     3 *stderr : 0
     4 
     5 GetStdHandle(STD_INPUT_HANDLE) return : 3
     6 GetStdHandle(STD_OUTPUT_HANDLE) return : 7
     7 GetStdHandle(STD_ERROR_HANDLE) return : b
     8 
     9 si.hStdOutput(1) : ffffffff
    10 si.hStdOutput(2) : ffffffff
    11 
    12 *stdin : 4285e0
    13 *stdout : 0  // ZC: 这个值不改变的话,本进程的 标准输出流 是没有被重定向的。
    14 *stderr : 0
    15 
    16 GetStdHandle(STD_INPUT_HANDLE) return : 3
    17 GetStdHandle(STD_OUTPUT_HANDLE) return : 64  // ZC: 只有这个值 改变了
    18 GetStdHandle(STD_ERROR_HANDLE) return : b
    19 Press any key to continue

    A

  • 相关阅读:
    python 笔记——生成器和迭代器
    Python装饰器
    python 小程序—三级菜单—循环和字典练习
    python 小程序—循环和列表训练
    lvs主备可以自由切换,vip落在主上的时候,端口无法telnet,业务连接不了
    mongodb学习
    lvs DR模式
    去哪儿网mysql语法审核工具Inception正式开源
    无法远程连接ubuntu下的mysql
    值得珍藏的28本股市投资经典著作
  • 原文地址:https://www.cnblogs.com/CodeSkill/p/4949325.html
Copyright © 2011-2022 走看看