Прошу рецензію на C++ код
Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті.
<p>Прошу переглянути нищенаведений код, який повинен працювати на<br/>
чистих Windows XP та Vista.</p>
<p>Ця програма (Launcher) призначена для запуску іншої програми (Target app).<br/>
Рішення про запуск приймається на основі наявності файлу autostart.<br/>
Якщо виникають проблеми при запуску — повідомити про це користувача та<br/>
записати в лог файл.</p>
<p>Launcher не повинен відкривати будь-яких власних вікон включаючи консольне, <br/>
UAC, compatibility або Windows Resource Protection, тощо.</p>
<p>Окреме питання про те, чи потрібна підтримка Unicode і як її реалізувати тоді? </p>
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#define STRICT
#include <windows.h>
#include <stdio.h>
#define LAUNCHER_NAME "GigatronLauncher"
#define AUTOSTART_FILEPATH "%APPDATA%\\Gigatron\\autostart"
#define TARGET_NAME "Gigatron"
#define TARGET_PARAMETER "autostart"
inline bool AutoStartEnabled();
bool LaunchTargetApplication();
int HandleLaunchResult( const bool );
// Entry point of launcher program
int APIENTRY WinMain( HINSTANCE, HINSTANCE, LPSTR, int ){
bool launchSucceed = true;
try{
const bool AUTOSTART_ENABLED = AutoStartEnabled();
if( AUTOSTART_ENABLED ){
launchSucceed = LaunchTargetApplication();
}
else{
// do nothing
}
}
catch(...){
launchSucceed = false;
// CloseHandle( pi.hProcess ); CloseHandle( pi.hThread );
}
HandleLaunchResult( launchSucceed );
}
/* Answers whether autostart of target application is enabled. */
bool AutoStartEnabled(){
// Expand autostart file path
LPSTR expandedPath = new CHAR[ MAX_PATH ];
// sprintf_s( autostartFilePath, MAX_PATH, "%APPDATA%\\%s\\%s", TARGET_NAME, AUTOSTART_FILENAME );
ExpandEnvironmentStrings( ( LPSTR )AUTOSTART_FILEPATH, expandedPath, MAX_PATH );
// Check if autostart file exists
OFSTRUCT openFileStructure = {0};
const HFILE FILE_HANDLE = OpenFile( expandedPath, &openFileStructure, OF_EXIST );
if( HFILE_ERROR != FILE_HANDLE ){
return true;
}
else{
return false;
}
}
/* Launches target application and returns true if succeed, false if failed. */
bool LaunchTargetApplication(){
// Define command line string
LPSTR commandLine = new CHAR[ MAX_PATH ];
sprintf_s( commandLine, MAX_PATH, "%s.exe %s", TARGET_NAME, TARGET_PARAMETER );//_tcscat();
// Prepare process creation data
PROCESS_INFORMATION processInfo = {0};
ZeroMemory( &processInfo, sizeof( processInfo ) );
STARTUPINFO startupInfo = {0};
ZeroMemory( &startupInfo, sizeof( startupInfo ) );
startupInfo.cb = sizeof( startupInfo );
// Start target application
const BOOL PROCESS_RESULT = CreateProcess( NULL, commandLine, NULL, NULL, FALSE, 0, NULL,
NULL, &startupInfo, &processInfo );
return ( 0 != PROCESS_RESULT );
}
/* Handles target application launch result. */
int HandleLaunchResult( const bool in_LaunchSucceed ){
const int LAST_ERROR_CODE = GetLastError();
if( in_LaunchSucceed ){
return 0;
}
else{
// Log system error message to file
HANDLE logFileHandle;
try{
// Get last error message
LPSTR systemErrorMessage;
FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, LAST_ERROR_CODE, 0, ( LPTSTR )&systemErrorMessage, 0, NULL );
// Create log file and write mesage into it
const LPSTR envPath = new CHAR[ MAX_PATH ];
sprintf_s( envPath, MAX_PATH, "%APPDATA%\\%s\\%s.log", TARGET_NAME, LAUNCHER_NAME );
const LPSTR logFilePath = new CHAR[ MAX_PATH ];
ExpandEnvironmentStrings( envPath, logFilePath, MAX_PATH );
logFileHandle = CreateFile( logFilePath, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL );
if( INVALID_HANDLE_VALUE != logFileHandle ){
DWORD numberOfBytesWritten;
WriteFile( logFileHandle, systemErrorMessage, ( DWORD )strlen( systemErrorMessage ),
&numberOfBytesWritten, NULL );
}
else{
// do nothing
}
}
catch(...){
// do nothing
}
if( INVALID_HANDLE_VALUE != logFileHandle ){
CloseHandle( logFileHandle );
}
else{
// do nothing
}
// Display user message
LPSTR userMessage = new CHAR[ MAX_PATH ];
sprintf_s( userMessage, MAX_PATH, "Problem starting %s.", TARGET_NAME );
MessageBox( NULL, userMessage, TARGET_NAME, MB_ICONERROR ); // TODO: add tech support button or adress.
return LAST_ERROR_CODE;
}
}
10 коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарів