2025-09-20 20:20:47 +05:30
# include <filesystem>
# include <fstream>
# include <chrono>
# include <format>
# include <QObject>
# include <QJsonDocument>
# include <QJsonObject>
# include <QJsonArray>
# include <iostream>
# include <sstream>
# include <QString>
# include <QCoreApplication>
# include <QProcess>
# include <unistd.h>
char * get_current_time ( ) {
const auto now = std : : chrono : : system_clock : : now ( ) ;
const std : : time_t t_c = std : : chrono : : system_clock : : to_time_t ( now ) ;
return std : : ctime ( & t_c ) ;
}
int main ( int argc , char * argv [ ] ) {
QCoreApplication app ( argc , argv ) ;
if ( ! std : : filesystem : : exists ( " /home/ud/logs/ " ) ) {
std : : filesystem : : create_directory ( " /home/ud/logs " ) ;
}
std : : fstream log_file ( " /home/ud/logs/StartUpRunner.log " , std : : fstream : : app ) ;
if ( ! log_file . is_open ( ) ) {
log_file . open ( " /home/ud/logs/StartUpRunner.log " , std : : fstream : : out ) ;
}
log_file < < " -------- Starting app: " < < get_current_time ( ) ;
log_file < < " Current path: " < < std : : filesystem : : current_path ( ) < < " \n " ;
if ( ! std : : filesystem : : exists ( " startup_apps.json " ) ) {
log_file < < " startup_apps.json not found exiting. \n " ;
log_file . flush ( ) ;
log_file . close ( ) ;
exit ( - 1 ) ;
}
std : : string data = " " ;
std : : string t_data = " " ;
std : : fstream json_file ;
json_file . open ( " startup_apps.json " , std : : fstream : : in ) ;
if ( ! json_file . is_open ( ) ) {
std : : cout < < " Why is the startup_apps.json file not open? " < < std : : endl ;
return - 1 ;
}
std : : stringstream test ;
test < < json_file . rdbuf ( ) ;
json_file . close ( ) ;
QByteArray arr_data = QByteArray : : fromStdString ( test . str ( ) ) ;
QJsonArray top = QJsonDocument : : fromJson ( arr_data ) . array ( ) ;
std : : vector < QProcess * > active_process_list ;
for ( auto i : top ) {
auto object = i . toObject ( ) ;
std : : string name = object [ " app_name " ] . toString ( ) . toStdString ( ) ;
std : : string args = " " ;
QStringList sargs ;
for ( auto k : object [ " app_args " ] . toArray ( ) ) {
args + = k . toString ( ) . toStdString ( ) ;
sargs < < k . toString ( ) ;
}
QString mode = object [ " mode " ] . toString ( " wait " ) ;
QString working_dir = object [ " working_dir " ] . toString ( " /home/ud/StartUpApps/ " ) ;
std : : string file_name = std : : filesystem : : path ( name ) . stem ( ) . string ( ) ;
std : : string log_file_name = std : : format ( " /home/ud/logs/{}.log " , file_name ) ;
bool create_log_file = object [ " create_log " ] . toBool ( ) ;
std : : string command ;
if ( create_log_file )
command = std : : format ( " {} {} > {} " , name , args , log_file_name ) ;
else
command = std : : format ( " {} {} " , name , args ) ;
2025-10-28 09:47:44 +05:30
log_file < < " Running: " < < command < < " with working dir: " < < working_dir . toStdString ( ) < < " \n " ;
2025-09-20 20:20:47 +05:30
QProcess * proc = new QProcess ( ) ;
2025-10-28 09:47:44 +05:30
QObject : : connect ( proc , & QProcess : : started , [ & , command , proc , working_dir ] ( ) {
log_file < < " Started process: " < < command < < " with pid: " < < QString : : number ( proc - > processId ( ) ) . toStdString ( ) < < " with working directory as: " < < working_dir . toStdString ( ) < < std : : endl ;
2025-09-20 20:20:47 +05:30
} ) ;
if ( mode = = " wait " ) {
QObject : : connect ( proc , & QProcess : : finished , [ & , command , proc ] ( int exitcode , QProcess : : ExitStatus status ) {
auto process = proc ;
if ( status = = QProcess : : NormalExit )
log_file < < " Process: " < < command < < " with pid: " < < QString : : number ( proc - > processId ( ) ) . toStdString ( ) < < std : : endl < < " exited with exit code: " < < exitcode < < std : : endl ;
else
log_file < < " Process: " < < command < < " with pid: " < < QString : : number ( proc - > processId ( ) ) . toStdString ( ) < < std : : endl < < " CRASHED with exit code: " < < exitcode < < std : : endl ;
auto it = std : : find ( active_process_list . begin ( ) , active_process_list . end ( ) , process ) ;
active_process_list . erase ( it ) ;
if ( active_process_list . size ( ) = = 0 ) {
log_file < < " -------- All processes finished. " < < std : : endl ;
log_file . flush ( ) ;
log_file . close ( ) ;
app . exit ( 0 ) ;
}
} ) ;
active_process_list . push_back ( proc ) ;
}
if ( ! working_dir . isEmpty ( ) )
2025-10-28 09:47:44 +05:30
proc - > setWorkingDirectory ( working_dir ) ;
2025-09-20 20:20:47 +05:30
proc - > setStandardOutputFile ( QString : : fromStdString ( log_file_name ) ) ;
proc - > setProgram ( QString : : fromStdString ( name ) ) ;
proc - > setArguments ( sargs ) ;
if ( mode = = " wait " )
proc - > start ( QString : : fromStdString ( name ) , sargs ) ;
else
proc - > startDetached ( QString : : fromStdString ( name ) , sargs ) ;
}
return app . exec ( ) ;
}