转自:http://hi.baidu.com/jackyho2000/blog/item/b5c5fabdd3b4db0019d81fbb.html

我演示了一下在MFC程序中怎么应用DOS的dir的命令,可是我们遇到了需要解决的问题,首先就是文件dir.txt的残留问题,其实这个问题很简单,我们也可以用dos的del命令在操作后将dir.txt文件删除,这样的结果就是程序会两次弹出窗口,这样更加让人无法接受了,现在我们的问题是,有没有办法隐藏弹出窗口?答案是有的,这点我在网上找了很久,都没有找到解答,最后自己摸索出了一些方法,不知道还有没有更好的方法,因为这些方法都有些缺点,比较恼火。

首先,我们可以用第二参数为SW_HIDE调用WinExec()这个windows的API,这时候又有个问题了,WinExec()是调用程序的,而DIR程序文件在哪里?呵呵,其实这点在有很多DOS使用经验的人都知道,DOS命令在以前就分两种,一种叫内部命令,一种叫外部命令。其中比较常用的比如dir,del都属于内部命令,特点是直接加载进内存。而外部命令是可以在目录中找到具体的文件的,当时就会常常遇到PATH设定不对导致的外部命令调用错误,而需要找到目录去调用的情况。既然加载在内存里面,我们到哪里去找命令文件?答案我不知道,不过有个变通的方法。因为在windows中,DOS的实际调用都是用cmd程序,那么我们就用它来调用,具体方法是以/C为参数调用。比如我们要调用dir命令,那么具体方法如下:

WinExec("cmd /C dir");

理由可以参考help cmd。当然我们还是有以前那样的问题,那就是dir后面跟具体目录做参数的时候需要加引号,那么我们调用目录的时候一般可以用下面的形式:

