Execute powershell directly
This commit is contained in:
		
							parent
							
								
									9eb993eb65
								
							
						
					
					
						commit
						f7b65abc15
					
				|  | @ -62,7 +62,7 @@ | ||||||
| -export([pget/2, pget/3, pupdate/3, pget_or_die/2, pmerge/3, pset/3, plmerge/2]). | -export([pget/2, pget/3, pupdate/3, pget_or_die/2, pmerge/3, pset/3, plmerge/2]). | ||||||
| -export([format_message_queue/2]). | -export([format_message_queue/2]). | ||||||
| -export([append_rpc_all_nodes/4, append_rpc_all_nodes/5]). | -export([append_rpc_all_nodes/4, append_rpc_all_nodes/5]). | ||||||
| -export([os_cmd/1]). | -export([os_cmd/1, pwsh_cmd/1]). | ||||||
| -export([is_os_process_alive/1]). | -export([is_os_process_alive/1]). | ||||||
| -export([version/0, otp_release/0, platform_and_version/0, otp_system_version/0, | -export([version/0, otp_release/0, platform_and_version/0, otp_system_version/0, | ||||||
|          rabbitmq_and_erlang_versions/0, which_applications/0]). |          rabbitmq_and_erlang_versions/0, which_applications/0]). | ||||||
|  | @ -1156,6 +1156,14 @@ os_cmd(Command) -> | ||||||
|             end |             end | ||||||
|     end. |     end. | ||||||
| 
 | 
 | ||||||
|  | pwsh_cmd(Command) -> | ||||||
|  |     case os:type() of | ||||||
|  |         {win32, _} -> | ||||||
|  |             do_pwsh_cmd(Command); | ||||||
|  |         _ -> | ||||||
|  |             {error, invalid_os_type} | ||||||
|  |     end. | ||||||
|  | 
 | ||||||
| is_os_process_alive(Pid) -> | is_os_process_alive(Pid) -> | ||||||
|     with_os([{unix, fun () -> |     with_os([{unix, fun () -> | ||||||
|                             run_ps(Pid) =:= 0 |                             run_ps(Pid) =:= 0 | ||||||
|  | @ -1164,26 +1172,17 @@ is_os_process_alive(Pid) -> | ||||||
|                              PidS = rabbit_data_coercion:to_list(Pid), |                              PidS = rabbit_data_coercion:to_list(Pid), | ||||||
|                              case os:find_executable("tasklist.exe") of |                              case os:find_executable("tasklist.exe") of | ||||||
|                                  false -> |                                  false -> | ||||||
|                                      Cmd = |                                      Cmd = format("(Get-Process -Id ~ts).ProcessName", [PidS]), | ||||||
|                                      format( |                                      {ok, Res} = pwsh_cmd(Cmd), | ||||||
|                                        "powershell.exe -NoLogo -NoProfile -NonInteractive -Command " |  | ||||||
|                                        "\"(Get-Process -Id ~ts).ProcessName\"", |  | ||||||
|                                        [PidS]), |  | ||||||
|                                      Res = |  | ||||||
|                                      os_cmd(Cmd ++ " 2>&1") -- [$\r, $\n], |  | ||||||
|                                      case Res of |                                      case Res of | ||||||
|                                          "erl"  -> true; |                                          "erl"  -> true; | ||||||
|                                          "werl" -> true; |                                          "werl" -> true; | ||||||
|                                          _      -> false |                                          _      -> false | ||||||
|                                      end; |                                      end; | ||||||
|                                  _ -> |                                  TasklistExe -> | ||||||
|                                      Cmd = |                                      Args = ["/nh", "/fi", "pid eq " ++ PidS], | ||||||
|                                      "tasklist /nh /fi " |                                      {ok, Res} = do_win32_cmd(TasklistExe, Args), | ||||||
|                                      "\"pid eq " ++ PidS ++ "\"", |                                      match =:= re:run(Res, "erl\\.exe", [{capture, none}]) | ||||||
|                                      Res = os_cmd(Cmd ++ " 2>&1"), |  | ||||||
|                                      match =:= re:run(Res, |  | ||||||
|                                                       "erl\\.exe", |  | ||||||
|                                                       [{capture, none}]) |  | ||||||
|                              end |                              end | ||||||
|                      end}]). |                      end}]). | ||||||
| 
 | 
 | ||||||
|  | @ -1472,3 +1471,82 @@ whereis_name(Name) -> | ||||||
| 
 | 
 | ||||||
| %% End copypasta from gen_server2.erl | %% End copypasta from gen_server2.erl | ||||||
| %% ------------------------------------------------------------------------- | %% ------------------------------------------------------------------------- | ||||||
|  | 
 | ||||||
|  | %% This will execute a Powershell command that is expected to return a | ||||||
|  | %% single-line result. Output lines can't exceed 512 bytes. If multiple | ||||||
|  | %% lines are returned by the command, these functions will return the | ||||||
|  | %% last line. | ||||||
|  | %% | ||||||
|  | %% Inspired by os:cmd/1 in lib/kernel/src/os.erl | ||||||
|  | do_pwsh_cmd(Command) -> | ||||||
|  |     Pwsh = find_powershell(), | ||||||
|  |     A1 = ["-NoLogo", | ||||||
|  |           "-NonInteractive", | ||||||
|  |           "-NoProfile", | ||||||
|  |           "-InputFormat", "Text", | ||||||
|  |           "-OutputFormat", "Text", | ||||||
|  |           "-Command", Command], | ||||||
|  |     do_win32_cmd(Pwsh, A1). | ||||||
|  | 
 | ||||||
