79 lines
2.7 KiB
C#
79 lines
2.7 KiB
C#
using System;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Runtime.InteropServices;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace JJServiceManager
|
|
{
|
|
/// <summary>
|
|
/// Windows 명령(schtasks, netsh 등)을 실행하고 출력을 읽음.
|
|
/// 시스템 설정에 따라 출력이 UTF-8 또는 CP949(OEM)일 수 있어,
|
|
/// 바이트로 받은 뒤 UTF-8로 올바르게 읽히면 UTF-8, 아니면 시스템 OEM 코드페이지로 해석함.
|
|
/// </summary>
|
|
public static class ConsoleRunner
|
|
{
|
|
[DllImport("kernel32.dll")]
|
|
private static extern uint GetOEMCP();
|
|
|
|
public static (int exitCode, string output) Run(string file, string args, int timeoutMs = 15000)
|
|
{
|
|
try
|
|
{
|
|
var psi = new ProcessStartInfo(file, args)
|
|
{
|
|
UseShellExecute = false,
|
|
CreateNoWindow = true,
|
|
RedirectStandardOutput = true,
|
|
RedirectStandardError = true
|
|
};
|
|
using var p = Process.Start(psi);
|
|
var outTask = ReadAllAsync(p.StandardOutput.BaseStream);
|
|
var errTask = ReadAllAsync(p.StandardError.BaseStream);
|
|
if (!p.WaitForExit(timeoutMs))
|
|
{
|
|
try { p.Kill(); } catch { }
|
|
return (-1, "시간 초과");
|
|
}
|
|
var bytes = Combine(outTask.Result, errTask.Result);
|
|
return (p.ExitCode, Decode(bytes).Trim());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return (-1, ex.Message);
|
|
}
|
|
}
|
|
|
|
private static async Task<byte[]> ReadAllAsync(Stream s)
|
|
{
|
|
using var ms = new MemoryStream();
|
|
await s.CopyToAsync(ms).ConfigureAwait(false);
|
|
return ms.ToArray();
|
|
}
|
|
|
|
private static byte[] Combine(byte[] a, byte[] b)
|
|
{
|
|
var r = new byte[a.Length + b.Length];
|
|
Buffer.BlockCopy(a, 0, r, 0, a.Length);
|
|
Buffer.BlockCopy(b, 0, r, a.Length, b.Length);
|
|
return r;
|
|
}
|
|
|
|
public static string Decode(byte[] bytes)
|
|
{
|
|
if (bytes.Length == 0) return "";
|
|
try
|
|
{
|
|
var strict = new UTF8Encoding(false, throwOnInvalidBytes: true);
|
|
return strict.GetString(bytes);
|
|
}
|
|
catch { }
|
|
try { return Encoding.GetEncoding((int)GetOEMCP()).GetString(bytes); }
|
|
catch { }
|
|
try { return Encoding.GetEncoding(949).GetString(bytes); }
|
|
catch { return Encoding.UTF8.GetString(bytes); }
|
|
}
|
|
}
|
|
}
|