セージ の メモ書き

メモこそ命の恩人だ

TCP/UDPポートNo.からプロセス情報を取得

Step1:コマンド実行

以下で、コマンドを実行し、結果を取得できるようにする。

/// <summary>
/// コマンドを実行する
/// </summary>
/// <param name="commandName">コマンド名</param>
/// <param name="commandArgument">コマンド引数</param>
/// <returns>実行結果</returns>
private IEnumerable<string> RunCommand(string commandName, string commandArgument)
{
    using (var process = new System.Diagnostics.Process())
    {
        process.StartInfo = new System.Diagnostics.ProcessStartInfo()
        {
            FileName = commandName,
            Arguments = commandArgument,
            UseShellExecute = false,
            RedirectStandardInput = false,
            RedirectStandardOutput = true,  // 出力有効化
            CreateNoWindow = true    // ウィンドウ非表示
        };
        process.Start();
        while (!process.StandardOutput.EndOfStream)
        {
            yield return process.StandardOutput.ReadLine()?.Trim();
        }
        process.Close();
    }
}

Step2:通信ポート情報の取得

以下で、UDPポートを使用中のプロセス情報がわかる。

/// <summary>
/// 指定UDPポートを使用中のプロセス情報を取得する
/// </summary>
/// <param name="udpPort">UDPポート</param>
/// <param name="defaultString">返却用の既定文字列</param>
/// <returns>プロセス情報(netstatの結果)</returns>
/// <remarks>
/// netstatについて、"netstat -a -b -n -p UDP" で取得した場合、
/// プロセス名に[システム]と結果が返り、コマンドプロンプトとの結果と一致しない。
/// そのため、PIDからプロセス情報を判定する。
/// </remarks>
private string GetUdpPortInfo(int udpPort, string defaultString = "---")
{
    // UDPポートに対応するPIDの取得
    // https://docs.microsoft.com/ja-jp/windows-server/administration/windows-commands/netstat
    // - a:全ポートの表示
    // - n:IPアドレスのまま表示(名前解決なし)
    // - o:PIDの表示
    // - p:プロトコル指定
    var netstatResult = RunCommand("netstat.exe", "-anop UDP")?.FirstOrDefault(x => x.Contains($":{udpPort.ToString()} "));
    var pidString = netstatResult?.Split(' ')?.LastOrDefault();
    if (!int.TryParse(pidString, out var pid))
    {
        logger.LogError($"UDPポート取得エラー <netstat:{netstatResult}, PID:{pidString}>");
        return defaultString;
    }

    // プロセス名の取得
    var processName = System.Diagnostics.Process.GetProcessById(pid)?.ProcessName;
    if (processName.IsNullOrEmpty())
    {
        logger.LogError($"UDPポート対応プロセス取得エラー <PID:{pid}>");
        return defaultString;
    }

    // サービス名の取得
    // https://docs.microsoft.com/ja-jp/windows-server/administration/windows-commands/tasklist
    var tasklistResult = RunCommand("tasklist.exe", $@"/svc /fi ""PID eq {pid.ToString()}""")?.LastOrDefault();
    var serviceName = tasklistResult?.Split(' ')?.LastOrDefault();

    // プロセス情報の返却
    return $"{processName}.exe ({pid}), service:{serviceName}";
}

以上