WinExec("cmd /c dir /"xxxxx/");

这种方法在直接调用的时候很好用,比如删除文件的时候,直接一个WinExec("cmd /c del dir.txt");就可以了,但是也是有个问题,这是个太老的API了,所以根本没有Unicode的版本,苦闷的Unicode版本程序因此无法较好的使用,在以CString为字符串调用的时候似乎只有两种方法,一种是以ANSI方式编译,一种就是通过Unicode到ANSI的转换了,这样的转换很可能还会丢失中文信息。因此,个人推荐只在直接调用DOS命令的时候使用WinExec,而且也推荐直接调用的时候使用,因为WinExec只需要两个参数,很容易调用。但是要在Unicode程序中以CString为参数调用怎么办?当然,用MSDN中推荐的CreateProcess不会有任何问题,问题是,太复杂了。。。。。个人推荐另一个方案,ShellExecute。虽然比WinExec复杂一点,但是还可以接受。函数原型如下:

HINSTANCE ShellExecute(

HWND hwnd,

LPCTSTR lpOperation,

LPCTSTR lpFile,

LPCTSTR lpParameters,

LPCTSTR lpDirectory,

INT nShowCmd

);

这里,hwnd直接用窗口的句柄就可以了,lpOperation可以省略,默认为open,lpFile我们调用cmd,lpParameters我们加入参数,注意的是cmd要多个/C参数,目录可以为空,nShowCmd为SW_HIDE以达到我们的目的,同上面的情况,调用ShellExecute的时候为以下形式:

ShellExecute(m_hWnd, NULL, _T(cmd), _T("/C dir /"xxxxxx/"");

比如在上一节的例子中,我们调用ShellExecute的方法就是下面这样:

CString dir = _T("/C dir /"") + m_directory + _T("/" >dir.txt");

ShellExecute(m_hWnd, NULL, _T("cmd"), dir, NULL, SW_HIDE);

然后,改变后你会发现程序在第一次调用的时候不会有任何反应,一定要第二次点击按钮才能生效,原因可能会令人很困惑,有多线程编程经验的人可能会反应过来,因为ShellExecute的调用实际上是新开了一个线程,那么所有关于多线程编程让人郁闷苦恼烦躁的问题都完全适用。这里,问题在于,ShellExecute新开线程后直接返回了,不等dir调用完成,那么下面接着的打开文件根本就找不到文件,我给出一种解决方案,在打开文件的时候检测一下,然后用Sleep休息200毫秒,再检测,如此可以达到需要的要求:

while(!infile.is_open())

{

static int i = 0;

::Sleep(200);

infile.open("dir.txt");

++i;

if(i > 50)

{

MessageBox(_T("Error to create and open the file"));

exit(EXIT_FAILURE);

}

}

经过完善,上节中ReadFromDir函数完整结果如下:

std::string CTestDialogDlg::ReadFromDir()

{

UpdateData();

CString dir = _T("/C dir /"") + m_directory + _T("/" >dir.txt");

// _wsystem(dir);

std::string strFile,strTemp;

ShellExecute(m_hWnd, NULL, _T("cmd"), dir, NULL, SW_HIDE);

// WinExec(dir, SW_HIDE);

std::ifstream infile;

while(!infile.is_open())

{

static int i = 0;

::Sleep(200);

infile.open("dir.txt");

++i;

if(i > 50)

{

MessageBox(_T("Error to create and open the file"));

exit(EXIT_FAILURE);

}

}

while(std::getline(infile, strTemp))

{

strFile += strTemp + "/n";

}

infile.close();

WinExec("del dir.txt", SW_HIDE);

// _wsystem("del dir.txt");

return strFile;

}

经过如上改变,再使用程序,没有看到源代码的人,谁还知道你是用了DOS的DIR命令实现的呢?

这一节的主要内容是给广大因为使用了DOS命令而导致程序运行效果不佳老弹出窗口的同志们信心,大胆的调用DOS命令吧,没有人知道的,只要能简单的完成任务,我们不择手段,呵呵。

///

转自:http://hi.baidu.com/notepad519/blog/item/0f126643545eae1673f05dc7.html

去除控件台程序中的窗口显示

总的来说都来改变程序的入口点来达到目的:

1.

#pragma comment(linker, "/subsystem:windows /entry:mainCRTStartup")
#include <iostream>
using namespace std;
int main(void)

{
   cout<<"河北经贸大学"<<endl;
return 0;

}

在Cdm下 文件名.exe>>新的文件名.txt(格式后缀可变) 可以进行查看输入内容。

2.

#pragma comment( linker, "/subsystem:windows" )
#include   <windows.h>
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR     lpCmdLine,
int       nCmdShow)
{
MessageBox(NULL,"显示内容","标题",0);
     return 0;
}

后记:一开始用的是AfxMessageBox 出现以后错误
'AfxMessageBox' : undeclared identifier
原因是:因为AfxMesageBox(   )函数是
MFC类库提供的函数,而Console程序又没有提供支持   MFC,
所以就不应该使用这个函数了。要实现用API函数
MessageBox(   )来实现。
注意需要在添加   #include   <windows.h>

3、subsystem和可执行文件的启动
LINK的时候需要指定/subsystem,这个链接选项告诉Windows如何运行可执行文件。
控制台程序是/subsystem:"console"
其它程序一般都是/subsystem:"windows "

将 subsystem 选成"console"后,Windows在进入可执行文件的代码前(如mainCRTStartup),就会产生一个控制台窗口。
如果选择"windows",操作系统就不产生console窗口,该类型应用程序的窗口由用户自己创建。

可执行文件都有一个Entry Point,LINK时可以用/entry指定。缺省情况下,如果subsystem是“console”,Entry Point是 mainCRTStartup(ANSI)或wmainCRTStartuup(UNICODE),即:
/subsystem:"console" /entry:"mainCRTStartup" (ANSI)
/subsystem:"console" /entry:"wmainCRTStartuup" (UNICODE)
mainCRTStartup 或 wmainCRTStartuup 会调用main或wmain。
值得一提的是,在进入应用程序的Entry Point前,Windows的装载器已经做过C变量的初始化,有初值的全局变量拥有了它们的初值,没有初值的变量被设为0。

如果subsystem是“windows”,Entry Point是WinMain(ANSI)或wWinMain(UINCODE),即:
/subsystem:"windows" /entry:"WinMainCRTStartup" (ANSI)
/sbusystem:"windows" /entry:"wWinMainCRTStartup" (UINCODE)
WinMainCRTStartup 或 wWinMainCRTStartup 会调用 WinMain 或 wWinMain。

如果使用MFC框架,WinMain也会被埋藏在MFC库中(APPMODUL.CPP):
extern "C" int WINAPI
_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
// call shared/exported WinMain
return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
}
"_t"是一个宏,对于ANSI版本,"_tWinMain"就是"WinMain";对于UINCODE版本,"_tWinMain"就是"wWinMain"。

全局C++对象的构造函数是在什么地方调用的?答案是在进入应用程序的Entry Point后,在调用main函数前的初始化操作中。所以MFC的theApp的构造函数是在_tWinMain之前调用的。

4、不显示Console窗口的Console程序
在默认情况下/subsystem 和/entry开关是匹配的,也就是:
"console"对应"mainCRTStartup"或者"wmainCRTStartup"
"windows"对应"WinMain"或者"wWinMain"
我们可以通过手动修改的方法使他们不匹配。例如:

#include "windows.h"
#pragma comment( linker, "/subsystem:/"windows/" /entry:/"mainCRTStartup/"" ) // 设置入口地址
void main(void)
{
MessageBox(NULL, "hello", "Notice", MB_OK);
}

这个Console程序就不会显示Console窗口。如果选/MLd的话,这个程序只需要链接LIBCD.LIB user32.lib kernel32.lib

