如何解决NSIS安装脚本启动C++ GUI应用时仅作为后台进程运行不显示界面的问题
如何解决NSIS安装脚本启动C++ GUI应用时仅作为后台进程运行不显示界面的问题
嘿,我来帮你搞定这个头疼的问题!你的NSIS脚本启动自己的C++ GUI程序时,程序只在任务管理器的后台进程里躺着,就是不弹窗口,但记事本和画图却正常运行,这主要是两个关键问题导致的,咱们一步步来修复:
一、先搞定C++程序的窗口显示逻辑
你的C++程序创建了窗口,但压根没告诉系统要把它显示出来!而且还有个小坑:全局变量hInstance的赋值写错了,导致后续的窗口相关操作可能出问题。
打开你的C++代码里的InitInstance函数,改成这样:
BOOL InitInstance(HINSTANCE hInst, int nCmdShow) { // 这里要给全局变量hInstance赋值,之前的写法是参数自己赋值给自己,等于没写! ::hInstance = hInst; HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInst, nullptr); if (!hWnd) { return FALSE; } // 必须添加这两行!CreateWindow只是创建了窗口对象,要调用ShowWindow才会让它显示在屏幕上 ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); // 强制刷新窗口,确保内容显示 return TRUE; }
解释下:
::hInstance = hInst;:因为你全局变量的名字和函数参数名都是hInstance,直接写hInstance = hInstance只会修改参数的值,不会影响全局变量,所以要用::指定全局命名空间。ShowWindow(hWnd, nCmdShow):这是核心!把创建好的窗口按照系统传递的参数(比如正常显示、最大化等)显示出来。UpdateWindow(hWnd):强制触发一次窗口绘制,避免窗口显示后内容为空。
二、修正NSIS脚本的启动时机
你的NSIS脚本犯了一个顺序错误:在.onInit阶段就启动程序,但此时程序文件还没被复制到$TEMP目录!
.onInit是安装程序的初始化阶段,这个阶段早于Section的执行,而你是在Section里才把${TARGET_NAME}.exe复制到$TEMP的,所以你之前启动的要么是$TEMP里残留的旧文件,要么根本启动失败(但任务管理器里的后台进程可能是旧残留)。
把启动程序的代码移到Section的末尾,确保文件复制完成后再启动:
ManifestDPIAware true OutFile "setup.exe" !include MUI2.nsh RequestExecutionLevel admin !define TARGET_NAME "1_Test" !define MUI_WELCOMEPAGE_TITLE "Warcraft II for Windows 10" !define MUI_WELCOMEPAGE_TEXT "Ready to work!$\r$\n$\r$\nWith just a few simple steps, our peons will have you ready to play Warcraft II on Windows 10." !insertmacro MUI_PAGE_WELCOME !insertmacro MUI_LANGUAGE "English" !insertmacro MUI_LANGUAGE "Russian" Function .onInit InitPluginsDir !insertmacro MUI_LANGDLL_DISPLAY FunctionEnd Section SetOutPath "$TEMP" ; 先把程序文件复制到目标目录 File "SetupBack\${TARGET_NAME}.exe" ; 现在文件已经存在,再启动所有程序 ExecShell "open" "$TEMP\${TARGET_NAME}.exe" ExecShell "open" "notepad.exe" ExecShell "open" "mspaint.exe" SectionEnd
如果你一定要在初始化阶段启动程序,那得先把文件复制到临时目录(比如PluginsDir),因为File命令只能在Section里用,你可以用CopyFiles或者把文件释放到$PluginsDir:
Function .onInit InitPluginsDir !insertmacro MUI_LANGDLL_DISPLAY ; 把程序复制到PluginsDir(NSIS的内置临时目录) CopyFiles "SetupBack\${TARGET_NAME}.exe" "$PluginsDir\" ; 启动程序 ExecShell "open" "$PluginsDir\${TARGET_NAME}.exe" ExecShell "open" "notepad.exe" ExecShell "open" "mspaint.exe" FunctionEnd Section ; 如果需要把程序保留在$TEMP,这里再复制一次,否则可以留空 ; SetOutPath "$TEMP" ; File "SetupBack\${TARGET_NAME}.exe" SectionEnd
最后测试
把修改后的C++程序重新编译,替换SetupBack里的文件,然后重新编译NSIS脚本,运行安装程序,你的GUI程序应该就能正常弹出窗口了!
内容来源于stack exchange
相关产品推荐
相关产品推荐

