Borland Together Architect for Eclipse启动Dos窗口屏蔽方法
by
郭世龙
在启动 Borland Together Architect for Eclipse是总是首先弹出一个Dos窗口感觉很是不专业、不舒服、。仔细看了一下启动过程,之所以弹出这个窗口是应为在主程序程序之前有一个TogetherArchitect.bat批处理文件执行,这是Dos窗口弹出的罪魁祸首。首先想到的是修改这个批处理文件使之不显示Dos窗口,在网上查了半天资料也没能清除怎样屏蔽Dos窗口。还是用比较熟悉的Win32 Console程序来解决问题吧。有两个问题需要解决:其一是就是我们的目的,屏蔽批处理程序弹出的Dos窗口;其二是我们的控制台程序自身弹出的Dos窗口。第二个问题很好解决,在VC中的项目属性->链接中修改编译器链接选项,加入开关/SUBSYSTEM:Windows /ENTRY:main ,或者在程序中加入#pragma comment( linker, "/subsystem:/"windows/" /entry:/"mainCRTStartup/"" )
关于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;
如果subsystem是“windows”,Entry Point是WinMain(ANSI使用)或wWinMain(UINCODE使用),即:/subsystem:windows /entry:WinMainCRTStartup (ANSI使用) 或者/sbusystem:windows/entry:wWinMainCRTStartup (UINCODE使用)。WinMainCRTStartup 或 wWinMainCRTStartup 会调用 WinMain 或 wWinMain。
Function name
|
Default for
|
mainCRTStartup(or wmainCRTStartup)
|
An application using /SUBSYSTEM:CONSOLE; calls main (or wmain).
|
WinMainCRTStartup(or wWinMainCRTStartup)
|
An application using /SUBSYSTEM:WINDOWS; calls WinMain (or wWinMain), which must be defined with __stdcall.
|
_DllMainCRTStartup
|
A DLL; calls DllMain, which must be defined with __stdcall, if it exists.
|
在默认情况下/subsystem 和/entry开关是匹配的,也就是:"console"对应"mainCRTStartup"或者"wmainCRTStartup","windows"对应"WinMain"或者"wWinMain"。为了不显示控制台窗口,在控制台程序中加入如下的链接选项#pragma comment( linker, "/subsystem:/"windows/" /entry:/"mainCRTStartup/"" ) ,通过手动修改链接参数的方法使他们不匹配,告诉系统以“windows”的方式(不要产生窗口,程序自己创建窗口)来处理控制台程序。
屏蔽批处理程序弹出的Dos窗口
屏蔽批处理程序弹出的Dos窗口的方法也不复杂,其思路就是使用Windows API函数CreateProcess函数创建一个新的进程执行TogetherArchitect.bat批处理文件,在创建这个进程是要隐藏窗口。CreateProcess函数原型:
BOOL
CreateProcess(
LPCTSTR lpApplicationName,
LPTSTR
lpCommandLine,
LPSECURITY_ATTRIBUTES
lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCTSTR lpCurrentDirectory,
LPSTARTUPINFO lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
);
简单介绍一下几个重要的参数,
lpApplicationName
[
输入参数]
是一个指向以null结尾的字符串指针,它指明了的将要执行的程序。字符串可以是要执行程序的全路径以及文件名也可以使部分名。如果使用部分名,则函数用当前驱动器当前目录来完成将要执程序的指定。如果程序名没有后缀则使用默认扩展.exe。这个参量可以设置位NULL,此时使用lpCommandLine参量来指定要执行的程序。
lpCommandLine
[
输入、输出参数]
是指向一个以null结尾的将要执行的命令行字符串指针。这个参数可以是NULL。在这种情况下,使用参数lpApplicationName作为命令行。
bInheritHandles
[
输入参数] 如果这个参数是TRUE,调用进程的每个可继承的句柄都被新进程继承,如果是FALSE则不继承。
dwCreationFlags
[
输入参数] 这个参数用来控制进程的创建及其优先级。这里我们主要关心的标帜是CREATE_NO_WINDOW,它用来创建一个无窗口的控制台程序,它不能和CREATE_NEW_CONSOLE 或DETACHED_PROCESS一起使用,在基于MS-DOS的程序也不能使用。这个参数也用来控制新进程的优先级,默认优先级是NORMAL_PRIORITY_CLASS 。
lpStartupInfo
[
输入参数] 这个参数是一个指向STARTUOINFO结构体的指针。这个结构体用来说明新进程主窗口的窗口状态、桌面、标准句柄和外观。在这里,STARTUPINGO结构中需要设置的参数是cb= sizeof(STARTUPINFO),dwFlags = STARTF_USESHOWWINDOW和wShowWindow = SW_HIDE通过设置这些参数来隐藏窗口。
lpProcessInformation
[
输出参数] 是一个指向PROCESS_INFORMATION结构体的指针。这个结构体用来接受新进程的信息。这个结构体中的句柄必须用CloseHandle关闭,当它们不在需要的时候。
其他详细说明见MSDN文档。
使用这个API函数隐藏窗口有两种方法其一是将
dwCreationFlags
参数值设为CREATE_NO_WINDOW;其二是在输入参数
lpStartupInfo
指向的STARTUOINFO结构体中的dwFlags 变量设为STARTF_USESHOWWINDOW,将wShowWindow 变量设为SW_HIDE。
代 码
//CloseDosWin.cpp
#include "winuser.h"
#include "windows.h"
#include "CloseDosWin.h"
#include "stdio.h"
#include "string.h"
#define cmdline "cmd.exe /c TogetherArchitect.bat"
int main(int argc, char** argv)
{
TCHAR szCommand[]=_T(cmdline);
STARTUPINFO startupInfo;
ZeroMemory( &startupInfo, sizeof(startupInfo) );
startupInfo.cb = sizeof(STARTUPINFO);
//startupInfo.dwFlags = STARTF_USESHOWWINDOW;
//startupInfo.wShowWindow = SW_HIDE;
PROCESS_INFORMATION processInfo;
ZeroMemory( &processInfo, sizeof(processInfo) );
if (!CreateProcess(NULL,szCommand,NULL,NULL,FALSE,CREATE_NO_WINDOW/*NORMAL_PRIORITY_CLASS*/,NULL,NULL,&startupInfo,&processInfo))
{
return false;
}
CloseHandle (processInfo.hThread);
//
关闭新创建的主线程句柄
CloseHandle (processInfo.hProcess);
//
关闭新创建的进程句柄
//TerminateProcess( processInfo.hProcess,0 );
//WaitForSingleObject( processInfo.hProcess, INFINITE);//
一直等待新创建的进程结束
return 0;
}
使用方法
(1)
编译生成CloseDosWin.exe
(2)将CloseDosWin.exe放入Together安装目录
(3)单击鼠标右键打开桌面(和或开始菜单程序)的TogetherArchhitect图标的属性
(4)将属性->目标项中的“.../TogetherArchitect.bat”替换成“.../CloseDosWin.exe”
可执行文件下载