|  | do_win32_cmd(Exe, Args) -> | ||||||
|  |     SystemRootDir = os:getenv("SystemRoot", "/"), | ||||||
|  |     % Note: 'hide' must be used or this will not work! | ||||||
|  |     A0 = [exit_status, stderr_to_stdout, in, hide, | ||||||
|  |           {cd, SystemRootDir}, {line, 512}, {arg0, Exe}, {args, Args}], | ||||||
|  |     Port = erlang:open_port({spawn_executable, Exe}, A0), | ||||||
|  |     MonRef = erlang:monitor(port, Port), | ||||||
|  |     Result = win32_cmd_receive(Port, MonRef, <<>>), | ||||||
|  |     true = erlang:demonitor(MonRef, [flush]), | ||||||
|  |     Result. | ||||||
|  | 
 | ||||||
|  | win32_cmd_receive(Port, MonRef, Data0) -> | ||||||
|  |     receive | ||||||
|  |         {Port, {exit_status, 0}} -> | ||||||
|  |             win32_cmd_receive_finish(Port, MonRef), | ||||||
|  |             {ok, Data0}; | ||||||
|  |         {Port, {exit_status, Status}} -> | ||||||
|  |             win32_cmd_receive_finish(Port, MonRef), | ||||||
|  |             {error, {exit_status, Status}}; | ||||||
|  |         {Port, {data, {eol, Data1}}} -> | ||||||
|  |             Data2 = string:trim(Data1), | ||||||
|  |             win32_cmd_receive(Port, MonRef, Data2); | ||||||
|  |         {'DOWN', MonRef, _, _, _} -> | ||||||
|  |             flush_exit(Port), | ||||||
|  |             {error, nodata} | ||||||
|  |     after 5000 -> | ||||||
|  |               {error, timeout} | ||||||
|  |     end. | ||||||
|  | 
 | ||||||
|  | win32_cmd_receive_finish(Port, MonRef) -> | ||||||
|  |     catch erlang:port_close(Port), | ||||||
|  |     flush_until_down(Port, MonRef). | ||||||
|  | 
 | ||||||
|  | flush_until_down(Port, MonRef) -> | ||||||
|  |     receive | ||||||
|  |         {Port, {data, _Bytes}} -> | ||||||
|  |             flush_until_down(Port, MonRef); | ||||||
|  |         {'DOWN', MonRef, _, _, _} -> | ||||||
|  |             flush_exit(Port) | ||||||
|  |     after 500 -> | ||||||
|  |               flush_exit(Port) | ||||||
|  |     end. | ||||||
|  | 
 | ||||||
|  | flush_exit(Port) -> | ||||||
|  |     receive | ||||||
|  |         {'EXIT', Port, _} -> ok | ||||||
|  |     after 0 -> | ||||||
|  |               ok | ||||||
|  |     end. | ||||||
|  | 
 | ||||||
|  | find_powershell() -> | ||||||
|  |     case os:find_executable("pwsh.exe") of | ||||||
|  |         false -> | ||||||
|  |             case os:find_executable("powershell.exe") of | ||||||
|  |                 false -> | ||||||
|  |                     "powershell.exe"; | ||||||
|  |                 PowershellExe -> | ||||||
|  |                     PowershellExe | ||||||
|  |             end; | ||||||
|  |         PwshExe -> | ||||||
|  |             PwshExe | ||||||
|  |     end. | ||||||
|  |  | ||||||
|  | @ -146,9 +146,9 @@ find_files_line([_H | T]) -> | ||||||
|     find_files_line(T). |     find_files_line(T). | ||||||
| 
 | 
 | ||||||
| get_used_fd_via_powershell(Pid) -> | get_used_fd_via_powershell(Pid) -> | ||||||
|     PwshExe = find_powershell(), |     Cmd = "Get-Process -Id " ++ Pid ++ " | Select-Object -ExpandProperty HandleCount", | ||||||
|     Handle = rabbit_misc:os_cmd("\"" ++ PwshExe ++ "\" -NoLogo -NoProfile -NonInteractive -Command (Get-Process -Id " ++ Pid ++ ").Handles"), |     {ok, Result} = rabbit_misc:pwsh_cmd(Cmd), | ||||||
|     list_to_integer(string:trim(Handle)). |     list_to_integer(Result). | ||||||
| 
 | 
 | ||||||
| -define(SAFE_CALL(Fun, NoProcFailResult), | -define(SAFE_CALL(Fun, NoProcFailResult), | ||||||
|     try |     try | ||||||
|  | @ -430,16 +430,3 @@ get_fhc_stats() -> | ||||||
| 
 | 
 | ||||||
| get_ra_io_metrics() -> | get_ra_io_metrics() -> | ||||||
|     lists:sort(ets:tab2list(ra_io_metrics)). |     lists:sort(ets:tab2list(ra_io_metrics)). | ||||||
| 
 |  | ||||||
| find_powershell() -> |  | ||||||
|     case os:find_executable("pwsh.exe") of |  | ||||||
|         false -> |  | ||||||
|             case os:find_executable("powershell.exe") of |  | ||||||
|                 false -> |  | ||||||
|                     "powershell.exe"; |  | ||||||
|                 PowershellExe -> |  | ||||||
|                     PowershellExe |  | ||||||
|             end; |  | ||||||
|         PwshExe -> |  | ||||||
|             PwshExe |  | ||||||
|     end. |  | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue