我在 cmd 中啟動我的應用程式。我用 Cmake 編譯它WIN32_EXECUTABLE,所以它掛在 cmd 中(即以未分離的方式啟動)。現在我想關閉控制臺并嘗試通過呼叫FreeConsole().
這在我雙擊應用程式的情況下有效——黑色控制臺快速閃爍并關閉。但是當我在cmd中啟動它時它不起作用。該 cmd 仍然附加到啟動的應用程式并且FreeConsole()沒有幫助。
有沒有辦法以編程方式將其與 cmd 分離?我找到了運行的機會start /b myapp,但我想以編程方式進行。
更新
對于那些感興趣的人來說, Anders的答案的粗略實作——見下文。在這個實作中,我將提供給 main.com 的所有引數傳遞給子行程 main.exe。
// main.cpp
// cl main.cpp
// link main.obj /SUBSYSTEM:WINDOWS /ENTRY:"mainCRTStartup"
//
#include <stdio.h>
#include <Windows.h>
int main(int argc, char** argv)
{
if (AttachConsole(ATTACH_PARENT_PROCESS)) {
freopen("CONOUT$", "w", stdout);
freopen("CONOUT$", "w", stderr);
freopen("CONIN$", "r", stdin);
}
for (int i = 0; i < argc; i )
printf("--%s", argv[i]);
printf("Hello\n");
int k = 0;
scanf("%d", &k);
printf("%d\n", k);
return 0;
}
// helper.cpp
// cl helper.cpp
// link helper.obj /OUT:main.com
//
#include <windows.h>
#include <stdio.h>
#include <string.h>
void main( int argc, char **argv )
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
// Reconstructing the command line args for main.exe:
char cmdLine[32767] = { 0 };
strcpy(cmdLine, "main.exe ");
int shift = strlen("main.exe ");
for (int i = 1 ; i < argc; i )
{
strcpy(cmdLine shift, argv[i]);
const int argLength = strlen(argv[i]);
cmdLine[shift argLength] = ' ';
shift = (argLength 1);
}
printf("\n!!!!%s!!!!!%s\n", cmdLine, GetCommandLine());
// Start the child process.
// https://learn.microsoft.com/en-us/windows/win32/procthread/creating-processes
//
if( !CreateProcess(NULL, // No module name (use command line)
cmdLine, // Command line
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
0, // No creation flags
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&si, // Pointer to STARTUPINFO structure
&pi ) // Pointer to PROCESS_INFORMATION structure
)
{
printf( "CreateProcess failed (%d).\n", GetLastError() );
return;
}
// Wait until child process exits.
WaitForSingleObject( pi.hProcess, INFINITE );
// Close process and thread handles.
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
}
uj5u.com熱心網友回復:
在 Windows 上創建既可以是 GUI 也可以是控制臺的“完美”應用程式是不可能的。
當 .exe 將其子系統設定為控制臺時,會發生兩件事:
CreateProcess將其附加到父母控制臺。如果父級沒有,則會創建一個新控制臺。這只能通過將標志傳遞給來抑制CreateProcess。- cmd.exe 將等待行程完成。
將子系統設定為 Windows 并使用的技巧AttachConsole是次優的,因為 cmd.exe 不會等待。
最好的解決方案是將您的主 .exe 創建為 Windows 應用程式。創建另一個控制臺幫助應用程式,將其從 .exe 重命名為 .com。輔助應用程式只會在 GUI 模式下啟動主應用程式,然后退出。在控制臺模式下,它必須告訴主應用程式它需要附加并且您需要附加WaitForSingleObject它。此處提供示例應用程式。
Visual Studio 使用這個 .com 技巧。這個技巧很有效,因為 .com 列在 %pathext% 中的 .exe 之前。
uj5u.com熱心網友回復:
我可以為主應用程式和部分添加一些說明waitforsingleobject。上面的答案意味著主程式中的執行緒之間的合作。當 helper 呼叫CreateProcess一個 PROCESS_INFORMATION 填充了子行程的句柄時,將這個和 INFINITE 傳遞給WaitForSingleObject.我可以WaitForMultipleObjects用來撰寫一個示例以幫助您理解。
DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
...................
}
DWORD WINAPI ThreadProc2(LPVOID lpParameter)
{
....................
}
int main()
{
HANDLE hThread[2];
DWORD dWResult1;
DWORD dWResult2;
hThread[0] = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
hThread[1] = CreateThread(NULL, 0, ThreadProc2, NULL, 0, NULL);
WaitForMultipleObjects(2,hThread,true,INFINITE);
============================================
just a sample which stops and closes threads, here can call `AttachConsole` to replace the following code`
===========================================
GetExitCodeThread(hThread[0], &dWResult1);
GetExitCodeThread(hThread[1], &dWResult2);
printf("Thread execution completed \n");
getchar();
CloseHandle(hThread[0]);
CloseHandle(hThread[1]);
return 0;
}
然后你可以使用attachconsole你需要執行的代碼來替換我寫的程式來中止退出。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/515600.html
標籤:C 视窗温纳皮命令
