2024-05-21 16:55:15 +02:00
|
|
|
|
#include "pch.h"
|
|
|
|
|
|
|
2024-07-18 17:11:51 +02:00
|
|
|
|
#include <ProjectsLib/ProjectsData.h>
|
2024-05-21 16:55:15 +02:00
|
|
|
|
|
2024-06-12 19:31:43 +02:00
|
|
|
|
#include <AppLauncher.h>
|
2024-05-21 16:55:15 +02:00
|
|
|
|
|
2024-07-25 15:17:02 +02:00
|
|
|
|
#include <Generated Files/resource.h>
|
|
|
|
|
|
|
2024-07-22 20:37:49 +02:00
|
|
|
|
#include <common/utils/elevation.h>
|
2024-06-13 23:07:43 +02:00
|
|
|
|
#include <common/utils/gpo.h>
|
2024-06-12 21:45:39 +02:00
|
|
|
|
#include <common/utils/logger_helper.h>
|
2024-07-22 20:37:49 +02:00
|
|
|
|
#include <common/utils/process_path.h>
|
2024-06-12 21:45:39 +02:00
|
|
|
|
#include <common/utils/UnhandledExceptionHandler.h>
|
2024-07-25 15:17:02 +02:00
|
|
|
|
#include <common/utils/resources.h>
|
2024-06-12 21:45:39 +02:00
|
|
|
|
|
|
|
|
|
|
const std::wstring moduleName = L"Projects\\ProjectsLauncher";
|
|
|
|
|
|
const std::wstring internalPath = L"";
|
|
|
|
|
|
|
2024-06-13 12:34:08 +02:00
|
|
|
|
int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, LPSTR cmdline, int cmdShow)
|
2024-05-21 16:55:15 +02:00
|
|
|
|
{
|
2024-06-12 21:45:39 +02:00
|
|
|
|
LoggerHelpers::init_logger(moduleName, internalPath, LogSettings::projectsLauncherLoggerName);
|
|
|
|
|
|
InitUnhandledExceptionHandler();
|
|
|
|
|
|
|
2024-06-13 23:07:43 +02:00
|
|
|
|
if (powertoys_gpo::getConfiguredProjectsEnabledValue() == powertoys_gpo::gpo_rule_configured_disabled)
|
|
|
|
|
|
{
|
|
|
|
|
|
Logger::warn(L"Tried to start with a GPO policy setting the utility to always be disabled. Please contact your systems administrator.");
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-07-22 20:37:49 +02:00
|
|
|
|
if (is_process_elevated())
|
|
|
|
|
|
{
|
|
|
|
|
|
Logger::warn("Projects Launcher is elevated, restart");
|
|
|
|
|
|
|
|
|
|
|
|
constexpr DWORD exe_path_size = 0xFFFF;
|
|
|
|
|
|
auto exe_path = std::make_unique<wchar_t[]>(exe_path_size);
|
|
|
|
|
|
GetModuleFileNameW(nullptr, exe_path.get(), exe_path_size);
|
|
|
|
|
|
|
|
|
|
|
|
const auto modulePath = get_module_folderpath();
|
|
|
|
|
|
|
|
|
|
|
|
std::string cmdLineStr(cmdline);
|
|
|
|
|
|
std::wstring cmdLineWStr(cmdLineStr.begin(), cmdLineStr.end());
|
|
|
|
|
|
|
|
|
|
|
|
run_non_elevated(exe_path.get(), cmdLineWStr, nullptr, modulePath.c_str());
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-07-17 17:32:14 +02:00
|
|
|
|
// COM should be initialized before ShellExecuteEx is called.
|
2024-07-22 20:37:49 +02:00
|
|
|
|
if (FAILED(CoInitializeEx(NULL, COINIT_MULTITHREADED)))
|
2024-07-17 17:32:14 +02:00
|
|
|
|
{
|
|
|
|
|
|
Logger::error("CoInitializeEx failed");
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-06-23 23:15:06 +02:00
|
|
|
|
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
|
2024-07-22 20:37:49 +02:00
|
|
|
|
|
2024-05-21 16:55:15 +02:00
|
|
|
|
// read projects
|
2024-07-22 20:37:49 +02:00
|
|
|
|
auto projectsFileName = ProjectsData::ProjectsFile();
|
2024-07-18 17:11:51 +02:00
|
|
|
|
std::vector<ProjectsData::Project> projects;
|
2024-05-21 16:55:15 +02:00
|
|
|
|
try
|
|
|
|
|
|
{
|
2024-07-22 20:37:49 +02:00
|
|
|
|
auto savedProjectsJson = json::from_file(projectsFileName);
|
2024-05-21 16:55:15 +02:00
|
|
|
|
if (savedProjectsJson.has_value())
|
|
|
|
|
|
{
|
2024-07-18 17:11:51 +02:00
|
|
|
|
auto savedProjects = ProjectsData::ProjectsListJSON::FromJson(savedProjectsJson.value());
|
2024-05-21 16:55:15 +02:00
|
|
|
|
if (savedProjects.has_value())
|
|
|
|
|
|
{
|
|
|
|
|
|
projects = savedProjects.value();
|
|
|
|
|
|
}
|
2024-07-18 17:11:51 +02:00
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
Logger::critical("Incorrect Projects file");
|
2024-07-25 15:17:02 +02:00
|
|
|
|
std::wstring formattedMessage = fmt::format(GET_RESOURCE_STRING(IDS_INCORRECT_FILE_ERROR), L"projects.json");
|
|
|
|
|
|
MessageBox(NULL, formattedMessage.c_str(), GET_RESOURCE_STRING(IDS_PROJECTS).c_str(), MB_ICONERROR | MB_OK);
|
2024-07-18 17:11:51 +02:00
|
|
|
|
return 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
Logger::critical("Incorrect Projects file");
|
2024-07-25 15:17:02 +02:00
|
|
|
|
std::wstring formattedMessage = fmt::format(GET_RESOURCE_STRING(IDS_INCORRECT_FILE_ERROR), L"projects.json");
|
|
|
|
|
|
MessageBox(NULL, formattedMessage.c_str(), GET_RESOURCE_STRING(IDS_PROJECTS).c_str(), MB_ICONERROR | MB_OK);
|
2024-07-18 17:11:51 +02:00
|
|
|
|
return 1;
|
2024-05-21 16:55:15 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-06-12 21:45:39 +02:00
|
|
|
|
catch (std::exception ex)
|
2024-05-21 16:55:15 +02:00
|
|
|
|
{
|
2024-07-25 15:17:02 +02:00
|
|
|
|
Logger::critical("Exception on reading projects: {}", ex.what());
|
|
|
|
|
|
std::wstring formattedMessage = fmt::format(GET_RESOURCE_STRING(IDS_FILE_READING_ERROR), L"projects.json");
|
|
|
|
|
|
MessageBox(NULL, formattedMessage.c_str(), GET_RESOURCE_STRING(IDS_PROJECTS).c_str(), MB_ICONERROR | MB_OK);
|
2024-05-21 16:55:15 +02:00
|
|
|
|
return 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (projects.empty())
|
|
|
|
|
|
{
|
2024-06-12 21:45:39 +02:00
|
|
|
|
Logger::warn("Projects file is empty");
|
2024-07-25 15:17:02 +02:00
|
|
|
|
std::wstring formattedMessage = fmt::format(GET_RESOURCE_STRING(IDS_EMPTY_FILE), L"projects.json");
|
|
|
|
|
|
MessageBox(NULL, formattedMessage.c_str(), GET_RESOURCE_STRING(IDS_PROJECTS).c_str(), MB_ICONERROR | MB_OK);
|
2024-05-21 16:55:15 +02:00
|
|
|
|
return 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-07-18 17:11:51 +02:00
|
|
|
|
ProjectsData::Project projectToLaunch{};
|
2024-06-12 21:45:39 +02:00
|
|
|
|
std::string idStr(cmdline);
|
|
|
|
|
|
std::wstring id(idStr.begin(), idStr.end());
|
|
|
|
|
|
if (!id.empty())
|
2024-05-21 16:55:15 +02:00
|
|
|
|
{
|
|
|
|
|
|
for (const auto& proj : projects)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (proj.id == id)
|
|
|
|
|
|
{
|
|
|
|
|
|
projectToLaunch = proj;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-06-20 12:50:14 +02:00
|
|
|
|
if (projectToLaunch.id.empty())
|
|
|
|
|
|
{
|
2024-07-25 15:17:02 +02:00
|
|
|
|
Logger::critical(L"Project {} not found", id);
|
|
|
|
|
|
std::wstring formattedMessage = fmt::format(GET_RESOURCE_STRING(IDS_PROJECT_NOT_FOUND), id);
|
|
|
|
|
|
MessageBox(NULL, formattedMessage.c_str(), GET_RESOURCE_STRING(IDS_PROJECTS).c_str(), MB_ICONERROR | MB_OK);
|
2024-06-20 12:50:14 +02:00
|
|
|
|
return 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-06-12 21:45:39 +02:00
|
|
|
|
Logger::info(L"Launch Project {} : {}", projectToLaunch.name, projectToLaunch.id);
|
|
|
|
|
|
|
2024-05-21 16:55:15 +02:00
|
|
|
|
// launch apps
|
2024-06-26 17:40:57 +02:00
|
|
|
|
projectToLaunch = Launch(projectToLaunch);
|
2024-06-11 15:43:42 +02:00
|
|
|
|
|
2024-05-21 16:55:15 +02:00
|
|
|
|
// update last-launched time
|
|
|
|
|
|
time_t launchedTime = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
|
|
|
|
|
|
projectToLaunch.lastLaunchedTime = launchedTime;
|
|
|
|
|
|
for (int i = 0; i < projects.size(); i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (projects[i].id == projectToLaunch.id)
|
|
|
|
|
|
{
|
|
|
|
|
|
projects[i] = projectToLaunch;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-07-22 20:37:49 +02:00
|
|
|
|
json::to_file(projectsFileName, ProjectsData::ProjectsListJSON::ToJson(projects));
|
2024-05-21 16:55:15 +02:00
|
|
|
|
|
2024-07-17 17:32:14 +02:00
|
|
|
|
CoUninitialize();
|
2024-05-21 16:55:15 +02:00
|
|
|
|
return 0;
|
|
|
|
|
|
}
|