Skip to content

Commit

Permalink
Process extension (#304)
Browse files Browse the repository at this point in the history
* - Renamed `ExtensionsSystem.cs` to `ExtensionsGeneral.cs`
- Removed warnings from `ExtensionsGeneral.cs` file
- Extracted `ProcessExtensions` class to separate file
- Return null when non windows computer attempts to retrieve parent process
- Updated VSCode tasks

* Addressing review comments
  • Loading branch information
Allcharles authored Mar 19, 2020
1 parent c72b759 commit 48371ec
Show file tree
Hide file tree
Showing 7 changed files with 287 additions and 170 deletions.
79 changes: 48 additions & 31 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,58 @@
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/src/AnalysisPrograms/AnalysisPrograms.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/src/AnalysisPrograms/AnalysisPrograms.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile",
"group": {
"kind": "build",
"isDefault": true
}
},
{
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/src/AnalysisPrograms/AnalysisPrograms.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
"label": "test",
"command": "dotnet",
"type": "process",
"args": [
"test"
],
"problemMatcher": "$msCompile",
"group": {
"kind": "test",
"isDefault": true
}
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"${workspaceFolder}/src/AnalysisPrograms/AnalysisPrograms.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/src/AnalysisPrograms/AnalysisPrograms.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"${workspaceFolder}/src/AnalysisPrograms/AnalysisPrograms.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
}
]
}
110 changes: 110 additions & 0 deletions src/Acoustics.Shared/Extensions/ProcessExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ProcessExtensions.cs" company="QutEcoacoustics">
// All code in this file and all associated files are the copyright and property of the QUT Ecoacoustics Research Group (formerly MQUTeR, and formerly QUT Bioacoustics Research Group).
// </copyright>
// <summary>
// Defines the Utilities type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace System
{
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.InteropServices;
using static Acoustics.Shared.AppConfigHelper;

public static class ProcessExtensions
{
/// <summary>
/// A utility class to determine a process parent.
/// http://stackoverflow.com/a/3346055.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct ParentProcessUtilities
{
#if DEBUG
#pragma warning disable SA1310
// These members must match PROCESS_BASIC_INFORMATION
internal IntPtr Reserved1;

internal IntPtr PebBaseAddress;

internal IntPtr Reserved2_0;

internal IntPtr Reserved2_1;

internal IntPtr UniqueProcessId;

internal IntPtr InheritedFromUniqueProcessId;
#pragma warning restore

// TODO This import is windows only, replace with .NET Core API
[DllImport("ntdll.dll")]
private static extern int NtQueryInformationProcess(
IntPtr processHandle,
int processInformationClass,
ref ParentProcessUtilities processInformation,
int processInformationLength,
out int returnLength);

#pragma warning disable SA1202
/// <summary>
/// !WARNING Windows OS only
/// Gets the parent process of the current process.
/// Linux support blocked by https://github.com/dotnet/runtime/issues/24423.
/// </summary>
/// <returns>An instance of the Process class.</returns>
public static Process GetParentProcess()
{
return GetParentProcess(Process.GetCurrentProcess().Handle);
}

/// <summary>
/// !WARNING Windows OS only
/// Gets the parent process of specified process.
/// </summary>
/// <param name="id">The process id.</param>
/// <returns>An instance of the Process class.</returns>
public static Process GetParentProcess(int id)
{
Process process = Process.GetProcessById(id);
return GetParentProcess(process.Handle);
}

/// <summary>
/// !WARNING Windows OS only
/// Gets the parent process of a specified process.
/// </summary>
/// <param name="handle">The process handle.</param>
/// <returns>An instance of the Process class.</returns>
public static Process GetParentProcess(IntPtr handle)
{
if (!IsWindows)
{
return null;
}

ParentProcessUtilities pbi = default;

int status = NtQueryInformationProcess(handle, 0, ref pbi, Marshal.SizeOf(pbi), out var _);
if (status != 0)
{
throw new Win32Exception(status);
}

try
{
return Process.GetProcessById(pbi.InheritedFromUniqueProcessId.ToInt32());
}
catch (ArgumentException)
{
// not found
return null;
}
}
#pragma warning restore
#endif
}
}
}
Loading

0 comments on commit 48371ec

Please sign in to comment.