Win: Add launcher to hide the console window flash
This patch fixes a long-standing complaint from users: the console window shortly flashing when they start blender. This is done by adding a new executable called blender-launcher.exe which starts blender.exe while hiding the console. Any command line parameters given to blender-launcher will be passed on to blender.exe so it'll be a drop in replacement. Starting blender.exe on its own will still function as a proper console app so no changes required here for users that use blender for batch processing. Notable changes: Registering blender (-R switch) will now register blender-launcher as the preferred executable. This patch updates the installer and updates the shortcuts to start blender-launcher.exe rather than blender.exe Differential Revision: https://developer.blender.org/D11094 Reviewed by: brecht, harley
This commit is contained in:
parent
6fc9ec9257
commit
f3944cf503
|
@ -104,8 +104,8 @@ if(WIN32)
|
|||
set(CPACK_WIX_LIGHT_EXTRA_FLAGS -dcl:medium)
|
||||
endif()
|
||||
|
||||
set(CPACK_PACKAGE_EXECUTABLES "blender" "blender")
|
||||
set(CPACK_CREATE_DESKTOP_LINKS "blender" "blender")
|
||||
set(CPACK_PACKAGE_EXECUTABLES "blender-launcher" "blender")
|
||||
set(CPACK_CREATE_DESKTOP_LINKS "blender-launcher" "blender")
|
||||
|
||||
include(CPack)
|
||||
|
||||
|
|
|
@ -94,9 +94,9 @@ void BLI_windows_register_blend_extension(const bool background)
|
|||
GetModuleFileName(0, BlPath, MAX_PATH);
|
||||
|
||||
/* Replace the actual app name with the wrapper. */
|
||||
blender_app = strstr(BlPath, "blender-app.exe");
|
||||
blender_app = strstr(BlPath, "blender.exe");
|
||||
if (blender_app != NULL) {
|
||||
strcpy(blender_app, "blender.exe");
|
||||
strcpy(blender_app, "blender-launcher.exe");
|
||||
}
|
||||
|
||||
/* root is HKLM by default */
|
||||
|
|
|
@ -343,8 +343,13 @@ void WM_init(bContext *C, int argc, const char **argv)
|
|||
(void)argv; /* unused */
|
||||
#endif
|
||||
|
||||
if (!G.background && !wm_start_with_console) {
|
||||
GHOST_toggleConsole(3);
|
||||
if (!G.background) {
|
||||
if (wm_start_with_console) {
|
||||
GHOST_toggleConsole(1);
|
||||
}
|
||||
else {
|
||||
GHOST_toggleConsole(3);
|
||||
}
|
||||
}
|
||||
|
||||
BKE_material_copybuf_clear();
|
||||
|
|
|
@ -285,6 +285,15 @@ if(WITH_PYTHON_MODULE)
|
|||
|
||||
else()
|
||||
add_executable(blender ${EXETYPE} ${SRC})
|
||||
if(WIN32)
|
||||
add_executable(blender-launcher WIN32
|
||||
blender-launcher.c
|
||||
${CMAKE_SOURCE_DIR}/release/windows/icons/winblender.rc
|
||||
${CMAKE_BINARY_DIR}/blender.exe.manifest
|
||||
)
|
||||
target_compile_definitions (blender-launcher PRIVATE -D_UNICODE -DUNICODE)
|
||||
target_link_libraries(blender-launcher Pathcch.lib)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_BUILDINFO)
|
||||
|
@ -1212,7 +1221,7 @@ endif()
|
|||
|
||||
if(WIN32 AND NOT WITH_PYTHON_MODULE)
|
||||
install(
|
||||
TARGETS blender
|
||||
TARGETS blender blender-launcher
|
||||
COMPONENT Blender
|
||||
DESTINATION "."
|
||||
)
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <Windows.h>
|
||||
#include <strsafe.h>
|
||||
|
||||
#include <PathCch.h>
|
||||
|
||||
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
|
||||
{
|
||||
STARTUPINFO siStartInfo = {0};
|
||||
PROCESS_INFORMATION procInfo;
|
||||
wchar_t path[MAX_PATH];
|
||||
|
||||
siStartInfo.wShowWindow = SW_HIDE;
|
||||
siStartInfo.dwFlags = STARTF_USESHOWWINDOW;
|
||||
|
||||
/* Get the path to the currently running executable (blender-launcher.exe) */
|
||||
|
||||
DWORD nSize = GetModuleFileName(NULL, path, MAX_PATH);
|
||||
if (!nSize) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* GetModuleFileName returns the number of characters written, but GetLastError needs to be
|
||||
* called to see if it ran out of space or not. However where would we be without exceptions
|
||||
* to the rule: "If the buffer is too small to hold the module name, the function returns nSize.
|
||||
* The last error code remains ERROR_SUCCESS." - source: MSDN. */
|
||||
|
||||
if (GetLastError() == ERROR_SUCCESS && nSize == MAX_PATH) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Remove the filename (blender-launcher.exe) from path. */
|
||||
if (PathCchRemoveFileSpec(path, MAX_PATH) != S_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Add blender.exe to path, resulting in the full path to the blender executable. */
|
||||
if (PathCchCombine(path, MAX_PATH, path, L"blender.exe") != S_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int required_size_chars = lstrlenW(path) + /* Module name */
|
||||
3 + /* 2 quotes + Space */
|
||||
lstrlenW(pCmdLine) + /* Original command line */
|
||||
1; /* Zero terminator */
|
||||
size_t required_size_bytes = required_size_chars * sizeof(wchar_t);
|
||||
wchar_t *buffer = (wchar_t *)malloc(required_size_bytes);
|
||||
if (!buffer) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (StringCbPrintfEx(buffer,
|
||||
required_size_bytes,
|
||||
NULL,
|
||||
NULL,
|
||||
STRSAFE_NULL_ON_FAILURE,
|
||||
L"\"%s\" %s",
|
||||
path,
|
||||
pCmdLine) != S_OK) {
|
||||
free(buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
BOOL success = CreateProcess(
|
||||
path, buffer, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &siStartInfo, &procInfo);
|
||||
|
||||
if (success) {
|
||||
/* Handles in PROCESS_INFORMATION must be closed with CloseHandle when they are no longer
|
||||
* needed - MSDN. Closing the handles will NOT terminate the thread/process that we just
|
||||
* started. */
|
||||
CloseHandle(procInfo.hThread);
|
||||
CloseHandle(procInfo.hProcess);
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
return success ? 0 : -1;
|
||||
}
|
Loading…
Reference in New Issue