diff --git a/installer/PowerToysSetup/Product.wxs b/installer/PowerToysSetup/Product.wxs index 0a5033f677..3c5145fbc5 100644 --- a/installer/PowerToysSetup/Product.wxs +++ b/installer/PowerToysSetup/Product.wxs @@ -221,8 +221,11 @@ Installed AND (REMOVE="ALL") + + Installed AND (REMOVE="ALL") + - + @@ -369,8 +372,16 @@ DllEntry="UnApplyModulesRegistryChangeSetsCA" /> + - + + diff --git a/installer/PowerToysSetupCustomActions/CustomAction.cpp b/installer/PowerToysSetupCustomActions/CustomAction.cpp index 8a942d3348..31d6cbe1f6 100644 --- a/installer/PowerToysSetupCustomActions/CustomAction.cpp +++ b/installer/PowerToysSetupCustomActions/CustomAction.cpp @@ -11,6 +11,10 @@ #include "../../src/common/updating/installer.h" #include "../../src/common/version/version.h" +#include +#include +#include + using namespace std; HINSTANCE DLL_HANDLE = nullptr; @@ -912,7 +916,7 @@ LExit: if (!SUCCEEDED(hr)) { PMSIHANDLE hRecord = MsiCreateRecord(0); - MsiRecordSetString(hRecord, 0, TEXT("Filed to iminstall virtual camera driver")); + MsiRecordSetString(hRecord, 0, TEXT("Failed to uninstall virtual camera driver")); MsiProcessMessage(hInstall, INSTALLMESSAGE(INSTALLMESSAGE_WARNING + MB_OK), hRecord); } @@ -920,6 +924,78 @@ LExit: return WcaFinalize(er); } +UINT __stdcall UnRegisterContextMenuPackagesCA(MSIHANDLE hInstall) +{ + using namespace winrt::Windows::Foundation; + using namespace winrt::Windows::Management::Deployment; + + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + + hr = WcaInitialize(hInstall, "UnRegisterContextMenuPackagesCA"); // original func name is too long + + try + { + // Packages to unregister + const std::vector packagesToRemoveDisplayName{ { L"PowerRenameContextMenu" } }; + + PackageManager packageManager; + + for (auto const& package : packageManager.FindPackages()) + { + const auto& packageFullName = std::wstring{ package.Id().FullName() }; + + for (const auto& packageToRemove : packagesToRemoveDisplayName) + { + if (packageFullName.contains(packageToRemove)) + { + auto deploymentOperation{ packageManager.RemovePackageAsync(packageFullName) }; + deploymentOperation.get(); + + // Check the status of the operation + if (deploymentOperation.Status() == AsyncStatus::Error) + { + auto deploymentResult{ deploymentOperation.GetResults() }; + auto errorCode = deploymentOperation.ErrorCode(); + auto errorText = deploymentResult.ErrorText(); + + Logger::error(L"Unregister {} package failed. ErrorCode: {}, ErrorText: {}", packageFullName, std::to_wstring(errorCode), errorText); + + er = ERROR_INSTALL_FAILURE; + } + else if (deploymentOperation.Status() == AsyncStatus::Canceled) + { + Logger::error(L"Unregister {} package canceled.", packageFullName); + + er = ERROR_INSTALL_FAILURE; + } + else if (deploymentOperation.Status() == AsyncStatus::Completed) + { + Logger::info(L"Unregister {} package completed.", packageFullName); + } + else + { + Logger::debug(L"Unregister {} package started.", packageFullName); + } + } + + } + } + } + catch (std::exception e) + { + std::string errorMessage{ "Exception thrown while trying to unregister sparse packages: " }; + errorMessage += e.what(); + Logger::error(errorMessage); + + er = ERROR_INSTALL_FAILURE; + } + + er = er == ERROR_SUCCESS ? (SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE) : er; + return WcaFinalize(er); +} + + UINT __stdcall TerminateProcessesCA(MSIHANDLE hInstall) { HRESULT hr = S_OK; diff --git a/installer/PowerToysSetupCustomActions/CustomAction.def b/installer/PowerToysSetupCustomActions/CustomAction.def index f8e4d84481..255b64724e 100644 --- a/installer/PowerToysSetupCustomActions/CustomAction.def +++ b/installer/PowerToysSetupCustomActions/CustomAction.def @@ -14,10 +14,10 @@ EXPORTS TelemetryLogRepairCancelCA TelemetryLogRepairFailCA TerminateProcessesCA - TerminateProcessesCA CertifyVirtualCameraDriverCA InstallVirtualCameraDriverCA InstallEmbeddedMSIXCA UnApplyModulesRegistryChangeSetsCA UninstallVirtualCameraDriverCA + UnRegisterContextMenuPackagesCA UninstallEmbeddedMSIXCA \ No newline at end of file diff --git a/installer/PowerToysSetupCustomActions/PowerToysSetupCustomActions.vcxproj b/installer/PowerToysSetupCustomActions/PowerToysSetupCustomActions.vcxproj index f43503577e..55507fd2f2 100644 --- a/installer/PowerToysSetupCustomActions/PowerToysSetupCustomActions.vcxproj +++ b/installer/PowerToysSetupCustomActions/PowerToysSetupCustomActions.vcxproj @@ -1,7 +1,7 @@ - + + {32f3882b-f2d6-4586-b5ed-11e39e522bd3} Win32Proj @@ -43,7 +43,6 @@ false ..\..\src\common\Telemetry;$(IncludePath) - inc;..\..\src\;..\..\src\common\Telemetry;telemetry;$(WixSdkPath)VS2017\inc;%(AdditionalIncludeDirectories) @@ -56,7 +55,6 @@ CustomAction.def - WIN64;%(PreprocessorDefinitions) @@ -65,7 +63,6 @@ $(WixSdkPath)VS2017\lib\$(Platform);%(AdditionalLibraryDirectories) - Disabled @@ -127,5 +124,14 @@ - + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + \ No newline at end of file diff --git a/installer/PowerToysSetupCustomActions/packages.config b/installer/PowerToysSetupCustomActions/packages.config index 6b8deb9c96..fa024c0634 100644 --- a/installer/PowerToysSetupCustomActions/packages.config +++ b/installer/PowerToysSetupCustomActions/packages.config @@ -1,3 +1,4 @@  + \ No newline at end of file diff --git a/src/modules/powerrename/PowerRenameContextMenu/AppxManifest.xml b/src/modules/powerrename/PowerRenameContextMenu/AppxManifest.xml index 0015178c97..f43fb523d1 100644 --- a/src/modules/powerrename/PowerRenameContextMenu/AppxManifest.xml +++ b/src/modules/powerrename/PowerRenameContextMenu/AppxManifest.xml @@ -37,6 +37,12 @@ + + + + + + diff --git a/src/modules/powerrename/PowerRenameContextMenu/PowerRenameContextMenu.cpp b/src/modules/powerrename/PowerRenameContextMenu/PowerRenameContextMenu.cpp deleted file mode 100644 index c3f59a9eb5..0000000000 --- a/src/modules/powerrename/PowerRenameContextMenu/PowerRenameContextMenu.cpp +++ /dev/null @@ -1,22 +0,0 @@ -// PowerRenameContextMenu.cpp : Defines the exported functions for the DLL. -// - -#include "pch.h" -#include "framework.h" -#include "PowerRenameContextMenu.h" - - -// This is an example of an exported variable -POWERRENAMECONTEXTMENU_API int nPowerRenameContextMenu=0; - -// This is an example of an exported function. -POWERRENAMECONTEXTMENU_API int fnPowerRenameContextMenu(void) -{ - return 0; -} - -// This is the constructor of a class that has been exported. -CPowerRenameContextMenu::CPowerRenameContextMenu() -{ - return; -} diff --git a/src/modules/powerrename/PowerRenameContextMenu/PowerRenameContextMenu.h b/src/modules/powerrename/PowerRenameContextMenu/PowerRenameContextMenu.h deleted file mode 100644 index 2145f56e2b..0000000000 --- a/src/modules/powerrename/PowerRenameContextMenu/PowerRenameContextMenu.h +++ /dev/null @@ -1,22 +0,0 @@ -// The following ifdef block is the standard way of creating macros which make exporting -// from a DLL simpler. All files within this DLL are compiled with the POWERRENAMECONTEXTMENU_EXPORTS -// symbol defined on the command line. This symbol should not be defined on any project -// that uses this DLL. This way any other project whose source files include this file see -// POWERRENAMECONTEXTMENU_API functions as being imported from a DLL, whereas this DLL sees symbols -// defined with this macro as being exported. -#ifdef POWERRENAMECONTEXTMENU_EXPORTS -#define POWERRENAMECONTEXTMENU_API __declspec(dllexport) -#else -#define POWERRENAMECONTEXTMENU_API __declspec(dllimport) -#endif - -// This class is exported from the dll -class POWERRENAMECONTEXTMENU_API CPowerRenameContextMenu { -public: - CPowerRenameContextMenu(void); - // TODO: add your methods here. -}; - -extern POWERRENAMECONTEXTMENU_API int nPowerRenameContextMenu; - -POWERRENAMECONTEXTMENU_API int fnPowerRenameContextMenu(void); diff --git a/src/modules/powerrename/PowerRenameContextMenu/PowerRenameContextMenu.vcxproj b/src/modules/powerrename/PowerRenameContextMenu/PowerRenameContextMenu.vcxproj index 49341b8d60..fafd59c793 100644 --- a/src/modules/powerrename/PowerRenameContextMenu/PowerRenameContextMenu.vcxproj +++ b/src/modules/powerrename/PowerRenameContextMenu/PowerRenameContextMenu.vcxproj @@ -84,7 +84,6 @@ MakeAppx.exe pack /d . /p $(OutDir)PowerRenameContextMenuPackage.msix /nv - @@ -92,7 +91,6 @@ MakeAppx.exe pack /d . /p $(OutDir)PowerRenameContextMenuPackage.msix /nv Create - diff --git a/src/modules/powerrename/PowerRenameContextMenu/PowerRenameContextMenu.vcxproj.filters b/src/modules/powerrename/PowerRenameContextMenu/PowerRenameContextMenu.vcxproj.filters index 66afa4c1fc..5c486cd453 100644 --- a/src/modules/powerrename/PowerRenameContextMenu/PowerRenameContextMenu.vcxproj.filters +++ b/src/modules/powerrename/PowerRenameContextMenu/PowerRenameContextMenu.vcxproj.filters @@ -18,9 +18,6 @@ Header Files - - Header Files - Header Files @@ -29,9 +26,6 @@ - - Source Files - Source Files @@ -41,6 +35,177 @@ + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + @@ -48,9 +213,6 @@ - - Resource Files - Resource Files @@ -543,12 +705,6 @@ Resource Files - - Resource Files - - - Resource Files - Resource Files diff --git a/src/modules/powerrename/PowerRenameContextMenu/dllmain.cpp b/src/modules/powerrename/PowerRenameContextMenu/dllmain.cpp index 12658bc50b..494f3e192d 100644 --- a/src/modules/powerrename/PowerRenameContextMenu/dllmain.cpp +++ b/src/modules/powerrename/PowerRenameContextMenu/dllmain.cpp @@ -22,12 +22,15 @@ #include #include +#include #include using namespace Microsoft::WRL; HINSTANCE g_hInst = 0; +#define BUFSIZE 4096 * 4 + BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved @@ -94,34 +97,11 @@ public: IFACEMETHODIMP Invoke(_In_opt_ IShellItemArray* selection, _In_opt_ IBindCtx*) noexcept try { - HWND parent = nullptr; - if (m_site) - { - ComPtr oleWindow; - RETURN_IF_FAILED(m_site.As(&oleWindow)); - RETURN_IF_FAILED(oleWindow->GetWindow(&parent)); - } - - std::wostringstream title; - title << Title(); - if (selection) { - DWORD count; - RETURN_IF_FAILED(selection->GetCount(&count)); - title << L" (" << count << L" selected items)"; + RunPowerRename(selection); } - else - { - title << L"(no selected items)"; - } - std::filesystem::path modulePath{ wil::GetModuleFileNameW() }; - std::wstring path = get_module_folderpath(g_hInst); - path = path + L"\\PowerToys.PowerRename.exe"; - std::wstring iconResourcePath = get_module_filename(); - MessageBox(parent, iconResourcePath.c_str(), iconResourcePath.c_str(), MB_OK); - RunPowerRename(selection); return S_OK; } CATCH_RETURN(); @@ -149,111 +129,110 @@ protected: ComPtr m_site; private: - HRESULT RunPowerRename(IShellItemArray* psiItemArray) + + HRESULT StartNamedPipeServerAndSendData(std::wstring pipe_name, IShellItemArray* psiItemArray) { - HRESULT hr = E_FAIL; - HWND parent = nullptr; - if (m_site) + hPipe = CreateNamedPipe( + pipe_name.c_str(), + PIPE_ACCESS_DUPLEX | + WRITE_DAC, + PIPE_TYPE_MESSAGE | + PIPE_READMODE_MESSAGE | + PIPE_WAIT, + PIPE_UNLIMITED_INSTANCES, + BUFSIZE, + BUFSIZE, + 0, + NULL); + + if (hPipe == NULL || hPipe == INVALID_HANDLE_VALUE) { - ComPtr oleWindow; - RETURN_IF_FAILED(m_site.As(&oleWindow)); - RETURN_IF_FAILED(oleWindow->GetWindow(&parent)); + return E_FAIL; } + // This call blocks until a client process connects to the pipe + BOOL connected = ConnectNamedPipe(hPipe, NULL); + if (!connected) + { + if (GetLastError() == ERROR_PIPE_CONNECTED) + { + return S_OK; + } + else + { + CloseHandle(hPipe); + } + return E_FAIL; + } + return S_OK; + } + + HRESULT RunPowerRename(IShellItemArray* psiItemArray) + { if (CSettingsInstance().GetEnabled()) { Trace::Invoked(); // Set the application path based on the location of the dll std::wstring path = get_module_folderpath(g_hInst); path = path + L"\\PowerToys.PowerRename.exe"; - LPTSTR lpApplicationName = (LPTSTR)path.c_str(); - // Create an anonymous pipe to stream filenames - SECURITY_ATTRIBUTES sa; - HANDLE hReadPipe; - HANDLE hWritePipe; - sa.nLength = sizeof(SECURITY_ATTRIBUTES); - sa.lpSecurityDescriptor = NULL; - sa.bInheritHandle = TRUE; - if (!CreatePipe(&hReadPipe, &hWritePipe, &sa, 0)) + + std::wstring pipe_name(L"\\\\.\\pipe\\powertoys_powerrenameinput_"); + UUID temp_uuid; + wchar_t* uuid_chars = nullptr; + if (UuidCreate(&temp_uuid) == RPC_S_UUID_NO_ADDRESS) { - hr = HRESULT_FROM_WIN32(GetLastError()); - return hr; + auto val = get_last_error_message(GetLastError()); + Logger::warn(L"UuidCreate can not create guid. {}", val.has_value() ? val.value() : L""); } - if (!SetHandleInformation(hWritePipe, HANDLE_FLAG_INHERIT, 0)) + else if (UuidToString(&temp_uuid, (RPC_WSTR*)&uuid_chars) != RPC_S_OK) { - hr = HRESULT_FROM_WIN32(GetLastError()); - return hr; - } - CAtlFile writePipe(hWritePipe); - - CString commandLine; - commandLine.Format(_T("\"%s\""), lpApplicationName); - int nSize = commandLine.GetLength() + 1; - LPTSTR lpszCommandLine = new TCHAR[nSize]; - _tcscpy_s(lpszCommandLine, nSize, commandLine); - - STARTUPINFO startupInfo; - ZeroMemory(&startupInfo, sizeof(STARTUPINFO)); - startupInfo.cb = sizeof(STARTUPINFO); - startupInfo.hStdInput = hReadPipe; - startupInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; - startupInfo.wShowWindow = SW_SHOWNORMAL; - - PROCESS_INFORMATION processInformation; - - // Start the resizer - CreateProcess( - NULL, - lpszCommandLine, - NULL, - NULL, - TRUE, - 0, - NULL, - NULL, - &startupInfo, - &processInformation); - - RunNonElevatedEx(path.c_str(), {}, get_module_folderpath(g_hInst)); - - delete[] lpszCommandLine; - if (!CloseHandle(processInformation.hProcess)) - { - hr = HRESULT_FROM_WIN32(GetLastError()); - return hr; - } - if (!CloseHandle(processInformation.hThread)) - { - hr = HRESULT_FROM_WIN32(GetLastError()); - return hr; + auto val = get_last_error_message(GetLastError()); + Logger::warn(L"UuidToString can not convert to string. {}", val.has_value() ? val.value() : L""); } - //m_pdtobj will be NULL when invoked from the MSIX build as Initialize is never called (IShellExtInit functions aren't called in case of MSIX). - DWORD fileCount = 0; - // Gets the list of files currently selected using the IShellItemArray - psiItemArray->GetCount(&fileCount); - // Iterate over the list of files - for (DWORD i = 0; i < fileCount; i++) + if (uuid_chars != nullptr) { - IShellItem* shellItem; - psiItemArray->GetItemAt(i, &shellItem); - LPWSTR itemName; - // Retrieves the entire file system path of the file from its shell item - shellItem->GetDisplayName(SIGDN_FILESYSPATH, &itemName); - CString fileName(itemName); - // File name can't contain '?' - fileName.Append(_T("?")); - // Write the file path into the input stream for image resizer - writePipe.Write(fileName, fileName.GetLength() * sizeof(TCHAR)); + pipe_name += std::wstring(uuid_chars); + RpcStringFree((RPC_WSTR*)&uuid_chars); + uuid_chars = nullptr; + } + create_pipe_thread = std::thread(&PowerRenameContextMenuCommand::StartNamedPipeServerAndSendData, this, pipe_name, psiItemArray); + RunNonElevatedEx(path.c_str(), pipe_name, get_module_folderpath(g_hInst)); + create_pipe_thread.join(); + + if (hPipe != INVALID_HANDLE_VALUE) + { + CAtlFile writePipe(hPipe); + + DWORD fileCount = 0; + // Gets the list of files currently selected using the IShellItemArray + psiItemArray->GetCount(&fileCount); + // Iterate over the list of files + for (DWORD i = 0; i < fileCount; i++) + { + IShellItem* shellItem; + psiItemArray->GetItemAt(i, &shellItem); + LPWSTR itemName; + // Retrieves the entire file system path of the file from its shell item + shellItem->GetDisplayName(SIGDN_FILESYSPATH, &itemName); + CString fileName(itemName); + // File name can't contain '?' + fileName.Append(_T("?")); + // Write the file path into the input stream for image resizer + writePipe.Write(fileName, fileName.GetLength() * sizeof(TCHAR)); + } + writePipe.Close(); } - writePipe.Close(); } - Trace::InvokedRet(hr); + Trace::InvokedRet(S_OK); - return hr; + return S_OK; } + + std::thread create_pipe_thread; + HANDLE hPipe = INVALID_HANDLE_VALUE; std::wstring app_name = L"PowerRename"; }; diff --git a/src/modules/powerrename/PowerRenameUILib/App.xaml.cpp b/src/modules/powerrename/PowerRenameUILib/App.xaml.cpp index 38aa58bf21..db906e2af8 100644 --- a/src/modules/powerrename/PowerRenameUILib/App.xaml.cpp +++ b/src/modules/powerrename/PowerRenameUILib/App.xaml.cpp @@ -53,15 +53,61 @@ void App::OnLaunched(LaunchActivatedEventArgs const&) { LoggerHelpers::init_logger(moduleName, L"", LogSettings::powerRenameLoggerName); -#define BUFSIZE 4096 * 4 + auto args = std::wstring{ GetCommandLine() }; + size_t pos{ args.rfind(' ') }; + + std::wstring pipe_name; + if (pos != std::wstring::npos) + { + pipe_name = args.substr(pos + 1); + } + + + HANDLE hStdin; + + if (pipe_name.size() > 0) + { + while (1) + { + hStdin = CreateFile( + pipe_name.c_str(), // pipe name + GENERIC_READ | GENERIC_WRITE, // read and write + 0, // no sharing + NULL, // default security attributes + OPEN_EXISTING, // opens existing pipe + 0, // default attributes + NULL); // no template file + + // Break if the pipe handle is valid. + if (hStdin != INVALID_HANDLE_VALUE) + break; + + // Exit if an error other than ERROR_PIPE_BUSY occurs. + auto error = GetLastError(); + if (error != ERROR_PIPE_BUSY) + { + break; + } + + if (!WaitNamedPipe(pipe_name.c_str(), 3)) + { + printf("Could not open pipe: 20 second wait timed out."); + } + } + } + else + { + hStdin = GetStdHandle(STD_INPUT_HANDLE); + } - HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE); if (hStdin == INVALID_HANDLE_VALUE) { Logger::error(L"Invalid input handle."); ExitProcess(1); } +#define BUFSIZE 4096 * 4 + BOOL bSuccess; WCHAR chBuf[BUFSIZE]; DWORD dwRead; @@ -86,6 +132,7 @@ void App::OnLaunched(LaunchActivatedEventArgs const&) if (!bSuccess) break; } + CloseHandle(hStdin); Logger::debug(L"Starting PowerRename with {} files selected", g_files.size()); diff --git a/src/modules/powerrename/dll/dllmain.cpp b/src/modules/powerrename/dll/dllmain.cpp index b6b4d0d1d4..cd4a711f2d 100644 --- a/src/modules/powerrename/dll/dllmain.cpp +++ b/src/modules/powerrename/dll/dllmain.cpp @@ -10,13 +10,103 @@ #include #include "Generated Files/resource.h" #include +#include #include +#include #include #include +#include std::atomic g_dwModuleRefCount = 0; HINSTANCE g_hInst = 0; +#define STATUS_SUCCESS 0x00000000 +typedef NTSTATUS(WINAPI* RtlGetVersionPtr)(PRTL_OSVERSIONINFOW); + +namespace +{ + RTL_OSVERSIONINFOW GetRealOSVersion() + { + HMODULE hMod = ::GetModuleHandleW(L"ntdll.dll"); + if (hMod) + { + RtlGetVersionPtr fxPtr = (RtlGetVersionPtr)::GetProcAddress(hMod, "RtlGetVersion"); + if (fxPtr != nullptr) + { + RTL_OSVERSIONINFOW info = { 0 }; + info.dwOSVersionInfoSize = sizeof(info); + if (STATUS_SUCCESS == fxPtr(&info)) + { + return info; + } + } + } + RTL_OSVERSIONINFOW info = { 0 }; + return info; + } + + bool IsWindows11() + { + auto info = GetRealOSVersion(); + return info.dwMajorVersion >= 10 && info.dwBuildNumber >= 22000; + } + + + bool RegisterSparsePackage(std::wstring externalLocation, std::wstring sparsePkgPath) + { + using namespace winrt::Windows::Foundation; + using namespace winrt::Windows::Management::Deployment; + + try + { + Uri externalUri{ externalLocation }; + Uri packageUri{ sparsePkgPath }; + + PackageManager packageManager; + + // Declare use of an external location + AddPackageOptions options; + options.ExternalLocationUri(externalUri); + + IAsyncOperationWithProgress deploymentOperation = packageManager.AddPackageByUriAsync(packageUri, options); + deploymentOperation.get(); + + // Check the status of the operation + if (deploymentOperation.Status() == AsyncStatus::Error) + { + auto deploymentResult{ deploymentOperation.GetResults() }; + auto errorCode = deploymentOperation.ErrorCode(); + auto errorText = deploymentResult.ErrorText(); + + Logger::error(L"Register PowerRenameContextMenu package failed. ErrorCode: {}, ErrorText: {}", std::to_wstring(errorCode), errorText); + return false; + } + else if (deploymentOperation.Status() == AsyncStatus::Canceled) + { + Logger::error(L"Register PowerRenameContextMenu package canceled."); + return false; + } + else if (deploymentOperation.Status() == AsyncStatus::Completed) + { + Logger::info(L"Register PowerRenameContextMenu package completed."); + } + else + { + Logger::debug(L"Register PowerRenameContextMenu package started."); + } + + return true; + } + catch (std::exception e) + { + std::string errorMessage{ "Exception thrown while trying to register PowerRenameContextMenu package: " }; + errorMessage += e.what(); + Logger::error(errorMessage); + + return false; + } + } +} class CPowerRenameClassFactory : public IClassFactory { public: @@ -164,64 +254,6 @@ private: std::wstring app_key; public: - bool registerSparsePackage(std::wstring externalLocation, std::wstring sparsePkgPath) - { - bool registration = false; - try - { - using namespace winrt::Windows::Foundation; - using namespace winrt::Windows::Management::Deployment; - Uri externalUri{ externalLocation }; - Uri packageUri{ sparsePkgPath }; - - // Console.WriteLine("exe Location {0}", externalLocation); - // Console.WriteLine("msix Address {0}", sparsePkgPath); - - // Console.WriteLine(" exe Uri {0}", externalUri); - // Console.WriteLine(" msix Uri {0}", packageUri); - - PackageManager packageManager; - - // Declare use of an external location - AddPackageOptions options; - options.ExternalLocationUri(externalUri); - - IAsyncOperationWithProgress deploymentOperation = packageManager.AddPackageByUriAsync(packageUri, options); - //IAsyncOperationWithProgress deploymentOperation = packageManager.AddPackageAsync(packageUri, nullptr, DeploymentOptions::None); - deploymentOperation.get(); - - int returnValue = 0; - // Check the status of the operation - if (deploymentOperation.Status() == AsyncStatus::Error) - { - auto deploymentResult{ deploymentOperation.GetResults() }; - auto errorCode = deploymentOperation.ErrorCode(); - auto errorText = deploymentResult.ErrorText().c_str(); - returnValue = 1; - } - else if (deploymentOperation.Status() == AsyncStatus::Canceled) - { - returnValue = 1; - } - else if (deploymentOperation.Status() == AsyncStatus::Completed) - { - returnValue = 1; - } - else - { - returnValue = 1; - } - return returnValue; - - // Other progress and error-handling code omitted for brevity... - } - catch (...) - { - - } - - return true; - } // Return the localized display name of the powertoy @@ -239,13 +271,16 @@ public: // Enable the powertoy virtual void enable() { - std::wstring path = get_module_folderpath(g_hInst); - std::wstring packageUri = path + L"\\PowerRenameContextMenuPackage.msix"; - //std::wstring externalLocation = L"C:\\Users\\stefan\\Projects\\PowerToys\\x64\\Debug\\modules\\PowerRename"; - //std::wstring packageUri = L"C:\\Users\\stefan\\Projects\\PowerToys\\src\\modules\\powerrename\\PowerRenameContextMenu\\MyPackage.msix"; - registerSparsePackage(path, packageUri); Logger::info(L"PowerRename enabled"); m_enabled = true; + + if (IsWindows11()) + { + std::wstring path = get_module_folderpath(g_hInst); + std::wstring packageUri = path + L"\\PowerRenameContextMenuPackage.msix"; + RegisterSparsePackage(path, packageUri); + } + save_settings(); }