Make updater.exe a WIN32 GUI application instead of a console application on Windows

* Add WIN32 flag to add_executable() so that cmake generates a GUI application
 * Add WinMain() entry point which converts the unicode command line arguments to ANSI and then calls the standard main() entry point.

 The unit test continues to pass although I am not sure whether
 converting command-line args from Unicode to ANSI will cause problems
 with filenames passed on the command-line that contain non-ANSI
 characters.
This commit is contained in:
Robert Knight 2011-08-24 16:11:53 +01:00
parent bae300a6a7
commit 04c9c7204b
4 changed files with 60 additions and 3 deletions

View file

@ -82,9 +82,11 @@ if (UNIX)
target_link_libraries(updatershared pthread)
endif()
add_executable(updater
main.cpp
)
if (WIN32)
set(EXE_FLAGS WIN32)
endif()
add_executable(updater ${EXE_FLAGS} main.cpp)
if(APPLE)
set_target_properties(

View file

@ -401,4 +401,40 @@ std::string ProcessUtils::currentProcessPath()
return fileName;
#endif
}
void ProcessUtils::convertWindowsCommandLine(LPCWSTR commandLine, int& argc, char**& argv)
{
argc = 0;
LPWSTR* argvUnicode = CommandLineToArgvW(commandLine,&argc);
argv = new char*[argc];
for (int i=0; i < argc; i++)
{
const int BUFFER_SIZE = 4096;
char buffer[BUFFER_SIZE];
int length = WideCharToMultiByte(CP_ACP,
0 /* flags */,
argvUnicode[i],
-1, /* argvUnicode is null terminated*/
buffer,
BUFFER_SIZE,
0,
false);
// note: if WideCharToMultiByte() fails it will return zero,
// in which case we store a zero-length argument in argv
if (length == 0)
{
argv[i] = new char[1];
argv[i][0] = '\0';
}
else
{
// if the input string to WideCharToMultiByte is null-terminated,
// the output is also null-terminated
argv[i] = new char[length];
strncpy(argv[i],buffer,length);
}
}
LocalFree(argvUnicode);
}

View file

@ -23,6 +23,12 @@ class ProcessUtils
static bool waitForProcess(PLATFORM_PID pid);
/** Convert a unicode command line returned by GetCommandLineW()
* to a standard (argc,argv) pair. The resulting argv array and each
* element of argv must be freed using free()
*/
static void convertWindowsCommandLine(LPCWSTR commandLine, int& argc, char**& argv);
private:
static void runElevatedLinux(const std::string& executable,
const std::list<std::string>& args);

View file

@ -1,5 +1,6 @@
#include "Log.h"
#include "Platform.h"
#include "ProcessUtils.h"
#include "StringUtils.h"
#include "UpdateScript.h"
#include "UpdaterOptions.h"
@ -120,6 +121,18 @@ void runWithUi(int argc, char** argv, UpdateInstaller* installer)
#endif
#ifdef PLATFORM_WINDOWS
// application entry point under Windows
int CALLBACK WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
int argc = 0;
char** argv;
ProcessUtils::convertWindowsCommandLine(GetCommandLineW(),argc,argv);
return main(argc,argv);
}
void runWithUi(int argc, char** argv, UpdateInstaller* installer)
{
UpdateDialogWin32 dialog;