wl_base_help_plugin.cpp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. #include "wl_base_help_plugin.h"
  2. // This must be included before many other Windows headers.
  3. #include <windows.h>
  4. #include <tlhelp32.h>
  5. #include <string>
  6. // For getPlatformVersion; remove unless needed for your plugin implementation.
  7. #include <VersionHelpers.h>
  8. #include <flutter/method_channel.h>
  9. #include <flutter/plugin_registrar_windows.h>
  10. #include <flutter/standard_method_codec.h>
  11. #include <memory>
  12. #include <sstream>
  13. typedef LONG NTSTATUS, * PNTSTATUS;
  14. #define STATUS_SUCCESS (0x00000000)
  15. typedef NTSTATUS(WINAPI* RtlGetVersionPtr)(PRTL_OSVERSIONINFOW);
  16. RTL_OSVERSIONINFOW GetRealOSVersion() {
  17. HMODULE hMod = ::GetModuleHandleW(L"ntdll.dll");
  18. if (hMod) {
  19. RtlGetVersionPtr fnRtlGetVersion = (RtlGetVersionPtr)::GetProcAddress(hMod, "RtlGetVersion");
  20. if (fnRtlGetVersion != nullptr) {
  21. RTL_OSVERSIONINFOW rovi = { 0 };
  22. rovi.dwOSVersionInfoSize = sizeof(rovi);
  23. if (STATUS_SUCCESS == fnRtlGetVersion(&rovi)) {
  24. return rovi;
  25. }
  26. }
  27. }
  28. RTL_OSVERSIONINFOW rovi = { 0 };
  29. return rovi;
  30. }
  31. bool IsWindows11OrGreater() {
  32. RTL_OSVERSIONINFOW rovi = GetRealOSVersion();
  33. return (rovi.dwMajorVersion > 10) ||
  34. (rovi.dwMajorVersion == 10 && rovi.dwBuildNumber >= 22000);
  35. }
  36. void ShowConsole() {
  37. HWND consoleWindow = GetConsoleWindow();
  38. if (consoleWindow != NULL) {
  39. ShowWindow(consoleWindow, SW_SHOW);
  40. }
  41. }
  42. void HideConsole() {
  43. HWND consoleWindow = GetConsoleWindow();
  44. if (consoleWindow != NULL) {
  45. ShowWindow(consoleWindow, SW_HIDE);
  46. }
  47. }
  48. bool IsProcessRunning(const std::wstring& processName) {
  49. bool isRunning = false;
  50. HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  51. if (hSnapshot != INVALID_HANDLE_VALUE) {
  52. PROCESSENTRY32 pe32;
  53. pe32.dwSize = sizeof(PROCESSENTRY32);
  54. if (Process32First(hSnapshot, &pe32)) {
  55. do {
  56. if (processName == pe32.szExeFile) {
  57. isRunning = true;
  58. break;
  59. }
  60. } while (Process32Next(hSnapshot, &pe32));
  61. }
  62. CloseHandle(hSnapshot);
  63. }
  64. return isRunning;
  65. }
  66. void KillProcess(const std::wstring& processName) {
  67. HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  68. if (hSnapshot != INVALID_HANDLE_VALUE) {
  69. PROCESSENTRY32 pe32;
  70. pe32.dwSize = sizeof(PROCESSENTRY32);
  71. if (Process32First(hSnapshot, &pe32)) {
  72. do {
  73. if (processName == pe32.szExeFile) {
  74. HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pe32.th32ProcessID);
  75. if (hProcess != NULL) {
  76. TerminateProcess(hProcess, 0);
  77. CloseHandle(hProcess);
  78. break;
  79. }
  80. }
  81. } while (Process32Next(hSnapshot, &pe32));
  82. }
  83. CloseHandle(hSnapshot);
  84. }
  85. }
  86. namespace wl_base_help {
  87. // static
  88. void WlBaseHelpPlugin::RegisterWithRegistrar(
  89. flutter::PluginRegistrarWindows *registrar) {
  90. auto channel =
  91. std::make_unique<flutter::MethodChannel<flutter::EncodableValue>>(
  92. registrar->messenger(), "wl_base_help",
  93. &flutter::StandardMethodCodec::GetInstance());
  94. auto plugin = std::make_unique<WlBaseHelpPlugin>(registrar);
  95. channel->SetMethodCallHandler(
  96. [plugin_pointer = plugin.get()](const auto &call, auto result) {
  97. plugin_pointer->HandleMethodCall(call, std::move(result));
  98. });
  99. registrar->AddPlugin(std::move(plugin));
  100. }
  101. WlBaseHelpPlugin::WlBaseHelpPlugin(flutter::PluginRegistrarWindows* registrar) : registrar(registrar) {}
  102. WlBaseHelpPlugin::~WlBaseHelpPlugin() {}
  103. void WlBaseHelpPlugin::HandleMethodCall(
  104. const flutter::MethodCall<flutter::EncodableValue>& method_call,
  105. std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
  106. if (method_call.method_name().compare("isProcessRunning") == 0) {
  107. const auto* arguments = std::get_if<flutter::EncodableMap>(method_call.arguments());
  108. auto processName = std::get<std::string>(arguments->find(flutter::EncodableValue("processName"))->second);
  109. bool isRunning = IsProcessRunning(std::wstring(processName.begin(), processName.end()));
  110. result->Success(flutter::EncodableValue(isRunning));
  111. }
  112. else if (method_call.method_name().compare("killProcess") == 0) {
  113. const auto* arguments = std::get_if<flutter::EncodableMap>(method_call.arguments());
  114. auto processName = std::get<std::string>(arguments->find(flutter::EncodableValue("processName"))->second);
  115. KillProcess(std::wstring(processName.begin(), processName.end()));
  116. result->Success();
  117. }
  118. else if (method_call.method_name().compare("showConsole") == 0) {
  119. ShowConsole();
  120. result->Success();
  121. }
  122. else if (method_call.method_name().compare("hideConsole") == 0) {
  123. HideConsole();
  124. result->Success();
  125. }else if (method_call.method_name().compare("runAsAdministrator") == 0) {
  126. HWND hwnd = GetMainWindow();
  127. // 调用您的提权逻辑,传递 hwnd
  128. TryRunAsAdmin(hwnd, result);
  129. //result->Success(flutter::EncodableValue(true));
  130. }
  131. else if (method_call.method_name().compare("isRunningAsAdmin") == 0) {
  132. bool isAdmin = IsRunningAsAdmin();
  133. result->Success(flutter::EncodableValue(isAdmin));
  134. }
  135. else if (method_call.method_name().compare("getPlatformVersion") == 0) {
  136. std::ostringstream version_stream;
  137. version_stream << "Windows ";
  138. if (IsWindows11OrGreater()) {
  139. version_stream << "11+";
  140. }else if (IsWindows10OrGreater()) {
  141. version_stream << "10+";
  142. } else if (IsWindows8OrGreater()) {
  143. version_stream << "8";
  144. } else if (IsWindows7OrGreater()) {
  145. version_stream << "7";
  146. }
  147. result->Success(flutter::EncodableValue(version_stream.str()));
  148. } else {
  149. result->NotImplemented();
  150. }
  151. }
  152. HWND WlBaseHelpPlugin::GetMainWindow() {
  153. if (registrar)
  154. {
  155. windowHwnd = registrar->GetView()->GetNativeWindow();
  156. }
  157. return ::GetAncestor(windowHwnd, GA_ROOT);
  158. }
  159. bool WlBaseHelpPlugin::IsRunningAsAdmin() {
  160. BOOL isAdmin = FALSE;
  161. PSID adminGroup = NULL;
  162. SID_IDENTIFIER_AUTHORITY ntAuthority = SECURITY_NT_AUTHORITY;
  163. if (AllocateAndInitializeSid(&ntAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,
  164. DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0,
  165. &adminGroup)) {
  166. if (!CheckTokenMembership(NULL, adminGroup, &isAdmin)) {
  167. isAdmin = FALSE;
  168. }
  169. FreeSid(adminGroup);
  170. }
  171. return isAdmin != FALSE;
  172. }
  173. void WlBaseHelpPlugin::TryRunAsAdmin(HWND hwnd,
  174. std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>>& result){
  175. wchar_t szPath[MAX_PATH];
  176. if (GetModuleFileName(NULL, szPath, ARRAYSIZE(szPath))) {
  177. std::wstring params = L"--runas-admin";
  178. SHELLEXECUTEINFO sei = { sizeof(sei) };
  179. sei.lpVerb = L"runas";
  180. sei.lpFile = szPath;
  181. sei.lpParameters = params.c_str();
  182. sei.hwnd = hwnd;
  183. sei.nShow = SW_NORMAL;
  184. if (!ShellExecuteEx(&sei)) {
  185. DWORD dwError = GetLastError();
  186. if (dwError == ERROR_CANCELLED) {
  187. // 用户拒绝了 UAC 提示
  188. result->Error("UAC_CANCELLED", "User cancelled the UAC prompt.");
  189. } else {
  190. // 发生其他错误
  191. std::ostringstream errMsg;
  192. errMsg << "Failed to execute with error code: " << dwError;
  193. result->Error("EXECUTION_FAILED", errMsg.str());
  194. }
  195. } else {
  196. result->Success();
  197. ExitProcess(0); // 退出当前进程
  198. }
  199. } else {
  200. result->Error("GET_MODULE_FAILED", "Failed to get module file name.");
  201. }
  202. }
  203. } // namespace wl_base_help