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”
可執行檔下載