Ejemplo n.º 1
0
            // Creates a ProcessInfo object from the IEndpointInfo. Attempts to get the command line using event pipe
            // if the endpoint information doesn't provide it. The cancelation token can be used to timebox this fallback
            // mechansim.
            public static async Task <ProcessInfo> FromEndpointInfoAsync(IEndpointInfo endpointInfo, CancellationToken extendedInfoCancellationToken)
            {
                if (null == endpointInfo)
                {
                    throw new ArgumentNullException(nameof(endpointInfo));
                }

                var client = new DiagnosticsClient(endpointInfo.Endpoint);

                string commandLine = endpointInfo.CommandLine;

                if (string.IsNullOrEmpty(commandLine))
                {
                    await using var processor = new DiagnosticsEventPipeProcessor(
                                    PipeMode.ProcessInfo,
                                    processInfoCallback: cmdLine => { commandLine = cmdLine; return(Task.CompletedTask); });

                    try
                    {
                        await processor.Process(
                            client,
                            endpointInfo.ProcessId,
                            Timeout.InfiniteTimeSpan,
                            extendedInfoCancellationToken);
                    }
                    catch
                    {
                    }
                }

                string processName = null;

                if (!string.IsNullOrEmpty(commandLine))
                {
                    // Get the process name from the command line
                    bool isWindowsProcess = false;
                    if (string.IsNullOrEmpty(endpointInfo.OperatingSystem))
                    {
                        // If operating system is null, the process is likely .NET Core 3.1 (which doesn't have the GetProcessInfo command).
                        // Since the underlying diagnostic communication channel used by the .NET runtime requires that the diagnostic process
                        // must be running on the same type of operating system as the target process (e.g. dotnet-monitor must be running on Windows
                        // if the target process is running on Windows), then checking the local operating system should be a sufficient heuristic
                        // to determine the operating system of the target process.
                        isWindowsProcess = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
                    }
                    else
                    {
                        isWindowsProcess = ProcessOperatingSystemWindowsValue.Equals(endpointInfo.OperatingSystem, StringComparison.OrdinalIgnoreCase);
                    }

                    string processPath = CommandLineHelper.ExtractExecutablePath(commandLine, isWindowsProcess);
                    if (!string.IsNullOrEmpty(processPath))
                    {
                        processName = Path.GetFileName(processPath);
                        if (isWindowsProcess)
                        {
                            // Remove the extension on Windows to match the behavior of Process.ProcessName
                            processName = Path.GetFileNameWithoutExtension(processName);
                        }
                    }
                }

                // The GetProcessInfo command will return "unknown" for values for which it does
                // not know the value, such as operating system and process architecture if the
                // process is running on one that is not predefined. Mimic the same behavior here
                // when the extra process information was not provided.
                return(new ProcessInfo(
                           client,
                           endpointInfo.RuntimeInstanceCookie,
                           endpointInfo.ProcessId,
                           processName ?? ProcessFieldUnknownValue,
                           commandLine ?? ProcessFieldUnknownValue,
                           endpointInfo.OperatingSystem ?? ProcessFieldUnknownValue,
                           endpointInfo.ProcessArchitecture ?? ProcessFieldUnknownValue));
            }
Ejemplo n.º 2
0
            // Creates a ProcessInfo object from the IEndpointInfo. Attempts to get the command line using event pipe
            // if the endpoint information doesn't provide it. The cancelation token can be used to timebox this fallback
            // mechansim.
            public static async Task <ProcessInfo> FromEndpointInfoAsync(IEndpointInfo endpointInfo, CancellationToken extendedInfoCancellationToken)
            {
                if (null == endpointInfo)
                {
                    throw new ArgumentNullException(nameof(endpointInfo));
                }

                var client = new DiagnosticsClient(endpointInfo.Endpoint);

                string commandLine = endpointInfo.CommandLine;

                if (string.IsNullOrEmpty(commandLine))
                {
                    try
                    {
                        var infoSettings = new EventProcessInfoPipelineSettings
                        {
                            Duration = Timeout.InfiniteTimeSpan,
                        };

                        await using var pipeline = new EventProcessInfoPipeline(client, infoSettings,
                                                                                (cmdLine, token) => { commandLine = cmdLine; return(Task.CompletedTask); });

                        await pipeline.RunAsync(extendedInfoCancellationToken);
                    }
                    catch
                    {
                    }
                }

                string processName = null;

                if (!string.IsNullOrEmpty(commandLine))
                {
                    // Get the process name from the command line
                    bool isWindowsProcess = false;
                    if (string.IsNullOrEmpty(endpointInfo.OperatingSystem))
                    {
                        // If operating system is null, the process is likely .NET Core 3.1 (which doesn't have the GetProcessInfo command).
                        // Since the underlying diagnostic communication channel used by the .NET runtime requires that the diagnostic process
                        // must be running on the same type of operating system as the target process (e.g. dotnet-monitor must be running on Windows
                        // if the target process is running on Windows), then checking the local operating system should be a sufficient heuristic
                        // to determine the operating system of the target process.
                        isWindowsProcess = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
                    }
                    else
                    {
                        isWindowsProcess = ProcessOperatingSystemWindowsValue.Equals(endpointInfo.OperatingSystem, StringComparison.OrdinalIgnoreCase);
                    }

                    string processPath = CommandLineHelper.ExtractExecutablePath(commandLine, isWindowsProcess);
                    if (!string.IsNullOrEmpty(processPath))
                    {
                        processName = Path.GetFileName(processPath);
                        if (isWindowsProcess)
                        {
                            // Remove the extension on Windows to match the behavior of Process.ProcessName
                            processName = Path.GetFileNameWithoutExtension(processName);
                        }
                    }
                }

                return(new ProcessInfo(
                           endpointInfo,
                           commandLine,
                           processName));
            }