From 6bb0f18d53a20970070c06449e6b4c8f61015243 Mon Sep 17 00:00:00 2001 From: Andrey Nekrasov Date: Mon, 13 Apr 2020 16:00:51 +0300 Subject: [PATCH] chore: format PowerToys custom actions (#2104) * chore: format PowerToys custom actions * add curly braces --- .../CustomAction.cpp | 856 ++++++++++-------- 1 file changed, 458 insertions(+), 398 deletions(-) diff --git a/installer/PowerToysSetupCustomActions/CustomAction.cpp b/installer/PowerToysSetupCustomActions/CustomAction.cpp index cf932f901b..a27a22581c 100644 --- a/installer/PowerToysSetupCustomActions/CustomAction.cpp +++ b/installer/PowerToysSetupCustomActions/CustomAction.cpp @@ -17,11 +17,11 @@ using namespace std; TRACELOGGING_DEFINE_PROVIDER( - g_hProvider, - "Microsoft.PowerToysInstaller", - // {e1d8165d-5cb6-5c74-3b51-bdfbfe4f7a3b} - (0xe1d8165d, 0x5cb6, 0x5c74, 0x3b, 0x51, 0xbd, 0xfb, 0xfe, 0x4f, 0x7a, 0x3b), - TraceLoggingOptionProjectTelemetry()); + g_hProvider, + "Microsoft.PowerToysInstaller", + // {e1d8165d-5cb6-5c74-3b51-bdfbfe4f7a3b} + (0xe1d8165d, 0x5cb6, 0x5c74, 0x3b, 0x51, 0xbd, 0xfb, 0xfe, 0x4f, 0x7a, 0x3b), + TraceLoggingOptionProjectTelemetry()); const DWORD USERNAME_DOMAIN_LEN = DNLEN + UNLEN + 2; // Domain Name + '\' + User Name + '\0' const DWORD USERNAME_LEN = UNLEN + 1; // User Name + '\0' @@ -30,502 +30,562 @@ const DWORD USERNAME_LEN = UNLEN + 1; // User Name + '\0' // The path of the executable to run should be passed as the CustomActionData (Value). // Based on the Task Scheduler Logon Trigger Example: // https://docs.microsoft.com/en-us/windows/win32/taskschd/logon-trigger-example--c---/ -UINT __stdcall CreateScheduledTaskCA(MSIHANDLE hInstall) { - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; +UINT __stdcall CreateScheduledTaskCA(MSIHANDLE hInstall) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; - TCHAR username_domain[USERNAME_DOMAIN_LEN]; - TCHAR username[USERNAME_LEN]; + TCHAR username_domain[USERNAME_DOMAIN_LEN]; + TCHAR username[USERNAME_LEN]; - std::wstring wstrTaskName; + std::wstring wstrTaskName; - ITaskService *pService = NULL; - ITaskFolder *pTaskFolder = NULL; - ITaskDefinition *pTask = NULL; - IRegistrationInfo *pRegInfo = NULL; - ITaskSettings *pSettings = NULL; - ITriggerCollection *pTriggerCollection = NULL; - IRegisteredTask *pRegisteredTask = NULL; + ITaskService* pService = NULL; + ITaskFolder* pTaskFolder = NULL; + ITaskDefinition* pTask = NULL; + IRegistrationInfo* pRegInfo = NULL; + ITaskSettings* pSettings = NULL; + ITriggerCollection* pTriggerCollection = NULL; + IRegisteredTask* pRegisteredTask = NULL; - hr = WcaInitialize(hInstall, "CreateScheduledTaskCA"); - ExitOnFailure(hr, "Failed to initialize"); + hr = WcaInitialize(hInstall, "CreateScheduledTaskCA"); + ExitOnFailure(hr, "Failed to initialize"); - WcaLog(LOGMSG_STANDARD, "Initialized."); + WcaLog(LOGMSG_STANDARD, "Initialized."); - // ------------------------------------------------------ - // Get the Domain/Username for the trigger. - // - // This action needs to run as the system to get elevated privileges from the installation, - // so GetUserNameEx can't be used to get the current user details. - // The USERNAME and USERDOMAIN environment variables are used instead. - if (!GetEnvironmentVariable(L"USERNAME", username, USERNAME_LEN)) { - ExitWithLastError(hr, "Getting username failed: %x", hr); - } - if (!GetEnvironmentVariable(L"USERDOMAIN", username_domain, USERNAME_DOMAIN_LEN)) { - ExitWithLastError(hr, "Getting the user's domain failed: %x", hr); - } - wcscat_s(username_domain, L"\\"); - wcscat_s(username_domain, username); - - WcaLog(LOGMSG_STANDARD, "Current user detected: %ls", username_domain); - - // Task Name. - wstrTaskName = L"Autorun for "; - wstrTaskName += username; - - // Get the executable path passed to the custom action. - LPWSTR wszExecutablePath = NULL; - hr = WcaGetProperty(L"CustomActionData", &wszExecutablePath); - ExitOnFailure(hr, "Failed to get the executable path from CustomActionData."); - - // COM and Security Initialization is expected to have been done by the MSI. - // It couldn't be done in the DLL, anyway. - // ------------------------------------------------------ - // Create an instance of the Task Service. - hr = CoCreateInstance(CLSID_TaskScheduler, - NULL, - CLSCTX_INPROC_SERVER, - IID_ITaskService, - (void**)&pService); - ExitOnFailure(hr, "Failed to create an instance of ITaskService: %x", hr); - - // Connect to the task service. - hr = pService->Connect(_variant_t(), _variant_t(), - _variant_t(), _variant_t()); - ExitOnFailure(hr, "ITaskService::Connect failed: %x", hr); - - // ------------------------------------------------------ - // Get the PowerToys task folder. Creates it if it doesn't exist. - hr = pService->GetFolder(_bstr_t(L"\\PowerToys"), &pTaskFolder); - if (FAILED(hr)) { - // Folder doesn't exist. Get the Root folder and create the PowerToys subfolder. - ITaskFolder *pRootFolder = NULL; - hr = pService->GetFolder(_bstr_t(L"\\"), &pRootFolder); - ExitOnFailure(hr, "Cannot get Root Folder pointer: %x", hr); - hr = pRootFolder->CreateFolder(_bstr_t(L"\\PowerToys"), _variant_t(L""), &pTaskFolder); - if (FAILED(hr)) { - pRootFolder->Release(); - ExitOnFailure(hr, "Cannot create PowerToys task folder: %x", hr); + // ------------------------------------------------------ + // Get the Domain/Username for the trigger. + // + // This action needs to run as the system to get elevated privileges from the installation, + // so GetUserNameEx can't be used to get the current user details. + // The USERNAME and USERDOMAIN environment variables are used instead. + if (!GetEnvironmentVariable(L"USERNAME", username, USERNAME_LEN)) + { + ExitWithLastError(hr, "Getting username failed: %x", hr); } - WcaLog(LOGMSG_STANDARD, "PowerToys task folder created."); - } + if (!GetEnvironmentVariable(L"USERDOMAIN", username_domain, USERNAME_DOMAIN_LEN)) + { + ExitWithLastError(hr, "Getting the user's domain failed: %x", hr); + } + wcscat_s(username_domain, L"\\"); + wcscat_s(username_domain, username); - // If the same task exists, remove it. - pTaskFolder->DeleteTask(_bstr_t(wstrTaskName.c_str()), 0); + WcaLog(LOGMSG_STANDARD, "Current user detected: %ls", username_domain); - // Create the task builder object to create the task. - hr = pService->NewTask(0, &pTask); - ExitOnFailure(hr, "Failed to create a task definition: %x", hr); + // Task Name. + wstrTaskName = L"Autorun for "; + wstrTaskName += username; - // ------------------------------------------------------ - // Get the registration info for setting the identification. - hr = pTask->get_RegistrationInfo(&pRegInfo); - ExitOnFailure(hr, "Cannot get identification pointer: %x", hr); - hr = pRegInfo->put_Author(_bstr_t(username_domain)); - ExitOnFailure(hr, "Cannot put identification info: %x", hr); + // Get the executable path passed to the custom action. + LPWSTR wszExecutablePath = NULL; + hr = WcaGetProperty(L"CustomActionData", &wszExecutablePath); + ExitOnFailure(hr, "Failed to get the executable path from CustomActionData."); - // ------------------------------------------------------ - // Create the settings for the task - hr = pTask->get_Settings(&pSettings); - ExitOnFailure(hr, "Cannot get settings pointer: %x", hr); + // COM and Security Initialization is expected to have been done by the MSI. + // It couldn't be done in the DLL, anyway. + // ------------------------------------------------------ + // Create an instance of the Task Service. + hr = CoCreateInstance(CLSID_TaskScheduler, + NULL, + CLSCTX_INPROC_SERVER, + IID_ITaskService, + (void**)&pService); + ExitOnFailure(hr, "Failed to create an instance of ITaskService: %x", hr); - hr = pSettings->put_StartWhenAvailable(VARIANT_FALSE); - ExitOnFailure(hr, "Cannot put_StartWhenAvailable setting info: %x", hr); - hr = pSettings->put_StopIfGoingOnBatteries(VARIANT_FALSE); - ExitOnFailure(hr, "Cannot put_StopIfGoingOnBatteries setting info: %x", hr); - hr = pSettings->put_ExecutionTimeLimit(_bstr_t(L"PT0S")); //Unlimited - ExitOnFailure(hr, "Cannot put_ExecutionTimeLimit setting info: %x", hr); - hr = pSettings->put_DisallowStartIfOnBatteries(VARIANT_FALSE); - ExitOnFailure(hr, "Cannot put_DisallowStartIfOnBatteries setting info: %x", hr); + // Connect to the task service. + hr = pService->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t()); + ExitOnFailure(hr, "ITaskService::Connect failed: %x", hr); - // ------------------------------------------------------ - // Get the trigger collection to insert the logon trigger. - hr = pTask->get_Triggers(&pTriggerCollection); - ExitOnFailure(hr, "Cannot get trigger collection: %x", hr); + // ------------------------------------------------------ + // Get the PowerToys task folder. Creates it if it doesn't exist. + hr = pService->GetFolder(_bstr_t(L"\\PowerToys"), &pTaskFolder); + if (FAILED(hr)) + { + // Folder doesn't exist. Get the Root folder and create the PowerToys subfolder. + ITaskFolder* pRootFolder = NULL; + hr = pService->GetFolder(_bstr_t(L"\\"), &pRootFolder); + ExitOnFailure(hr, "Cannot get Root Folder pointer: %x", hr); + hr = pRootFolder->CreateFolder(_bstr_t(L"\\PowerToys"), _variant_t(L""), &pTaskFolder); + if (FAILED(hr)) + { + pRootFolder->Release(); + ExitOnFailure(hr, "Cannot create PowerToys task folder: %x", hr); + } + WcaLog(LOGMSG_STANDARD, "PowerToys task folder created."); + } - // Add the logon trigger to the task. - ITrigger *pTrigger = NULL; - hr = pTriggerCollection->Create(TASK_TRIGGER_LOGON, &pTrigger); - ExitOnFailure(hr, "Cannot create the trigger: %x", hr); + // If the same task exists, remove it. + pTaskFolder->DeleteTask(_bstr_t(wstrTaskName.c_str()), 0); - ILogonTrigger *pLogonTrigger = NULL; - hr = pTrigger->QueryInterface( - IID_ILogonTrigger, (void**)&pLogonTrigger); - pTrigger->Release(); - ExitOnFailure(hr, "QueryInterface call failed for ILogonTrigger: %x", hr); + // Create the task builder object to create the task. + hr = pService->NewTask(0, &pTask); + ExitOnFailure(hr, "Failed to create a task definition: %x", hr); - hr = pLogonTrigger->put_Id(_bstr_t(L"Trigger1")); - if (FAILED(hr)) { - WcaLogError(hr, "Cannot put the trigger ID: %x", hr); - } + // ------------------------------------------------------ + // Get the registration info for setting the identification. + hr = pTask->get_RegistrationInfo(&pRegInfo); + ExitOnFailure(hr, "Cannot get identification pointer: %x", hr); + hr = pRegInfo->put_Author(_bstr_t(username_domain)); + ExitOnFailure(hr, "Cannot put identification info: %x", hr); - // Timing issues may make explorer not be started when the task runs. - // Add a little delay to mitigate this. - hr = pLogonTrigger->put_Delay(_bstr_t(L"PT03S")); - if (FAILED(hr)) { - WcaLogError(hr, "Cannot put the trigger delay: %x", hr); - } + // ------------------------------------------------------ + // Create the settings for the task + hr = pTask->get_Settings(&pSettings); + ExitOnFailure(hr, "Cannot get settings pointer: %x", hr); - // Define the user. The task will execute when the user logs on. - // The specified user must be a user on this computer. - hr = pLogonTrigger->put_UserId(_bstr_t(username_domain)); - pLogonTrigger->Release(); - ExitOnFailure(hr, "Cannot add user ID to logon trigger: %x", hr); + hr = pSettings->put_StartWhenAvailable(VARIANT_FALSE); + ExitOnFailure(hr, "Cannot put_StartWhenAvailable setting info: %x", hr); + hr = pSettings->put_StopIfGoingOnBatteries(VARIANT_FALSE); + ExitOnFailure(hr, "Cannot put_StopIfGoingOnBatteries setting info: %x", hr); + hr = pSettings->put_ExecutionTimeLimit(_bstr_t(L"PT0S")); //Unlimited + ExitOnFailure(hr, "Cannot put_ExecutionTimeLimit setting info: %x", hr); + hr = pSettings->put_DisallowStartIfOnBatteries(VARIANT_FALSE); + ExitOnFailure(hr, "Cannot put_DisallowStartIfOnBatteries setting info: %x", hr); - // ------------------------------------------------------ - // Add an Action to the task. This task will execute the path passed to this custom action. - IActionCollection *pActionCollection = NULL; + // ------------------------------------------------------ + // Get the trigger collection to insert the logon trigger. + hr = pTask->get_Triggers(&pTriggerCollection); + ExitOnFailure(hr, "Cannot get trigger collection: %x", hr); - // Get the task action collection pointer. - hr = pTask->get_Actions(&pActionCollection); - ExitOnFailure(hr, "Cannot get Task collection pointer: %x", hr); + // Add the logon trigger to the task. + ITrigger* pTrigger = NULL; + hr = pTriggerCollection->Create(TASK_TRIGGER_LOGON, &pTrigger); + ExitOnFailure(hr, "Cannot create the trigger: %x", hr); - // Create the action, specifying that it is an executable action. - IAction *pAction = NULL; - hr = pActionCollection->Create(TASK_ACTION_EXEC, &pAction); - pActionCollection->Release(); - ExitOnFailure(hr, "Cannot create the action: %x", hr); + ILogonTrigger* pLogonTrigger = NULL; + hr = pTrigger->QueryInterface( + IID_ILogonTrigger, (void**)&pLogonTrigger); + pTrigger->Release(); + ExitOnFailure(hr, "QueryInterface call failed for ILogonTrigger: %x", hr); - IExecAction *pExecAction = NULL; - // QI for the executable task pointer. - hr = pAction->QueryInterface( - IID_IExecAction, (void**)&pExecAction); - pAction->Release(); - ExitOnFailure(hr, "QueryInterface call failed for IExecAction: %x", hr); + hr = pLogonTrigger->put_Id(_bstr_t(L"Trigger1")); + if (FAILED(hr)) + { + WcaLogError(hr, "Cannot put the trigger ID: %x", hr); + } - // Set the path of the executable to PowerToys (passed as CustomActionData). - hr = pExecAction->put_Path(_bstr_t(wszExecutablePath)); - pExecAction->Release(); - ExitOnFailure(hr, "Cannot set path of executable: %x", hr); + // Timing issues may make explorer not be started when the task runs. + // Add a little delay to mitigate this. + hr = pLogonTrigger->put_Delay(_bstr_t(L"PT03S")); + if (FAILED(hr)) + { + WcaLogError(hr, "Cannot put the trigger delay: %x", hr); + } - // ------------------------------------------------------ - // Create the principal for the task - IPrincipal *pPrincipal = NULL; - hr = pTask->get_Principal(&pPrincipal); - ExitOnFailure(hr, "Cannot get principal pointer: %x", hr); + // Define the user. The task will execute when the user logs on. + // The specified user must be a user on this computer. + hr = pLogonTrigger->put_UserId(_bstr_t(username_domain)); + pLogonTrigger->Release(); + ExitOnFailure(hr, "Cannot add user ID to logon trigger: %x", hr); - // Set up principal information: - hr = pPrincipal->put_Id(_bstr_t(L"Principal1")); - if (FAILED(hr)) { - WcaLogError(hr, "Cannot put the principal ID: %x", hr); - } + // ------------------------------------------------------ + // Add an Action to the task. This task will execute the path passed to this custom action. + IActionCollection* pActionCollection = NULL; - hr = pPrincipal->put_UserId(_bstr_t(username_domain)); - if (FAILED(hr)) { - WcaLogError(hr, "Cannot put principal user Id: %x", hr); - } + // Get the task action collection pointer. + hr = pTask->get_Actions(&pActionCollection); + ExitOnFailure(hr, "Cannot get Task collection pointer: %x", hr); - hr = pPrincipal->put_LogonType(TASK_LOGON_INTERACTIVE_TOKEN); - if (FAILED(hr)) { - WcaLogError(hr, "Cannot put principal logon type: %x", hr); - } + // Create the action, specifying that it is an executable action. + IAction* pAction = NULL; + hr = pActionCollection->Create(TASK_ACTION_EXEC, &pAction); + pActionCollection->Release(); + ExitOnFailure(hr, "Cannot create the action: %x", hr); - // Run the task with the highest available privileges. - hr = pPrincipal->put_RunLevel(TASK_RUNLEVEL_LUA); - pPrincipal->Release(); - ExitOnFailure(hr, "Cannot put principal run level: %x", hr); + IExecAction* pExecAction = NULL; + // QI for the executable task pointer. + hr = pAction->QueryInterface( + IID_IExecAction, (void**)&pExecAction); + pAction->Release(); + ExitOnFailure(hr, "QueryInterface call failed for IExecAction: %x", hr); - // ------------------------------------------------------ - // Save the task in the PowerToys folder. - { - _variant_t SDDL_FULL_ACCESS_FOR_EVERYONE = L"D:(A;;FA;;;WD)"; - hr = pTaskFolder->RegisterTaskDefinition( - _bstr_t(wstrTaskName.c_str()), - pTask, - TASK_CREATE_OR_UPDATE, - _variant_t(username_domain), - _variant_t(), - TASK_LOGON_INTERACTIVE_TOKEN, - SDDL_FULL_ACCESS_FOR_EVERYONE, - &pRegisteredTask); - ExitOnFailure(hr, "Error saving the Task : %x", hr); - } + // Set the path of the executable to PowerToys (passed as CustomActionData). + hr = pExecAction->put_Path(_bstr_t(wszExecutablePath)); + pExecAction->Release(); + ExitOnFailure(hr, "Cannot set path of executable: %x", hr); - WcaLog(LOGMSG_STANDARD, "Scheduled task created for the current user."); + // ------------------------------------------------------ + // Create the principal for the task + IPrincipal* pPrincipal = NULL; + hr = pTask->get_Principal(&pPrincipal); + ExitOnFailure(hr, "Cannot get principal pointer: %x", hr); + + // Set up principal information: + hr = pPrincipal->put_Id(_bstr_t(L"Principal1")); + if (FAILED(hr)) + { + WcaLogError(hr, "Cannot put the principal ID: %x", hr); + } + + hr = pPrincipal->put_UserId(_bstr_t(username_domain)); + if (FAILED(hr)) + { + WcaLogError(hr, "Cannot put principal user Id: %x", hr); + } + + hr = pPrincipal->put_LogonType(TASK_LOGON_INTERACTIVE_TOKEN); + if (FAILED(hr)) + { + WcaLogError(hr, "Cannot put principal logon type: %x", hr); + } + + // Run the task with the highest available privileges. + hr = pPrincipal->put_RunLevel(TASK_RUNLEVEL_LUA); + pPrincipal->Release(); + ExitOnFailure(hr, "Cannot put principal run level: %x", hr); + + // ------------------------------------------------------ + // Save the task in the PowerToys folder. + { + _variant_t SDDL_FULL_ACCESS_FOR_EVERYONE = L"D:(A;;FA;;;WD)"; + hr = pTaskFolder->RegisterTaskDefinition( + _bstr_t(wstrTaskName.c_str()), + pTask, + TASK_CREATE_OR_UPDATE, + _variant_t(username_domain), + _variant_t(), + TASK_LOGON_INTERACTIVE_TOKEN, + SDDL_FULL_ACCESS_FOR_EVERYONE, + &pRegisteredTask); + ExitOnFailure(hr, "Error saving the Task : %x", hr); + } + + WcaLog(LOGMSG_STANDARD, "Scheduled task created for the current user."); LExit: - ReleaseStr(wszExecutablePath); - if (pService) pService->Release(); - if (pTaskFolder) pTaskFolder->Release(); - if (pTask) pTask->Release(); - if (pRegInfo) pRegInfo->Release(); - if (pSettings) pSettings->Release(); - if (pTriggerCollection) pTriggerCollection->Release(); - if (pRegisteredTask) pRegisteredTask->Release(); + ReleaseStr(wszExecutablePath); + if (pService) + { + pService->Release(); + } + if (pTaskFolder) + { + pTaskFolder->Release(); + } + if (pTask) + { + pTask->Release(); + } + if (pRegInfo) + { + pRegInfo->Release(); + } + if (pSettings) + { + pSettings->Release(); + } + if (pTriggerCollection) + { + pTriggerCollection->Release(); + } + if (pRegisteredTask) + { + pRegisteredTask->Release(); + } - if (!SUCCEEDED(hr)) { - PMSIHANDLE hRecord = MsiCreateRecord(0); - MsiRecordSetString(hRecord, 0, TEXT("Failed to create a scheduled task to start PowerToys at user login. You can re-try to create the scheduled task using the PowerToys settings.")); - MsiProcessMessage(hInstall, INSTALLMESSAGE(INSTALLMESSAGE_WARNING + MB_OK), hRecord); - } + if (!SUCCEEDED(hr)) + { + PMSIHANDLE hRecord = MsiCreateRecord(0); + MsiRecordSetString(hRecord, 0, TEXT("Failed to create a scheduled task to start PowerToys at user login. You can re-try to create the scheduled task using the PowerToys settings.")); + MsiProcessMessage(hInstall, INSTALLMESSAGE(INSTALLMESSAGE_WARNING + MB_OK), hRecord); + } - er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; - return WcaFinalize(er); + er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; + return WcaFinalize(er); } // Removes all Scheduled Tasks in the PowerToys folder and deletes the folder afterwards. // Based on the Task Scheduler Displaying Task Names and State example: // https://docs.microsoft.com/en-us/windows/desktop/TaskSchd/displaying-task-names-and-state--c---/ -UINT __stdcall RemoveScheduledTasksCA(MSIHANDLE hInstall) { - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; +UINT __stdcall RemoveScheduledTasksCA(MSIHANDLE hInstall) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; - ITaskService *pService = NULL; - ITaskFolder *pTaskFolder = NULL; - IRegisteredTaskCollection* pTaskCollection = NULL; + ITaskService* pService = NULL; + ITaskFolder* pTaskFolder = NULL; + IRegisteredTaskCollection* pTaskCollection = NULL; - hr = WcaInitialize(hInstall, "RemoveScheduledTasksCA"); - ExitOnFailure(hr, "Failed to initialize"); + hr = WcaInitialize(hInstall, "RemoveScheduledTasksCA"); + ExitOnFailure(hr, "Failed to initialize"); - WcaLog(LOGMSG_STANDARD, "Initialized."); + WcaLog(LOGMSG_STANDARD, "Initialized."); - // COM and Security Initialization is expected to have been done by the MSI. - // It couldn't be done in the DLL, anyway. - // ------------------------------------------------------ - // Create an instance of the Task Service. - hr = CoCreateInstance(CLSID_TaskScheduler, - NULL, - CLSCTX_INPROC_SERVER, - IID_ITaskService, - (void**)&pService); - ExitOnFailure(hr, "Failed to create an instance of ITaskService: %x", hr); + // COM and Security Initialization is expected to have been done by the MSI. + // It couldn't be done in the DLL, anyway. + // ------------------------------------------------------ + // Create an instance of the Task Service. + hr = CoCreateInstance(CLSID_TaskScheduler, + NULL, + CLSCTX_INPROC_SERVER, + IID_ITaskService, + (void**)&pService); + ExitOnFailure(hr, "Failed to create an instance of ITaskService: %x", hr); - // Connect to the task service. - hr = pService->Connect(_variant_t(), _variant_t(), - _variant_t(), _variant_t()); - ExitOnFailure(hr, "ITaskService::Connect failed: %x", hr); + // Connect to the task service. + hr = pService->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t()); + ExitOnFailure(hr, "ITaskService::Connect failed: %x", hr); - // ------------------------------------------------------ - // Get the PowerToys task folder. - hr = pService->GetFolder(_bstr_t(L"\\PowerToys"), &pTaskFolder); - if (FAILED(hr)) { - // Folder doesn't exist. No need to delete anything. - WcaLog(LOGMSG_STANDARD, "The PowerToys scheduled task folder wasn't found. Nothing to delete."); - hr = S_OK; - ExitFunction(); - } - - // ------------------------------------------------------- - // Get the registered tasks in the folder. - hr = pTaskFolder->GetTasks(TASK_ENUM_HIDDEN, &pTaskCollection); - ExitOnFailure(hr, "Cannot get the registered tasks: %x", hr); - - LONG numTasks = 0; - hr = pTaskCollection->get_Count(&numTasks); - for (LONG i = 0; i < numTasks; i++) { - // Delete all the tasks found. - // If some tasks can't be deleted, the folder won't be deleted later and the user will still be notified. - IRegisteredTask* pRegisteredTask = NULL; - hr = pTaskCollection->get_Item(_variant_t(i + 1), &pRegisteredTask); - if (SUCCEEDED(hr)) { - BSTR taskName = NULL; - hr = pRegisteredTask->get_Name(&taskName); - if (SUCCEEDED(hr)) { - hr = pTaskFolder->DeleteTask(taskName, NULL); - if (FAILED(hr)) { - WcaLogError(hr, "Cannot delete the '%S' task: %x", taskName, hr); - } - SysFreeString(taskName); - } else { - WcaLogError(hr, "Cannot get the registered task name: %x", hr); - } - pRegisteredTask->Release(); - } else { - WcaLogError(hr, "Cannot get the registered task item at index=%d: %x", i + 1, hr); + // ------------------------------------------------------ + // Get the PowerToys task folder. + hr = pService->GetFolder(_bstr_t(L"\\PowerToys"), &pTaskFolder); + if (FAILED(hr)) + { + // Folder doesn't exist. No need to delete anything. + WcaLog(LOGMSG_STANDARD, "The PowerToys scheduled task folder wasn't found. Nothing to delete."); + hr = S_OK; + ExitFunction(); } - } - // ------------------------------------------------------ - // Get the pointer to the root task folder and delete the PowerToys subfolder. - ITaskFolder *pRootFolder = NULL; - hr = pService->GetFolder(_bstr_t(L"\\"), &pRootFolder); - ExitOnFailure(hr, "Cannot get Root Folder pointer: %x", hr); - hr = pRootFolder->DeleteFolder(_bstr_t(L"PowerToys"), NULL); - pRootFolder->Release(); - ExitOnFailure(hr, "Cannot delete the PowerToys folder: %x", hr); + // ------------------------------------------------------- + // Get the registered tasks in the folder. + hr = pTaskFolder->GetTasks(TASK_ENUM_HIDDEN, &pTaskCollection); + ExitOnFailure(hr, "Cannot get the registered tasks: %x", hr); - WcaLog(LOGMSG_STANDARD, "Deleted the PowerToys Task Scheduler folder."); + LONG numTasks = 0; + hr = pTaskCollection->get_Count(&numTasks); + for (LONG i = 0; i < numTasks; i++) + { + // Delete all the tasks found. + // If some tasks can't be deleted, the folder won't be deleted later and the user will still be notified. + IRegisteredTask* pRegisteredTask = NULL; + hr = pTaskCollection->get_Item(_variant_t(i + 1), &pRegisteredTask); + if (SUCCEEDED(hr)) + { + BSTR taskName = NULL; + hr = pRegisteredTask->get_Name(&taskName); + if (SUCCEEDED(hr)) + { + hr = pTaskFolder->DeleteTask(taskName, NULL); + if (FAILED(hr)) + { + WcaLogError(hr, "Cannot delete the '%S' task: %x", taskName, hr); + } + SysFreeString(taskName); + } + else + { + WcaLogError(hr, "Cannot get the registered task name: %x", hr); + } + pRegisteredTask->Release(); + } + else + { + WcaLogError(hr, "Cannot get the registered task item at index=%d: %x", i + 1, hr); + } + } + + // ------------------------------------------------------ + // Get the pointer to the root task folder and delete the PowerToys subfolder. + ITaskFolder* pRootFolder = NULL; + hr = pService->GetFolder(_bstr_t(L"\\"), &pRootFolder); + ExitOnFailure(hr, "Cannot get Root Folder pointer: %x", hr); + hr = pRootFolder->DeleteFolder(_bstr_t(L"PowerToys"), NULL); + pRootFolder->Release(); + ExitOnFailure(hr, "Cannot delete the PowerToys folder: %x", hr); + + WcaLog(LOGMSG_STANDARD, "Deleted the PowerToys Task Scheduler folder."); LExit: - if (pService) pService->Release(); - if (pTaskFolder) pTaskFolder->Release(); - if (pTaskCollection) pTaskCollection->Release(); + if (pService) + { + pService->Release(); + } + if (pTaskFolder) + { + pTaskFolder->Release(); + } + if (pTaskCollection) + { + pTaskCollection->Release(); + } - if (!SUCCEEDED(hr)) { - PMSIHANDLE hRecord = MsiCreateRecord(0); - MsiRecordSetString(hRecord, 0, TEXT("Failed to remove the PowerToys folder from the scheduled task. These can be removed manually later.")); - MsiProcessMessage(hInstall, INSTALLMESSAGE(INSTALLMESSAGE_WARNING + MB_OK), hRecord); - } + if (!SUCCEEDED(hr)) + { + PMSIHANDLE hRecord = MsiCreateRecord(0); + MsiRecordSetString(hRecord, 0, TEXT("Failed to remove the PowerToys folder from the scheduled task. These can be removed manually later.")); + MsiProcessMessage(hInstall, INSTALLMESSAGE(INSTALLMESSAGE_WARNING + MB_OK), hRecord); + } - er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; - return WcaFinalize(er); + er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; + return WcaFinalize(er); } -UINT __stdcall TelemetryLogInstallSuccessCA(MSIHANDLE hInstall) { - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; +UINT __stdcall TelemetryLogInstallSuccessCA(MSIHANDLE hInstall) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; - hr = WcaInitialize(hInstall, "TelemetryLogInstallSuccessCA"); - ExitOnFailure(hr, "Failed to initialize"); + hr = WcaInitialize(hInstall, "TelemetryLogInstallSuccessCA"); + ExitOnFailure(hr, "Failed to initialize"); - TraceLoggingWrite( - g_hProvider, - "Install_Success", - ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), - TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"), - TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); + TraceLoggingWrite( + g_hProvider, + "Install_Success", + ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), + TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"), + TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); LExit: - er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; - return WcaFinalize(er); + er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; + return WcaFinalize(er); } -UINT __stdcall TelemetryLogInstallCancelCA(MSIHANDLE hInstall) { - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; +UINT __stdcall TelemetryLogInstallCancelCA(MSIHANDLE hInstall) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; - hr = WcaInitialize(hInstall, "TelemetryLogInstallCancelCA"); - ExitOnFailure(hr, "Failed to initialize"); + hr = WcaInitialize(hInstall, "TelemetryLogInstallCancelCA"); + ExitOnFailure(hr, "Failed to initialize"); - TraceLoggingWrite( - g_hProvider, - "Install_Cancel", - ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), - TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"), - TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); + TraceLoggingWrite( + g_hProvider, + "Install_Cancel", + ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), + TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"), + TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); LExit: - er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; - return WcaFinalize(er); + er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; + return WcaFinalize(er); } -UINT __stdcall TelemetryLogInstallFailCA(MSIHANDLE hInstall) { - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; +UINT __stdcall TelemetryLogInstallFailCA(MSIHANDLE hInstall) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; - hr = WcaInitialize(hInstall, "TelemetryLogInstallFailCA"); - ExitOnFailure(hr, "Failed to initialize"); + hr = WcaInitialize(hInstall, "TelemetryLogInstallFailCA"); + ExitOnFailure(hr, "Failed to initialize"); - TraceLoggingWrite( - g_hProvider, - "Install_Fail", - ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), - TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"), - TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); + TraceLoggingWrite( + g_hProvider, + "Install_Fail", + ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), + TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"), + TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); LExit: - er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; - return WcaFinalize(er); + er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; + return WcaFinalize(er); } -UINT __stdcall TelemetryLogUninstallSuccessCA(MSIHANDLE hInstall) { - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; +UINT __stdcall TelemetryLogUninstallSuccessCA(MSIHANDLE hInstall) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; - hr = WcaInitialize(hInstall, "TelemetryLogUninstallSuccessCA"); - ExitOnFailure(hr, "Failed to initialize"); + hr = WcaInitialize(hInstall, "TelemetryLogUninstallSuccessCA"); + ExitOnFailure(hr, "Failed to initialize"); - TraceLoggingWrite( - g_hProvider, - "UnInstall_Success", - ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), - TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"), - TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); + TraceLoggingWrite( + g_hProvider, + "UnInstall_Success", + ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), + TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"), + TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); LExit: - er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; - return WcaFinalize(er); + er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; + return WcaFinalize(er); } -UINT __stdcall TelemetryLogUninstallCancelCA(MSIHANDLE hInstall) { - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; +UINT __stdcall TelemetryLogUninstallCancelCA(MSIHANDLE hInstall) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; - hr = WcaInitialize(hInstall, "TelemetryLogUninstallCancelCA"); - ExitOnFailure(hr, "Failed to initialize"); + hr = WcaInitialize(hInstall, "TelemetryLogUninstallCancelCA"); + ExitOnFailure(hr, "Failed to initialize"); - TraceLoggingWrite( - g_hProvider, - "UnInstall_Cancel", - ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), - TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"), - TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); + TraceLoggingWrite( + g_hProvider, + "UnInstall_Cancel", + ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), + TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"), + TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); LExit: - er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; - return WcaFinalize(er); + er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; + return WcaFinalize(er); } -UINT __stdcall TelemetryLogUninstallFailCA(MSIHANDLE hInstall) { - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; +UINT __stdcall TelemetryLogUninstallFailCA(MSIHANDLE hInstall) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; - hr = WcaInitialize(hInstall, "TelemetryLogUninstallFailCA"); - ExitOnFailure(hr, "Failed to initialize"); + hr = WcaInitialize(hInstall, "TelemetryLogUninstallFailCA"); + ExitOnFailure(hr, "Failed to initialize"); - TraceLoggingWrite( - g_hProvider, - "UnInstall_Fail", - ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), - TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"), - TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); + TraceLoggingWrite( + g_hProvider, + "UnInstall_Fail", + ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), + TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"), + TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); LExit: - er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; - return WcaFinalize(er); + er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; + return WcaFinalize(er); } -UINT __stdcall TelemetryLogRepairCancelCA(MSIHANDLE hInstall) { - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; +UINT __stdcall TelemetryLogRepairCancelCA(MSIHANDLE hInstall) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; - hr = WcaInitialize(hInstall, "TelemetryLogRepairCancelCA"); - ExitOnFailure(hr, "Failed to initialize"); + hr = WcaInitialize(hInstall, "TelemetryLogRepairCancelCA"); + ExitOnFailure(hr, "Failed to initialize"); - TraceLoggingWrite( - g_hProvider, - "Repair_Cancel", - ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), - TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"), - TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); + TraceLoggingWrite( + g_hProvider, + "Repair_Cancel", + ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), + TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"), + TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); LExit: - er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; - return WcaFinalize(er); + er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; + return WcaFinalize(er); } -UINT __stdcall TelemetryLogRepairFailCA(MSIHANDLE hInstall) { - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; +UINT __stdcall TelemetryLogRepairFailCA(MSIHANDLE hInstall) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; - hr = WcaInitialize(hInstall, "TelemetryLogRepairFailCA"); - ExitOnFailure(hr, "Failed to initialize"); + hr = WcaInitialize(hInstall, "TelemetryLogRepairFailCA"); + ExitOnFailure(hr, "Failed to initialize"); - TraceLoggingWrite( - g_hProvider, - "Repair_Fail", - ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), - TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"), - TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); + TraceLoggingWrite( + g_hProvider, + "Repair_Fail", + ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), + TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"), + TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); LExit: - er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; - return WcaFinalize(er); + er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; + return WcaFinalize(er); } // DllMain - Initialize and cleanup WiX custom action utils. -extern "C" BOOL WINAPI DllMain(__in HINSTANCE hInst, __in ULONG ulReason, __in LPVOID) { - switch (ulReason) { - case DLL_PROCESS_ATTACH: - WcaGlobalInitialize(hInst); - TraceLoggingRegister(g_hProvider); - break; +extern "C" BOOL WINAPI DllMain(__in HINSTANCE hInst, __in ULONG ulReason, __in LPVOID) +{ + switch (ulReason) + { + case DLL_PROCESS_ATTACH: + WcaGlobalInitialize(hInst); + TraceLoggingRegister(g_hProvider); + break; - case DLL_PROCESS_DETACH: - TraceLoggingUnregister(g_hProvider); - WcaGlobalFinalize(); - break; - } + case DLL_PROCESS_DETACH: + TraceLoggingUnregister(g_hProvider); + WcaGlobalFinalize(); + break; + } - return TRUE; + return TRUE; }