C++ 中隐藏DOS调用的命令行窗口相关推荐

  1. MySQL数据库安装-Windows10为例【超级详细安装过程(每一步的截图)、检测安装是否成功、登录数据库并查看版本号、将MySQL添加到环境变量中、在命令行窗口操作数据库】

    哈哈,这是在哔哩哔哩网站上 看的 MySQL安装步骤. 我安装的时候,截截图,希望对大家 有所帮助. 链接:https://pan.baidu.com/s/1fKFQCVHMQOmbg84UyGrKB ...

  2. 如何复制计算机页面,怎么把电脑命令行窗口里的内容复制到剪贴板

    想要把电脑命令行窗口里的内容复制到剪贴板,该如何操作呢,那么怎么把电脑命令行窗口里的内容复制到剪贴板的呢?下面是学习啦小编收集整理的怎么把电脑命令行窗口里的内容复制到剪贴板,希望对大家有帮助~~ 把电 ...

  3. VSMFC程序显示命令行窗口

    编写MFC程序时,想打印出调试信息,使用cout后,发现程序并没有像想象中那样自动弹出命令行窗口,要输出的信息也没地方去查看.百度后知道要手动调出命令行窗口,才可以看到输出的信息. 百度上介绍了两种方 ...

  4. 计算机 窗口打开的方法,如何打开命令行窗口?两种实用的方法介绍

    Windows系统中常常会用到命令行窗口,那么我们该如何打开命令行窗口?接下来,小编为大家介绍两种实用的打开命令行窗口的技巧,再也不必担忧如何打开命令行窗口的烦恼了. 第一种打开方法 1.点击自己的电 ...

  5. c++ 调用cmd命令行函数 可隐藏黑框 四种方法总结

    在很多情况下,不得不调用cmd命令行,去实现一系列功能,总结靠谱方法两种如下: 方法一:可接受cmd命令行黑框一闪(推荐星数::可传值几乎任何cmd命令) string string getCmdRe ...

  6. dos c语言显示符号图案,在DOS命令行窗口中显示出用各种字符拼凑出来的各种图案的实现方法,如本人头像...

    注:文中例子是本人刚学C++编程语言的时候制作的,实现方法很简单,主要使用for循环语句,无需什么复杂烧脑的算法. 由于经常看到各种符号拼成的图案,感觉很有意思,所以自己也弄了个,纯属好玩. (作品- ...

  7. 在DOS命令行窗口中显示出用各种字符拼凑出来的各种图案的实现方法,如本人头像

    注:文中例子是本人刚学C++编程语言的时候制作的,实现方法很简单,主要使用for循环语句,无需什么复杂烧脑的算法. 由于经常看到各种符号拼成的图案,感觉很有意思,所以自己也弄了个,纯属好玩. (作品- ...

  8. VS中让console程序不显示(隐藏)命令行窗口

    为了让Visual Studio编译的console程序运行时不显示命令行窗口,需要在main.cpp文件中添加以下代码: #pragma comment( linker, "/subsys ...

  9. dos重启计算机命令行,命令行中,重启计算机的命令是什么

    定时关机 Windows XP下实现定时关机的简单方法. 指定系统在22分钟后自动关闭:点击"开始→运行",在"打开"中输入命令"Shutdown - ...

最新文章

  1. js 监听 安卓事件_百行代码实现js事件监听实现跨页面数据传输
  2. iOS 进阶 - RUNTIME 运行时
  3. atheros蓝牙设备驱动 小米_小米Air 13笔记本黑苹果WiFi蓝牙硬件改装方案二
  4. Docker学习笔记 - Docker Compose
  5. java 蓝桥杯算法训练 未名湖边的烦恼
  6. BaseRecyclerViewAdapterHelper: 灵活强大的循环适配器
  7. linux运行bin not found,自己制作根文件后,程序-/bin/sh:XXX:not found错误
  8. js 访问android 路径,Android与JS进行交互传文件路径
  9. c语言计算器程序代码 链栈,【C语言】简易科学计算器源代码(链栈应用)(原创).doc...
  10. C#4.0新特性:可选参数,命名参数,Dynamic
  11. PeerCDN:使用WebRTC构建基于浏览器的P2P CDN
  12. SecureCRT官方下载地址
  13. 计算机应用维护师实习周记,计算机系统维护专业毕业实习周记
  14. 数学分析习题课讲义习题-第2章-2.4
  15. python 自动问答系统_问答系统介绍
  16. ubuntu 终端查看图片(eog)
  17. 基于 H5 Canvas “指纹识别“ 技术 【浏览器指纹 VS Canvas指纹】
  18. (译)ABP之Entities
  19. Android端阿里云实人认证
  20. 量化交易入门笔记-小市值股票策略

热门文章

  1. Monitor CodeForces - 846D ——二维前缀和
  2. linux上查看网络限制,如何在Linux上限制网络带宽
  3. 面向固态激光雷达和惯导的里程计和建图
  4. 剑指offer:面试题22. 链表中倒数第k个节点
  5. c++静态成员函数好处
  6. 在Ubuntu 16.4.3 LTS x86_64上安装PyCharm社区版笔记
  7. 在Blender中创建惊人的低多边形动画
  8. MQTT Qos类型解释
  9. jQuery的deferred对象详解
  10. asp.net提交危险字符处理方法之一