int main( int argc, char ** argv ) { #if defined (FC_OS_LINUX) || defined(FC_OS_BSD) // Make sure to setup the Qt locale system before setting LANG and LC_ALL to C. // which is needed to use the system locale settings. (void)QLocale::system(); #if QT_VERSION < 0x050000 // http://www.freecadweb.org/tracker/view.php?id=399 // Because of setting LANG=C the Qt automagic to use the correct encoding // for file names is broken. This is a workaround to force the use of UTF-8 encoding QFile::setEncodingFunction(myEncoderFunc); QFile::setDecodingFunction(myDecoderFunc); #endif // See https://forum.freecadweb.org/viewtopic.php?f=18&t=20600 // See Gui::Application::runApplication() putenv("LC_NUMERIC=C"); putenv("PYTHONPATH="); #elif defined(FC_OS_MACOSX) (void)QLocale::system(); putenv("PYTHONPATH="); #else _putenv("PYTHONPATH="); // https://forum.freecadweb.org/viewtopic.php?f=4&t=18288 // https://forum.freecadweb.org/viewtopic.php?f=3&t=20515 const char* fc_py_home = getenv("FC_PYTHONHOME"); if (fc_py_home) _putenv_s("PYTHONHOME", fc_py_home); else _putenv("PYTHONHOME="); #endif #if defined (FC_OS_WIN32) int argc_ = argc; QVector<QByteArray> data; QVector<char *> argv_; // get the command line arguments as unicode string { QCoreApplication app(argc, argv); QStringList args = app.arguments(); for (QStringList::iterator it = args.begin(); it != args.end(); ++it) { data.push_back(it->toUtf8()); argv_.push_back(data.back().data()); } argv_.push_back(0); // 0-terminated string } #endif #if PY_MAJOR_VERSION >= 3 #if defined(_MSC_VER) && _MSC_VER <= 1800 // See InterpreterSingleton::init Redirection out(stdout), err(stderr), inp(stdin); #endif #endif // PY_MAJOR_VERSION // Name and Version of the Application App::Application::Config()["ExeName"] = "FreeCAD"; App::Application::Config()["ExeVendor"] = "FreeCAD"; App::Application::Config()["AppDataSkipVendor"] = "true"; App::Application::Config()["MaintainerUrl"] = "http://www.freecadweb.org/wiki/Main_Page"; // set the banner (for logging and console) App::Application::Config()["CopyrightInfo"] = sBanner; App::Application::Config()["AppIcon"] = "freecad"; App::Application::Config()["SplashScreen"] = "freecadsplash"; App::Application::Config()["StartWorkbench"] = "StartWorkbench"; //App::Application::Config()["HiddenDockWindow"] = "Property editor"; App::Application::Config()["SplashAlignment" ] = "Bottom|Left"; App::Application::Config()["SplashTextColor" ] = "#ffffff"; // white App::Application::Config()["SplashInfoColor" ] = "#c8c8c8"; // light grey try { // Init phase =========================================================== // sets the default run mode for FC, starts with gui if not overridden in InitConfig... App::Application::Config()["RunMode"] = "Gui"; App::Application::Config()["Console"] = "0"; // Inits the Application #if defined (FC_OS_WIN32) App::Application::init(argc_, argv_.data()); #else App::Application::init(argc, argv); #endif #if defined(_MSC_VER) // create a dump file when the application crashes std::string dmpfile = App::Application::getUserAppDataDir(); dmpfile += "crash.dmp"; InitMiniDumpWriter(dmpfile); #endif std::map<std::string, std::string>::iterator it = App::Application::Config().find("NavigationStyle"); if (it != App::Application::Config().end()) { ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View"); // if not already defined do it now (for the very first start) std::string style = hGrp->GetASCII("NavigationStyle", it->second.c_str()); hGrp->SetASCII("NavigationStyle", style.c_str()); } Gui::Application::initApplication(); // Only if 'RunMode' is set to 'Gui' do the replacement if (App::Application::Config()["RunMode"] == "Gui") Base::Interpreter().replaceStdOutput(); } catch (const Base::UnknownProgramOption& e) { QApplication app(argc,argv); QString appName = QString::fromLatin1(App::Application::Config()["ExeName"].c_str()); QString msg = QString::fromLatin1(e.what()); QString s = QLatin1String("<pre>") + msg + QLatin1String("</pre>"); QMessageBox::critical(0, appName, s); exit(1); } catch (const Base::ProgramInformation& e) { QApplication app(argc,argv); QString appName = QString::fromLatin1(App::Application::Config()["ExeName"].c_str()); QString msg = QString::fromUtf8(e.what()); QString s = QLatin1String("<pre>") + msg + QLatin1String("</pre>"); QMessageBox msgBox; msgBox.setIcon(QMessageBox::Information); msgBox.setWindowTitle(appName); msgBox.setDetailedText(msg); msgBox.setText(s); msgBox.exec(); exit(0); } catch (const Base::Exception& e) { // Popup an own dialog box instead of that one of Windows QApplication app(argc,argv); QString appName = QString::fromLatin1(App::Application::Config()["ExeName"].c_str()); QString msg; msg = QObject::tr("While initializing %1 the following exception occurred: '%2'\n\n" "Python is searching for its files in the following directories:\n%3\n\n" "Python version information:\n%4\n") .arg(appName).arg(QString::fromUtf8(e.what())) #if PY_MAJOR_VERSION >= 3 #if PY_MINOR_VERSION >= 5 .arg(QString::fromUtf8(Py_EncodeLocale(Py_GetPath(),NULL))).arg(QString::fromLatin1(Py_GetVersion())); #else .arg(QString::fromUtf8(_Py_wchar2char(Py_GetPath(),NULL))).arg(QString::fromLatin1(Py_GetVersion())); #endif #else .arg(QString::fromUtf8(Py_GetPath())).arg(QString::fromLatin1(Py_GetVersion()));
int main( int argc, char ** argv ) { #if defined (FC_OS_LINUX) || defined(FC_OS_BSD) // Make sure to setup the Qt locale system before setting LANG and LC_ALL to C. // which is needed to use the system locale settings. (void)QLocale::system(); // http://www.freecadweb.org/tracker/view.php?id=399 // Because of setting LANG=C the Qt automagic to use the correct encoding // for file names is broken. This is a workaround to force the use of UTF-8 encoding QFile::setEncodingFunction(myEncoderFunc); QFile::setDecodingFunction(myDecoderFunc); // Make sure that we use '.' as decimal point. See also // http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=559846 putenv("LC_NUMERIC=C"); putenv("PYTHONPATH="); #elif defined(FC_OS_MACOSX) (void)QLocale::system(); putenv("LC_NUMERIC=C"); putenv("PYTHONPATH="); #else setlocale(LC_NUMERIC, "C"); _putenv("PYTHONPATH="); #endif #if defined (FC_OS_WIN32) int argc_ = argc; QVector<QByteArray> data; QVector<char *> argv_; // get the command line arguments as unicode string { QCoreApplication app(argc, argv); QStringList args = app.arguments(); for (QStringList::iterator it = args.begin(); it != args.end(); ++it) { data.push_back(it->toUtf8()); argv_.push_back(data.back().data()); } argv_.push_back(0); // 0-terminated string } #endif // Name and Version of the Application App::Application::Config()["ExeName"] = "FreeCAD"; App::Application::Config()["ExeVendor"] = "FreeCAD"; App::Application::Config()["AppDataSkipVendor"] = "true"; App::Application::Config()["MaintainerUrl"] = "http://www.freecadweb.org/wiki/index.php?title=Main_Page"; // set the banner (for logging and console) App::Application::Config()["CopyrightInfo"] = sBanner; App::Application::Config()["AppIcon"] = "freecad"; App::Application::Config()["SplashScreen"] = "freecadsplash"; App::Application::Config()["StartWorkbench"] = "StartWorkbench"; //App::Application::Config()["HiddenDockWindow"] = "Property editor"; App::Application::Config()["SplashAlignment" ] = "Bottom|Left"; App::Application::Config()["SplashTextColor" ] = "#ffffff"; // white App::Application::Config()["SplashInfoColor" ] = "#c8c8c8"; // light grey try { // Init phase =========================================================== // sets the default run mode for FC, starts with gui if not overridden in InitConfig... App::Application::Config()["RunMode"] = "Gui"; // Inits the Application #if defined (FC_OS_WIN32) App::Application::init(argc_, argv_.data()); #else App::Application::init(argc, argv); #endif #if defined(_MSC_VER) // create a dump file when the application crashes std::string dmpfile = App::Application::getUserAppDataDir(); dmpfile += "crash.dmp"; InitMiniDumpWriter(dmpfile); #endif std::map<std::string, std::string>::iterator it = App::Application::Config().find("NavigationStyle"); if (it != App::Application::Config().end()) { ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View"); // if not already defined do it now (for the very first start) std::string style = hGrp->GetASCII("NavigationStyle", it->second.c_str()); hGrp->SetASCII("NavigationStyle", style.c_str()); } Gui::Application::initApplication(); // Only if 'RunMode' is set to 'Gui' do the replacement if (App::Application::Config()["RunMode"] == "Gui") Base::Interpreter().replaceStdOutput(); } catch (const Base::UnknownProgramOption& e) { QApplication app(argc,argv); QString appName = QString::fromAscii(App::Application::Config()["ExeName"].c_str()); QString msg = QString::fromAscii(e.what()); QString s = QLatin1String("<pre>") + msg + QLatin1String("</pre>"); QMessageBox::critical(0, appName, s); exit(1); } catch (const Base::ProgramInformation& e) { QApplication app(argc,argv); QString appName = QString::fromAscii(App::Application::Config()["ExeName"].c_str()); QString msg = QString::fromAscii(e.what()); QString s = QLatin1String("<pre>") + msg + QLatin1String("</pre>"); QMessageBox::information(0, appName, s); exit(0); } catch (const Base::Exception& e) { // Popup an own dialog box instead of that one of Windows QApplication app(argc,argv); QString appName = QString::fromAscii(App::Application::Config()["ExeName"].c_str()); QString msg; msg = QObject::tr("While initializing %1 the following exception occurred: '%2'\n\n" "Python is searching for its files in the following directories:\n%3\n\n" "Python version information:\n%4\n") .arg(appName).arg(QString::fromUtf8(e.what())) .arg(QString::fromUtf8(Py_GetPath())).arg(QString::fromAscii(Py_GetVersion())); const char* pythonhome = getenv("PYTHONHOME"); if (pythonhome) { msg += QObject::tr("\nThe environment variable PYTHONHOME is set to '%1'.") .arg(QString::fromUtf8(pythonhome)); msg += QObject::tr("\nSetting this environment variable might cause Python to fail. " "Please contact your administrator to unset it on your system.\n\n"); } else { msg += QObject::tr("\nPlease contact the application's support team for more information.\n\n"); } QMessageBox::critical(0, QObject::tr("Initialization of %1 failed").arg(appName), msg); exit(100); } catch (...) { // Popup an own dialog box instead of that one of Windows QApplication app(argc,argv); QString appName = QString::fromAscii(App::Application::Config()["ExeName"].c_str()); QString msg = QObject::tr("Unknown runtime error occurred while initializing %1.\n\n" "Please contact the application's support team for more information.\n\n").arg(appName); QMessageBox::critical(0, QObject::tr("Initialization of %1 failed").arg(appName), msg); exit(101); } // Run phase =========================================================== Base::RedirectStdOutput stdcout; Base::RedirectStdLog stdclog; Base::RedirectStdError stdcerr; std::streambuf* oldcout = std::cout.rdbuf(&stdcout); std::streambuf* oldclog = std::clog.rdbuf(&stdclog); std::streambuf* oldcerr = std::cerr.rdbuf(&stdcerr); try { if (App::Application::Config()["RunMode"] == "Gui") Gui::Application::runApplication(); else App::Application::runApplication(); } catch (const Base::SystemExitException&) { exit(0); } catch (const Base::Exception& e) { Base::Console().Error("%s\n", e.what()); } catch (...) { Base::Console().Error("Application unexpectedly terminated\n"); } std::cout.rdbuf(oldcout); std::clog.rdbuf(oldclog); std::cerr.rdbuf(oldcerr); // Destruction phase =========================================================== Base::Console().Log("%s terminating...\n",App::Application::Config()["ExeName"].c_str()); // cleans up App::Application::destruct(); Base::Console().Log("%s completely terminated\n",App::Application::Config()["ExeName"].c_str()); return 0; }
int prepare(QFileInfo f, QStringList paths) { if (paths.isEmpty()) { cout << "No -path args were passed :(\n"; return -1; } int lastVersion = 0; QString lastVersionStr; QFileInfo last; QFileInfoList l = f.absoluteDir().entryInfoList(QDir::Files); for (QFileInfoList::iterator i = l.begin(), e = l.end(); i != e; ++i) { QRegularExpressionMatch m = QRegularExpression("/tsetup.((\\d+).(\\d+).(\\d+)).exe$").match(i->absoluteFilePath()); if (!m.hasMatch()) continue; int version = m.captured(2).toInt() * 1000000 + m.captured(3).toInt() * 1000 + m.captured(4).toInt(); if (version > lastVersion) { lastVersion = version; lastVersionStr = m.captured(1); last = *i; } } if (!lastVersion) { cout << "No tsetup.X.Y.Z.exe found :(\n"; return -1; } cout << "Last version: " << lastVersionStr.toUtf8().constData() << " (" << lastVersion << "), executing packer..\n"; QDir dir("deploy/" + lastVersionStr); if (dir.exists()) { cout << "Version " << lastVersionStr.toUtf8().constData() << " already exists in /deploy..\n"; return -1; } QString packer = QString("Packer.exe -version %1").arg(lastVersion); for (QStringList::iterator i = paths.begin(), e = paths.end(); i != e; ++i) { packer += " -path " + *i; } int res = system(packer.toUtf8().constData()); if (res) return res; dir.mkpath("."); paths.push_back("Telegram.pdb"); paths.push_back("Updater.pdb"); paths.push_back("tsetup." + lastVersionStr + ".exe"); paths.push_back(QString("tupdate%1").arg(lastVersion)); for (QStringList::iterator i = paths.begin(), e = paths.end(); i != e; ++i) { if (!QFile::copy(*i, "deploy/" + lastVersionStr + "/" + *i)) { cout << "Could not copy " << i->toUtf8().constData() << " to deploy/" << lastVersionStr.toUtf8().constData() << "\n"; return -1; } cout << "Copied " << i->toUtf8().constData() << "..\n"; } for (QStringList::iterator i = paths.begin(), e = paths.end(); i != e; ++i) { QFile::remove(*i); } cout << "Update created in deploy/" << lastVersionStr.toUtf8().constData() << "\n"; return 0; }