From 6aa9bd0f77dcb5128167fae62e32aa5252fe85c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Mon, 2 Dec 2013 00:55:24 +0100 Subject: Renew the updater branch Now with some actual consensus on what the updater will do! --- mmc_updater/src/main.cpp | 201 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 mmc_updater/src/main.cpp (limited to 'mmc_updater/src/main.cpp') diff --git a/mmc_updater/src/main.cpp b/mmc_updater/src/main.cpp new file mode 100644 index 00000000..e23cf16d --- /dev/null +++ b/mmc_updater/src/main.cpp @@ -0,0 +1,201 @@ +#include "AppInfo.h" +#include "FileUtils.h" +#include "Log.h" +#include "Platform.h" +#include "ProcessUtils.h" +#include "StringUtils.h" +#include "UpdateScript.h" +#include "UpdaterOptions.h" + +#include + +#if defined(PLATFORM_LINUX) + #include "UpdateDialogGtkFactory.h" + #include "UpdateDialogAscii.h" +#endif + +#if defined(PLATFORM_MAC) + #include "MacBundle.h" + #include "UpdateDialogCocoa.h" +#endif + +#if defined(PLATFORM_WINDOWS) + #include "UpdateDialogWin32.h" +#endif + +#include +#include + +#define UPDATER_VERSION "0.16" + +UpdateDialog* createUpdateDialog(); + +void runUpdaterThread(void* arg) +{ +#ifdef PLATFORM_MAC + // create an autorelease pool to free any temporary objects + // created by Cocoa whilst handling notifications from the UpdateInstaller + void* pool = UpdateDialogCocoa::createAutoreleasePool(); +#endif + + try + { + UpdateInstaller* installer = static_cast(arg); + installer->run(); + } + catch (const std::exception& ex) + { + LOG(Error,"Unexpected exception " + std::string(ex.what())); + } + +#ifdef PLATFORM_MAC + UpdateDialogCocoa::releaseAutoreleasePool(pool); +#endif +} + +#ifdef PLATFORM_MAC +extern unsigned char Info_plist[]; +extern unsigned int Info_plist_len; + +extern unsigned char mac_icns[]; +extern unsigned int mac_icns_len; + +bool unpackBundle(int argc, char** argv) +{ + MacBundle bundle(FileUtils::tempPath(),AppInfo::name()); + std::string currentExePath = ProcessUtils::currentProcessPath(); + + if (currentExePath.find(bundle.bundlePath()) != std::string::npos) + { + // already running from a bundle + return false; + } + LOG(Info,"Creating bundle " + bundle.bundlePath()); + + // create a Mac app bundle + std::string plistContent(reinterpret_cast(Info_plist),Info_plist_len); + std::string iconContent(reinterpret_cast(mac_icns),mac_icns_len); + bundle.create(plistContent,iconContent,ProcessUtils::currentProcessPath()); + + std::list args; + for (int i = 1; i < argc; i++) + { + args.push_back(argv[i]); + } + ProcessUtils::runSync(bundle.executablePath(),args); + return true; +} +#endif + +void setupConsole() +{ +#ifdef PLATFORM_WINDOWS + // see http://stackoverflow.com/questions/587767/how-to-output-to-console-in-c-windows + // and http://www.libsdl.org/cgi/docwiki.cgi/FAQ_Console + AttachConsole(ATTACH_PARENT_PROCESS); + freopen( "CON", "w", stdout ); + freopen( "CON", "w", stderr ); +#endif +} + +int main(int argc, char** argv) +{ +#ifdef PLATFORM_MAC + void* pool = UpdateDialogCocoa::createAutoreleasePool(); +#endif + + Log::instance()->open(AppInfo::logFilePath()); + +#ifdef PLATFORM_MAC + // when the updater is run for the first time, create a Mac app bundle + // and re-launch the application from the bundle. This permits + // setting up bundle properties (such as application icon) + if (unpackBundle(argc,argv)) + { + return 0; + } +#endif + + UpdaterOptions options; + options.parse(argc,argv); + if (options.showVersion) + { + setupConsole(); + std::cout << "Update installer version " << UPDATER_VERSION << std::endl; + return 0; + } + + UpdateInstaller installer; + UpdateScript script; + + if (!options.scriptPath.empty()) + { + script.parse(FileUtils::makeAbsolute(options.scriptPath.c_str(),options.packageDir.c_str())); + } + + LOG(Info,"started updater. install-dir: " + options.installDir + + ", package-dir: " + options.packageDir + + ", wait-pid: " + intToStr(options.waitPid) + + ", script-path: " + options.scriptPath + + ", mode: " + intToStr(options.mode)); + + installer.setMode(options.mode); + installer.setInstallDir(options.installDir); + installer.setPackageDir(options.packageDir); + installer.setScript(&script); + installer.setWaitPid(options.waitPid); + installer.setForceElevated(options.forceElevated); + installer.setAutoClose(options.autoClose); + + if (options.mode == UpdateInstaller::Main) + { + LOG(Info, "Showing updater UI - auto close? " + intToStr(options.autoClose)); + std::auto_ptr dialog(createUpdateDialog()); + dialog->setAutoClose(options.autoClose); + dialog->init(argc, argv); + installer.setObserver(dialog.get()); + std::thread updaterThread(runUpdaterThread, &installer); + dialog->exec(); + updaterThread.join(); + } + else + { + installer.run(); + } + +#ifdef PLATFORM_MAC + UpdateDialogCocoa::releaseAutoreleasePool(pool); +#endif + + return 0; +} + +UpdateDialog* createUpdateDialog() +{ +#if defined(PLATFORM_WINDOWS) + return new UpdateDialogWin32(); +#elif defined(PLATFORM_MAC) + return new UpdateDialogCocoa(); +#elif defined(PLATFORM_LINUX) + UpdateDialog* dialog = UpdateDialogGtkFactory::createDialog(); + if (!dialog) + { + dialog = new UpdateDialogAscii(); + } + return dialog; +#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); +} +#endif -- cgit v1.2.3 From e90f1a27569ac6b9e9782646c9de92fc9534b1d2 Mon Sep 17 00:00:00 2001 From: Andrew Date: Thu, 5 Dec 2013 20:32:12 -0600 Subject: Implement update installer --- mmc_updater/src/main.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'mmc_updater/src/main.cpp') diff --git a/mmc_updater/src/main.cpp b/mmc_updater/src/main.cpp index e23cf16d..fb072ab5 100644 --- a/mmc_updater/src/main.cpp +++ b/mmc_updater/src/main.cpp @@ -137,7 +137,8 @@ int main(int argc, char** argv) + ", package-dir: " + options.packageDir + ", wait-pid: " + intToStr(options.waitPid) + ", script-path: " + options.scriptPath - + ", mode: " + intToStr(options.mode)); + + ", mode: " + intToStr(options.mode) + + ", finish-cmd: " + options.finishCmd); installer.setMode(options.mode); installer.setInstallDir(options.installDir); @@ -146,6 +147,7 @@ int main(int argc, char** argv) installer.setWaitPid(options.waitPid); installer.setForceElevated(options.forceElevated); installer.setAutoClose(options.autoClose); + installer.setFinishCmd(options.finishCmd); if (options.mode == UpdateInstaller::Main) { -- cgit v1.2.3