From 6eae9b79470bb179d466c642c1684c749ef9a263 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E6=97=AD?= Date: Wed, 8 May 2024 11:10:21 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=BC=A9=E6=94=BE=E5=89=8D=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E4=BF=AE=E5=A4=8D=E8=A7=A6=E6=8E=A7=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Magpie.App/HomeViewModel.cpp | 46 +-------- src/Magpie.App/Resources.language-en-US.resw | 2 +- .../Resources.language-zh-Hans.resw | 2 +- src/Magpie.App/ScalingService.cpp | 38 +------- src/Magpie.App/TouchHelper.cpp | 96 ++++++++++++++++++- src/Magpie.App/TouchHelper.h | 1 + 6 files changed, 105 insertions(+), 80 deletions(-) diff --git a/src/Magpie.App/HomeViewModel.cpp b/src/Magpie.App/HomeViewModel.cpp index 00bb5bc1..7be387b4 100644 --- a/src/Magpie.App/HomeViewModel.cpp +++ b/src/Magpie.App/HomeViewModel.cpp @@ -9,7 +9,7 @@ #include "StrUtils.h" #include "UpdateService.h" #include "CommonSharedConstants.h" -#include "Logger.h" +#include "TouchHelper.h" namespace winrt::Magpie::App::implementation { @@ -187,33 +187,12 @@ void HomeViewModel::RemindMeLater() { } bool HomeViewModel::IsTouchSupportEnabled() const noexcept { - wil::unique_cotaskmem_string system32Dir; - HRESULT hr = SHGetKnownFolderPath( - FOLDERID_System, KF_FLAG_DEFAULT, NULL, system32Dir.put()); - if (FAILED(hr)) { - Logger::Get().ComError("SHGetKnownFolderPath 失败", hr); - return false; - } - - std::wstring path = StrUtils::Concat(system32Dir.get(), - L"\\Magpie\\", CommonSharedConstants::TOUCH_HELPER_EXE_NAME); - if (!Win32Utils::FileExists(path.c_str())) { - return false; - } - - path += L".ver"; - - std::vector version; - if (!Win32Utils::ReadFile(path.c_str(), version) || version.size() != 4) { - Logger::Get().Error("读取版本号失败"); - return false; - } - - return *(uint32_t*)version.data() == CommonSharedConstants::TOUCH_HELPER_VERSION; + // 不检查版本号是否匹配 + return TouchHelper::IsTouchSupportEnabled(); } fire_and_forget HomeViewModel::IsTouchSupportEnabled(bool value) { - if (IsTouchSupportEnabled() == value) { + if (TouchHelper::IsTouchSupportEnabled() == value) { co_return; } @@ -224,22 +203,7 @@ fire_and_forget HomeViewModel::IsTouchSupportEnabled(bool value) { // 见 https://github.com/microsoft/microsoft-ui-xaml/issues/4952 co_await resume_background(); - SHELLEXECUTEINFO execInfo{ - .cbSize = sizeof(execInfo), - .fMask = SEE_MASK_NOASYNC | SEE_MASK_NOCLOSEPROCESS, - .lpVerb = L"runas", - .lpFile = Win32Utils::GetExePath().c_str(), - .lpParameters = value ? L" -r" : L" -ur" - }; - - if (ShellExecuteEx(&execInfo)) { - wil::unique_process_handle hProcess(execInfo.hProcess); - if (hProcess) { - wil::handle_wait(hProcess.get()); - } - } else if (GetLastError() != ERROR_CANCELLED) { - Logger::Get().Win32Error("ShellExecuteEx 失败"); - } + TouchHelper::IsTouchSupportEnabled(value); co_await dispatcher; diff --git a/src/Magpie.App/Resources.language-en-US.resw b/src/Magpie.App/Resources.language-en-US.resw index bf643acc..5b3c6e63 100644 --- a/src/Magpie.App/Resources.language-en-US.resw +++ b/src/Magpie.App/Resources.language-en-US.resw @@ -832,7 +832,7 @@ Touch support - + If touch support fails, Magpie may request administrator privileges before scaling to perform repairs. \ No newline at end of file diff --git a/src/Magpie.App/Resources.language-zh-Hans.resw b/src/Magpie.App/Resources.language-zh-Hans.resw index a7ac6fee..fd51d4c2 100644 --- a/src/Magpie.App/Resources.language-zh-Hans.resw +++ b/src/Magpie.App/Resources.language-zh-Hans.resw @@ -832,7 +832,7 @@ 触控支持 - + 如果触控支持失效,Magpie 可能会在缩放前请求管理员权限以执行修复。 \ No newline at end of file diff --git a/src/Magpie.App/ScalingService.cpp b/src/Magpie.App/ScalingService.cpp index 8847fc2a..5df2dc69 100644 --- a/src/Magpie.App/ScalingService.cpp +++ b/src/Magpie.App/ScalingService.cpp @@ -9,8 +9,7 @@ #include "Logger.h" #include "EffectsService.h" #include -#include "CommonSharedConstants.h" -#include "StrUtils.h" +#include "TouchHelper.h" using namespace ::Magpie::Core; using namespace winrt; @@ -224,39 +223,6 @@ fire_and_forget ScalingService::_ScalingRuntime_IsRunningChanged(bool isRunning) IsRunningChanged.Invoke(isRunning); } -static void TryLaunchTouchHelper() noexcept { - wil::unique_cotaskmem_string system32Dir; - HRESULT hr = SHGetKnownFolderPath( - FOLDERID_System, KF_FLAG_DEFAULT, NULL, system32Dir.put()); - if (FAILED(hr)) { - Logger::Get().ComError("SHGetKnownFolderPath 失败", hr); - return; - } - - std::wstring path = StrUtils::Concat(system32Dir.get(), - L"\\Magpie\\", CommonSharedConstants::TOUCH_HELPER_EXE_NAME); - if (!Win32Utils::FileExists(path.c_str())) { - // 未启用触控支持 - return; - } - - wil::unique_mutex_nothrow hSingleInstanceMutex; - - bool alreadyExists = false; - if (hSingleInstanceMutex.try_create( - CommonSharedConstants::TOUCH_HELPER_SINGLE_INSTANCE_MUTEX_NAME, - CREATE_MUTEX_INITIAL_OWNER, - MUTEX_ALL_ACCESS, - nullptr, - &alreadyExists - ) && !alreadyExists) { - hSingleInstanceMutex.ReleaseMutex(); - - // TouchHelper 未在运行则启动它 - Win32Utils::ShellOpen(path.c_str()); - } -} - bool ScalingService::_StartScale(HWND hWnd, const Profile& profile) { if (profile.scalingMode < 0) { return false; @@ -275,7 +241,7 @@ bool ScalingService::_StartScale(HWND hWnd, const Profile& profile) { } } - TryLaunchTouchHelper(); + TouchHelper::TryLaunchTouchHelper(); options.graphicsCard = profile.graphicsCard; options.captureMethod = profile.captureMethod; diff --git a/src/Magpie.App/TouchHelper.cpp b/src/Magpie.App/TouchHelper.cpp index 6802f2c3..79fab03d 100644 --- a/src/Magpie.App/TouchHelper.cpp +++ b/src/Magpie.App/TouchHelper.cpp @@ -1,13 +1,107 @@ #include "pch.h" #include "TouchHelper.h" +#include "Logger.h" +#include "StrUtils.h" +#include "Win32Utils.h" +#include "CommonSharedConstants.h" namespace winrt::Magpie::App { +static std::wstring GetTouchHelperPath() noexcept { + wil::unique_cotaskmem_string system32Dir; + HRESULT hr = SHGetKnownFolderPath( + FOLDERID_System, KF_FLAG_DEFAULT, NULL, system32Dir.put()); + if (FAILED(hr)) { + Logger::Get().ComError("SHGetKnownFolderPath 失败", hr); + return {}; + } + + return StrUtils::Concat(system32Dir.get(), + L"\\Magpie\\", CommonSharedConstants::TOUCH_HELPER_EXE_NAME); +} + bool TouchHelper::IsTouchSupportEnabled() noexcept { - return false; + // 不检查版本号 + return Win32Utils::FileExists(GetTouchHelperPath().c_str()); } void TouchHelper::IsTouchSupportEnabled(bool value) noexcept { + SHELLEXECUTEINFO execInfo{ + .cbSize = sizeof(execInfo), + .fMask = SEE_MASK_NOASYNC | SEE_MASK_NOCLOSEPROCESS, + .lpVerb = L"runas", + .lpFile = Win32Utils::GetExePath().c_str(), + .lpParameters = value ? L" -r" : L" -ur" + }; + + if (ShellExecuteEx(&execInfo)) { + wil::unique_process_handle hProcess(execInfo.hProcess); + if (hProcess) { + wil::handle_wait(hProcess.get()); + } + } else if (GetLastError() != ERROR_CANCELLED) { + Logger::Get().Win32Error("ShellExecuteEx 失败"); + } +} + +static bool CheckAndFixTouchHelper(std::wstring& path) noexcept { + // 检查版本号 + path += L".ver"; + + std::vector versionData; + + const auto checkVersion = [&]() { + if (!Win32Utils::ReadFile(path.c_str(), versionData)) { + Logger::Get().Error("读取版本号失败"); + } + + return versionData.size() == 4 && + *(uint32_t*)versionData.data() == CommonSharedConstants::TOUCH_HELPER_VERSION; + }; + + if (!checkVersion()) { + // 版本号不匹配,尝试修复,这会请求管理员权限 + TouchHelper::IsTouchSupportEnabled(true); + + if (!checkVersion()) { + // 修复失败 + return false; + } + } + + path.erase(path.size() - 4); + return true; +} + +void TouchHelper::TryLaunchTouchHelper() noexcept { + std::wstring path = GetTouchHelperPath(); + if (!Win32Utils::FileExists(path.c_str())) { + // 未启用触控支持 + return; + } + + wil::unique_mutex_nothrow hSingleInstanceMutex; + + bool alreadyExists = false; + if (hSingleInstanceMutex.try_create( + CommonSharedConstants::TOUCH_HELPER_SINGLE_INSTANCE_MUTEX_NAME, + CREATE_MUTEX_INITIAL_OWNER, + MUTEX_ALL_ACCESS, + nullptr, + &alreadyExists + ) && !alreadyExists) { + hSingleInstanceMutex.ReleaseMutex(); + + // TouchHelper 未在运行则启动它 + + // 检查版本是否匹配并尝试修复 + if (!CheckAndFixTouchHelper(path)) { + // 修复失败 + return; + } + + Win32Utils::ShellOpen(path.c_str()); + } } } diff --git a/src/Magpie.App/TouchHelper.h b/src/Magpie.App/TouchHelper.h index 2c2e4724..139c9eff 100644 --- a/src/Magpie.App/TouchHelper.h +++ b/src/Magpie.App/TouchHelper.h @@ -5,6 +5,7 @@ namespace winrt::Magpie::App { struct TouchHelper { static bool IsTouchSupportEnabled() noexcept; static void IsTouchSupportEnabled(bool value) noexcept; + static void TryLaunchTouchHelper() noexcept; }; }