diff --git a/src/Build/BackEnd/BuildManager/BuildManager.cs b/src/Build/BackEnd/BuildManager/BuildManager.cs
index 10cf3577bf1..7e72e4ebea8 100644
--- a/src/Build/BackEnd/BuildManager/BuildManager.cs
+++ b/src/Build/BackEnd/BuildManager/BuildManager.cs
@@ -759,8 +759,8 @@ private static void AttachDebugger()
#endif
case "2":
// Sometimes easier to attach rather than deal with JIT prompt
- Process currentProcess = Process.GetCurrentProcess();
- Console.WriteLine($"Waiting for debugger to attach ({currentProcess.MainModule!.FileName} PID {currentProcess.Id}). Press enter to continue...");
+ Console.WriteLine($"Waiting for debugger to attach ({EnvironmentUtilities.ProcessPath} PID {EnvironmentUtilities.CurrentProcessId}). Press enter to continue...");
+
Console.ReadLine();
break;
}
diff --git a/src/Build/BackEnd/Client/MSBuildClient.cs b/src/Build/BackEnd/Client/MSBuildClient.cs
index c23b5134407..4a496ed7f8d 100644
--- a/src/Build/BackEnd/Client/MSBuildClient.cs
+++ b/src/Build/BackEnd/Client/MSBuildClient.cs
@@ -474,7 +474,7 @@ private bool TryLaunchServer()
];
NodeLauncher nodeLauncher = new NodeLauncher();
CommunicationsUtilities.Trace("Starting Server...");
- Process msbuildProcess = nodeLauncher.Start(_msbuildLocation, string.Join(" ", msBuildServerOptions), nodeId: 0);
+ using Process msbuildProcess = nodeLauncher.Start(_msbuildLocation, string.Join(" ", msBuildServerOptions), nodeId: 0);
CommunicationsUtilities.Trace("Server started with PID: {0}", msbuildProcess?.Id);
}
catch (Exception ex)
diff --git a/src/Build/BackEnd/Components/BuildRequestEngine/BuildRequestEngine.cs b/src/Build/BackEnd/Components/BuildRequestEngine/BuildRequestEngine.cs
index 9c633d14b8c..aa90f8d1277 100644
--- a/src/Build/BackEnd/Components/BuildRequestEngine/BuildRequestEngine.cs
+++ b/src/Build/BackEnd/Components/BuildRequestEngine/BuildRequestEngine.cs
@@ -1426,7 +1426,7 @@ private void TraceEngine(string format, params object[] stuff)
{
FileUtilities.EnsureDirectoryExists(_debugDumpPath);
- using (StreamWriter file = FileUtilities.OpenWrite(String.Format(CultureInfo.CurrentCulture, Path.Combine(_debugDumpPath, @"EngineTrace_{0}.txt"), Process.GetCurrentProcess().Id), append: true))
+ using (StreamWriter file = FileUtilities.OpenWrite(string.Format(CultureInfo.CurrentCulture, Path.Combine(_debugDumpPath, @"EngineTrace_{0}.txt"), EnvironmentUtilities.CurrentProcessId), append: true))
{
string message = String.Format(CultureInfo.CurrentCulture, format, stuff);
file.WriteLine("{0}({1})-{2}: {3}", Thread.CurrentThread.Name, Thread.CurrentThread.ManagedThreadId, DateTime.UtcNow.Ticks, message);
diff --git a/src/Build/BackEnd/Components/Communications/CurrentHost.cs b/src/Build/BackEnd/Components/Communications/CurrentHost.cs
index 37bc10fc28e..a9c8336b837 100644
--- a/src/Build/BackEnd/Components/Communications/CurrentHost.cs
+++ b/src/Build/BackEnd/Components/Communications/CurrentHost.cs
@@ -35,10 +35,7 @@ public static string GetCurrentHost()
}
else
{
- using (Process currentProcess = Process.GetCurrentProcess())
- {
- s_currentHost = currentProcess.MainModule.FileName;
- }
+ s_currentHost = EnvironmentUtilities.ProcessPath;
}
}
diff --git a/src/Build/BackEnd/Components/Communications/NodeProviderOutOfProcBase.cs b/src/Build/BackEnd/Components/Communications/NodeProviderOutOfProcBase.cs
index 87602148672..ef30661bbb5 100644
--- a/src/Build/BackEnd/Components/Communications/NodeProviderOutOfProcBase.cs
+++ b/src/Build/BackEnd/Components/Communications/NodeProviderOutOfProcBase.cs
@@ -56,6 +56,9 @@ internal abstract class NodeProviderOutOfProcBase
///
private const int TimeoutForWaitForExit = 30000;
+#if !FEATURE_PIPEOPTIONS_CURRENTUSERONLY
+ private static readonly WindowsIdentity s_currentWindowsIdentity = WindowsIdentity.GetCurrent();
+#endif
///
/// The build component host.
///
@@ -237,11 +240,12 @@ protected IList GetNodes(string msbuildLocation,
#endif
ConcurrentQueue nodeContexts = new();
ConcurrentQueue exceptions = new();
+ int currentProcessId = EnvironmentUtilities.CurrentProcessId;
Parallel.For(nextNodeId, nextNodeId + numberOfNodesToCreate, (nodeId) =>
{
try
{
- if (!TryReuseAnyFromPossibleRunningNodes(nodeId) && !StartNewNode(nodeId))
+ if (!TryReuseAnyFromPossibleRunningNodes(currentProcessId, nodeId) && !StartNewNode(nodeId))
{
// We were unable to reuse or launch a node.
CommunicationsUtilities.Trace("FAILED TO CONNECT TO A CHILD NODE");
@@ -260,12 +264,12 @@ protected IList GetNodes(string msbuildLocation,
return nodeContexts.ToList();
- bool TryReuseAnyFromPossibleRunningNodes(int nodeId)
+ bool TryReuseAnyFromPossibleRunningNodes(int currentProcessId, int nodeId)
{
while (possibleRunningNodes != null && possibleRunningNodes.TryDequeue(out var nodeToReuse))
{
CommunicationsUtilities.Trace("Trying to connect to existing process {2} with id {1} to establish node {0}...", nodeId, nodeToReuse.Id, nodeToReuse.ProcessName);
- if (nodeToReuse.Id == Process.GetCurrentProcess().Id)
+ if (nodeToReuse.Id == currentProcessId)
{
continue;
}
@@ -421,7 +425,7 @@ private string GetProcessesToIgnoreKey(Handshake hostHandshake, int nodeProcessI
// on non-Windows operating systems
private static void ValidateRemotePipeSecurityOnWindows(NamedPipeClientStream nodeStream)
{
- SecurityIdentifier identifier = WindowsIdentity.GetCurrent().Owner;
+ SecurityIdentifier identifier = s_currentWindowsIdentity.Owner;
#if FEATURE_PIPE_SECURITY
PipeSecurity remoteSecurity = nodeStream.GetAccessControl();
#else
diff --git a/src/Build/BackEnd/Components/Scheduler/Scheduler.cs b/src/Build/BackEnd/Components/Scheduler/Scheduler.cs
index 74adf85158f..e6c7331f93d 100644
--- a/src/Build/BackEnd/Components/Scheduler/Scheduler.cs
+++ b/src/Build/BackEnd/Components/Scheduler/Scheduler.cs
@@ -2569,7 +2569,7 @@ private void TraceScheduler(string format, params object[] stuff)
{
FileUtilities.EnsureDirectoryExists(_debugDumpPath);
- using StreamWriter file = FileUtilities.OpenWrite(String.Format(CultureInfo.CurrentCulture, Path.Combine(_debugDumpPath, "SchedulerTrace_{0}.txt"), Process.GetCurrentProcess().Id), append: true);
+ using StreamWriter file = FileUtilities.OpenWrite(string.Format(CultureInfo.CurrentCulture, Path.Combine(_debugDumpPath, "SchedulerTrace_{0}.txt"), EnvironmentUtilities.CurrentProcessId), append: true);
file.Write("{0}({1})-{2}: ", Thread.CurrentThread.Name, Thread.CurrentThread.ManagedThreadId, _schedulingData.EventTime.Ticks);
file.WriteLine(format, stuff);
file.Flush();
@@ -2593,7 +2593,7 @@ private void DumpSchedulerState()
try
{
FileUtilities.EnsureDirectoryExists(_debugDumpPath);
- using StreamWriter file = FileUtilities.OpenWrite(String.Format(CultureInfo.CurrentCulture, Path.Combine(_debugDumpPath, "SchedulerState_{0}.txt"), Process.GetCurrentProcess().Id), append: true);
+ using StreamWriter file = FileUtilities.OpenWrite(string.Format(CultureInfo.CurrentCulture, Path.Combine(_debugDumpPath, "SchedulerState_{0}.txt"), EnvironmentUtilities.CurrentProcessId), append: true);
file.WriteLine("Scheduler state at timestamp {0}:", _schedulingData.EventTime.Ticks);
file.WriteLine("------------------------------------------------");
@@ -2707,7 +2707,7 @@ private void DumpConfigurations()
{
try
{
- using StreamWriter file = FileUtilities.OpenWrite(String.Format(CultureInfo.CurrentCulture, Path.Combine(_debugDumpPath, "SchedulerState_{0}.txt"), Process.GetCurrentProcess().Id), append: true);
+ using StreamWriter file = FileUtilities.OpenWrite(string.Format(CultureInfo.CurrentCulture, Path.Combine(_debugDumpPath, "SchedulerState_{0}.txt"), EnvironmentUtilities.CurrentProcessId), append: true);
file.WriteLine("Configurations used during this build");
file.WriteLine("-------------------------------------");
@@ -2747,7 +2747,7 @@ private void DumpRequests()
{
try
{
- using StreamWriter file = FileUtilities.OpenWrite(String.Format(CultureInfo.CurrentCulture, Path.Combine(_debugDumpPath, "SchedulerState_{0}.txt"), Process.GetCurrentProcess().Id), append: true);
+ using StreamWriter file = FileUtilities.OpenWrite(string.Format(CultureInfo.CurrentCulture, Path.Combine(_debugDumpPath, "SchedulerState_{0}.txt"), EnvironmentUtilities.CurrentProcessId), append: true);
file.WriteLine("Requests used during the build:");
file.WriteLine("-------------------------------");
diff --git a/src/Build/BackEnd/Node/OutOfProcNode.cs b/src/Build/BackEnd/Node/OutOfProcNode.cs
index 5148f89be9f..30e0f29b969 100644
--- a/src/Build/BackEnd/Node/OutOfProcNode.cs
+++ b/src/Build/BackEnd/Node/OutOfProcNode.cs
@@ -847,7 +847,8 @@ private void HandleNodeBuildComplete(NodeBuildComplete buildComplete)
_shutdownReason = buildComplete.PrepareForReuse ? NodeEngineShutdownReason.BuildCompleteReuse : NodeEngineShutdownReason.BuildComplete;
if (_shutdownReason == NodeEngineShutdownReason.BuildCompleteReuse)
{
- ProcessPriorityClass priorityClass = Process.GetCurrentProcess().PriorityClass;
+ using Process currentProcess = Process.GetCurrentProcess();
+ ProcessPriorityClass priorityClass = currentProcess.PriorityClass;
if (priorityClass != ProcessPriorityClass.Normal && priorityClass != ProcessPriorityClass.BelowNormal)
{
// This isn't a priority class known by MSBuild. We should avoid connecting to this node.
@@ -860,7 +861,7 @@ private void HandleNodeBuildComplete(NodeBuildComplete buildComplete)
{
if (!lowPriority || NativeMethodsShared.IsWindows)
{
- Process.GetCurrentProcess().PriorityClass = lowPriority ? ProcessPriorityClass.Normal : ProcessPriorityClass.BelowNormal;
+ currentProcess.PriorityClass = lowPriority ? ProcessPriorityClass.Normal : ProcessPriorityClass.BelowNormal;
}
else
{
diff --git a/src/Build/Evaluation/ProjectRootElementCache.cs b/src/Build/Evaluation/ProjectRootElementCache.cs
index e086298a380..d70e5648f3e 100644
--- a/src/Build/Evaluation/ProjectRootElementCache.cs
+++ b/src/Build/Evaluation/ProjectRootElementCache.cs
@@ -674,7 +674,7 @@ private void DebugTraceCache(string message, string param1)
if (s_debugLogCacheActivity)
{
string prefix = OutOfProcNode.IsOutOfProcNode ? "C" : "P";
- Trace.WriteLine(prefix + " " + Process.GetCurrentProcess().Id + " | " + message + param1);
+ Trace.WriteLine(prefix + " " + EnvironmentUtilities.CurrentProcessId + " | " + message + param1);
}
}
}
diff --git a/src/Build/Logging/BinaryLogger/BinaryLogger.cs b/src/Build/Logging/BinaryLogger/BinaryLogger.cs
index be4eaa2288d..278d0d77573 100644
--- a/src/Build/Logging/BinaryLogger/BinaryLogger.cs
+++ b/src/Build/Logging/BinaryLogger/BinaryLogger.cs
@@ -502,13 +502,6 @@ private string GetUniqueStamp()
=> (PathParameterExpander ?? ExpandPathParameter)(string.Empty);
private static string ExpandPathParameter(string parameters)
- => $"{DateTime.UtcNow.ToString("yyyyMMdd-HHmmss")}--{ProcessId}--{StringUtils.GenerateRandomString(6)}";
-
- private static int ProcessId
-#if NET
- => Environment.ProcessId;
-#else
- => System.Diagnostics.Process.GetCurrentProcess().Id;
-#endif
+ => $"{DateTime.UtcNow.ToString("yyyyMMdd-HHmmss")}--{EnvironmentUtilities.CurrentProcessId}--{StringUtils.GenerateRandomString(6)}";
}
}
diff --git a/src/Build/Microsoft.Build.csproj b/src/Build/Microsoft.Build.csproj
index 66d6c38d007..9d83e1304f8 100644
--- a/src/Build/Microsoft.Build.csproj
+++ b/src/Build/Microsoft.Build.csproj
@@ -59,9 +59,6 @@
-
- SharedUtilities\EnvironmentUtilities.cs
-
SharedUtilities\BuildEnvironmentHelper.cs
diff --git a/src/Framework/FileClassifier.cs b/src/Framework/FileClassifier.cs
index 2072633870b..0e08b5c13c6 100644
--- a/src/Framework/FileClassifier.cs
+++ b/src/Framework/FileClassifier.cs
@@ -6,6 +6,8 @@
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
+using Microsoft.Build.Shared;
+
#if !RUNTIME_TYPE_NETCORE
using System.Diagnostics;
using System.Linq;
@@ -141,10 +143,10 @@ public FileClassifier()
// Seems like MSBuild did not run from VS but from CLI.
// Identify current process and run it
- string processName = Process.GetCurrentProcess().MainModule.FileName;
+ string? processName = EnvironmentUtilities.ProcessPath;
string processFileName = Path.GetFileNameWithoutExtension(processName);
- if (string.IsNullOrEmpty(processFileName))
+ if (processName == null || string.IsNullOrEmpty(processFileName))
{
return null;
}
diff --git a/src/Framework/Microsoft.Build.Framework.csproj b/src/Framework/Microsoft.Build.Framework.csproj
index 271026705ba..911198afdf5 100644
--- a/src/Framework/Microsoft.Build.Framework.csproj
+++ b/src/Framework/Microsoft.Build.Framework.csproj
@@ -1,4 +1,4 @@
-
+
$(LibraryTargetFrameworks)
true
@@ -40,6 +40,7 @@
Shared\BinaryWriterExtensions.cs
+
Shared\IMSBuildElementLocation.cs
diff --git a/src/Framework/Profiler/EvaluationIdProvider.cs b/src/Framework/Profiler/EvaluationIdProvider.cs
index e81cc016beb..573204e1e15 100644
--- a/src/Framework/Profiler/EvaluationIdProvider.cs
+++ b/src/Framework/Profiler/EvaluationIdProvider.cs
@@ -3,6 +3,7 @@
using System.Diagnostics;
using System.Threading;
+using Microsoft.Build.Shared;
#nullable disable
@@ -14,7 +15,7 @@ namespace Microsoft.Build.Framework.Profiler
internal static class EvaluationIdProvider
{
private static long _sAssignedId = -1;
- private static readonly long ProcessId = Process.GetCurrentProcess().Id;
+ private static readonly long ProcessId = EnvironmentUtilities.CurrentProcessId;
///
/// Returns a unique evaluation id
diff --git a/src/MSBuild/MSBuildClientApp.cs b/src/MSBuild/MSBuildClientApp.cs
index fbe3d349fc4..be768b58b8d 100644
--- a/src/MSBuild/MSBuildClientApp.cs
+++ b/src/MSBuild/MSBuildClientApp.cs
@@ -113,10 +113,7 @@ private static string GetCurrentHost()
}
else
{
- using (Process currentProcess = Process.GetCurrentProcess())
- {
- CurrentHost = currentProcess.MainModule?.FileName ?? throw new InvalidOperationException("Failed to retrieve process executable.");
- }
+ CurrentHost = EnvironmentUtilities.ProcessPath ?? throw new InvalidOperationException("Failed to retrieve process executable.");
}
}
diff --git a/src/MSBuild/OutOfProcTaskHostNode.cs b/src/MSBuild/OutOfProcTaskHostNode.cs
index 42b71f65fe9..f862ae2adca 100644
--- a/src/MSBuild/OutOfProcTaskHostNode.cs
+++ b/src/MSBuild/OutOfProcTaskHostNode.cs
@@ -811,8 +811,9 @@ private NodeEngineShutdownReason HandleShutdown()
_taskRunnerThread?.Join();
using StreamWriter debugWriter = _debugCommunications
- ? File.CreateText(string.Format(CultureInfo.CurrentCulture, Path.Combine(FileUtilities.TempFileDirectory, @"MSBuild_NodeShutdown_{0}.txt"), Process.GetCurrentProcess().Id))
- : null;
+ ? File.CreateText(string.Format(CultureInfo.CurrentCulture, Path.Combine(FileUtilities.TempFileDirectory, @"MSBuild_NodeShutdown_{0}.txt"), EnvironmentUtilities.CurrentProcessId))
+ : null;
+
debugWriter?.WriteLine("Node shutting down with reason {0}.", _shutdownReason);
#if !CLR2COMPATIBILITY
diff --git a/src/MSBuild/PerformanceLogEventListener.cs b/src/MSBuild/PerformanceLogEventListener.cs
index 3eb6090cd4b..6772a6aeefc 100644
--- a/src/MSBuild/PerformanceLogEventListener.cs
+++ b/src/MSBuild/PerformanceLogEventListener.cs
@@ -79,7 +79,7 @@ private PerformanceLogEventListener()
internal void Initialize(string logDirectory)
{
- _processIDStr = Process.GetCurrentProcess().Id.ToString();
+ _processIDStr = EnvironmentUtilities.CurrentProcessId.ToString();
// Use a GUID disambiguator to make sure that we have a unique file name.
string logFilePath = Path.Combine(logDirectory, $"perf-{_processIDStr}-{Guid.NewGuid().ToString("N")}.log");
diff --git a/src/MSBuild/XMake.cs b/src/MSBuild/XMake.cs
index aeddef7aba4..7bdfb82380d 100644
--- a/src/MSBuild/XMake.cs
+++ b/src/MSBuild/XMake.cs
@@ -431,7 +431,7 @@ private static void AppendOutputFile(string path, long elapsedTime)
///
private static void DumpCounters(bool initializeOnly)
{
- Process currentProcess = Process.GetCurrentProcess();
+ using Process currentProcess = Process.GetCurrentProcess();
if (!initializeOnly)
{
@@ -461,7 +461,7 @@ private static void DumpCounters(bool initializeOnly)
using PerformanceCounter counter = new PerformanceCounter(".NET CLR Memory", "Process ID", instance, true);
try
{
- if ((int)counter.RawValue == currentProcess.Id)
+ if ((int)counter.RawValue == EnvironmentUtilities.CurrentProcessId)
{
currentInstance = instance;
break;
@@ -627,9 +627,9 @@ private static void DebuggerLaunchCheck()
#endif
case "2":
// Sometimes easier to attach rather than deal with JIT prompt
- Process currentProcess = Process.GetCurrentProcess();
- Console.WriteLine($"Waiting for debugger to attach ({currentProcess.MainModule.FileName} PID {currentProcess.Id}). Press enter to continue...");
+ Console.WriteLine($"Waiting for debugger to attach ({EnvironmentUtilities.ProcessPath} PID {EnvironmentUtilities.CurrentProcessId}). Press enter to continue...");
Console.ReadLine();
+
break;
}
}
@@ -1736,7 +1736,7 @@ private static bool PrintTargets(string projectFile, string toolsVersion, Dictio
new BuildManager.DeferredBuildMessage(
ResourceUtilities.FormatResourceStringIgnoreCodeAndKeyword(
"Process",
- Process.GetCurrentProcess().MainModule?.FileName ?? string.Empty),
+ EnvironmentUtilities.ProcessPath ?? string.Empty),
MessageImportance.Low),
new BuildManager.DeferredBuildMessage(
ResourceUtilities.FormatResourceStringIgnoreCodeAndKeyword(
@@ -2527,8 +2527,7 @@ private static bool ProcessCommandLineSwitches(
if (!Debugger.IsAttached)
{
- Process currentProcess = Process.GetCurrentProcess();
- Console.WriteLine($"Waiting for debugger to attach... ({currentProcess.MainModule.FileName} PID {currentProcess.Id})");
+ Console.WriteLine($"Waiting for debugger to attach... ({EnvironmentUtilities.ProcessPath} PID {EnvironmentUtilities.CurrentProcessId})");
while (!Debugger.IsAttached)
{
Thread.Sleep(100);
@@ -2555,9 +2554,13 @@ private static bool ProcessCommandLineSwitches(
}
try
{
- if (lowPriority && Process.GetCurrentProcess().PriorityClass != ProcessPriorityClass.Idle)
+ if (lowPriority)
{
- Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.BelowNormal;
+ using Process currentProcess = Process.GetCurrentProcess();
+ if (currentProcess.PriorityClass != ProcessPriorityClass.Idle)
+ {
+ currentProcess.PriorityClass = ProcessPriorityClass.BelowNormal;
+ }
}
}
// We avoid increasing priority because that causes failures on mac/linux, but there is no good way to
diff --git a/src/MSBuildTaskHost/MSBuildTaskHost.csproj b/src/MSBuildTaskHost/MSBuildTaskHost.csproj
index da3dae7bf0f..a189f58567a 100644
--- a/src/MSBuildTaskHost/MSBuildTaskHost.csproj
+++ b/src/MSBuildTaskHost/MSBuildTaskHost.csproj
@@ -1,4 +1,4 @@
-
+
@@ -70,6 +70,7 @@
CopyOnWriteDictionary.cs
+
ErrorUtilities.cs
diff --git a/src/MSBuildTaskHost/OutOfProcTaskHost.cs b/src/MSBuildTaskHost/OutOfProcTaskHost.cs
index 0998734f9ce..90a7970b5e7 100644
--- a/src/MSBuildTaskHost/OutOfProcTaskHost.cs
+++ b/src/MSBuildTaskHost/OutOfProcTaskHost.cs
@@ -90,8 +90,8 @@ internal static ExitType Execute()
#endif
case "2":
// Sometimes easier to attach rather than deal with JIT prompt
- Process currentProcess = Process.GetCurrentProcess();
- Console.WriteLine($"Waiting for debugger to attach ({currentProcess.MainModule.FileName} PID {currentProcess.Id}). Press enter to continue...");
+ Console.WriteLine($"Waiting for debugger to attach ({EnvironmentUtilities.ProcessPath} PID {EnvironmentUtilities.CurrentProcessId}). Press enter to continue...");
+
Console.ReadLine();
break;
}
diff --git a/src/Shared/BuildEnvironmentHelper.cs b/src/Shared/BuildEnvironmentHelper.cs
index 2f3dce9f66b..c3615e4acf6 100644
--- a/src/Shared/BuildEnvironmentHelper.cs
+++ b/src/Shared/BuildEnvironmentHelper.cs
@@ -431,12 +431,13 @@ private static string GetProcessFromRunningProcess()
// an unmanaged application (for example, using custom CLR hosting).
if (AssemblyUtilities.EntryAssembly == null)
{
- return Process.GetCurrentProcess().MainModule.FileName;
+ return EnvironmentUtilities.ProcessPath;
}
return AssemblyUtilities.GetAssemblyLocation(AssemblyUtilities.EntryAssembly);
#else
- return Process.GetCurrentProcess().MainModule.FileName;
+
+ return EnvironmentUtilities.ProcessPath;
#endif
}
diff --git a/src/Shared/CommunicationsUtilities.cs b/src/Shared/CommunicationsUtilities.cs
index d9d361df7ba..e0af8233119 100644
--- a/src/Shared/CommunicationsUtilities.cs
+++ b/src/Shared/CommunicationsUtilities.cs
@@ -108,7 +108,8 @@ protected internal Handshake(HandshakeOptions nodeType)
fileVersionMinor = fileVersion.Minor;
fileVersionBuild = fileVersion.Build;
fileVersionPrivate = fileVersion.Revision;
- sessionId = Process.GetCurrentProcess().SessionId;
+ using Process currentProcess = Process.GetCurrentProcess();
+ sessionId = currentProcess.SessionId;
}
// This is used as a key, so it does not need to be human readable.
@@ -836,7 +837,7 @@ private static void TraceCore(int nodeId, string message)
fileName += ".txt";
using (StreamWriter file = FileUtilities.OpenWrite(
- String.Format(CultureInfo.CurrentCulture, Path.Combine(s_debugDumpPath, fileName), Process.GetCurrentProcess().Id, nodeId), append: true))
+ string.Format(CultureInfo.CurrentCulture, Path.Combine(s_debugDumpPath, fileName), EnvironmentUtilities.CurrentProcessId, nodeId), append: true))
{
long now = DateTime.UtcNow.Ticks;
float millisecondsSinceLastLog = (float)(now - s_lastLoggedTicks) / 10000L;
diff --git a/src/Shared/Debugging/DebugUtils.cs b/src/Shared/Debugging/DebugUtils.cs
index de83a6de360..ed9da076678 100644
--- a/src/Shared/Debugging/DebugUtils.cs
+++ b/src/Shared/Debugging/DebugUtils.cs
@@ -92,13 +92,13 @@ private static bool CurrentProcessMatchesDebugName()
{
var processNameToBreakInto = Environment.GetEnvironmentVariable("MSBuildDebugProcessName");
var thisProcessMatchesName = string.IsNullOrWhiteSpace(processNameToBreakInto) ||
- Process.GetCurrentProcess().ProcessName.Contains(processNameToBreakInto);
+ EnvironmentUtilities.ProcessName.Contains(processNameToBreakInto);
return thisProcessMatchesName;
}
public static readonly string ProcessInfoString =
- $"{ProcessNodeMode.Value}_{Process.GetCurrentProcess().ProcessName}_PID={Process.GetCurrentProcess().Id}_x{(Environment.Is64BitProcess ? "64" : "86")}";
+ $"{ProcessNodeMode.Value}_{EnvironmentUtilities.ProcessName}_PID={EnvironmentUtilities.CurrentProcessId}_x{(Environment.Is64BitProcess ? "64" : "86")}";
public static readonly bool ShouldDebugCurrentProcess = CurrentProcessMatchesDebugName();
diff --git a/src/Shared/EnvironmentUtilities.cs b/src/Shared/EnvironmentUtilities.cs
index 3b275ef40b5..b64e792b53d 100644
--- a/src/Shared/EnvironmentUtilities.cs
+++ b/src/Shared/EnvironmentUtilities.cs
@@ -1,17 +1,100 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+#nullable enable
+
using System;
+using System.Diagnostics;
using System.Runtime.InteropServices;
+using System.Threading;
namespace Microsoft.Build.Shared
{
internal static partial class EnvironmentUtilities
{
+#if NET472_OR_GREATER || NETCOREAPP
public static bool Is64BitProcess => Marshal.SizeOf() == 8;
public static bool Is64BitOperatingSystem =>
Environment.Is64BitOperatingSystem;
+#endif
+
+#if !NETCOREAPP
+ private static volatile int s_processId;
+ private static volatile string? s_processPath;
+#endif
+ private static volatile string? s_processName;
+
+ /// Gets the unique identifier for the current process.
+ public static int CurrentProcessId
+ {
+ get
+ {
+#if NETCOREAPP
+ return Environment.ProcessId;
+#else
+ // copied from Environment.ProcessId
+ int processId = s_processId;
+ if (processId == 0)
+ {
+ using Process currentProcess = Process.GetCurrentProcess();
+ s_processId = processId = currentProcess.Id;
+
+ // Assume that process Id zero is invalid for user processes. It holds for all mainstream operating systems.
+ Debug.Assert(processId != 0);
+ }
+
+ return processId;
+#endif
+ }
+ }
+
+ ///
+ /// Returns the path of the executable that started the currently executing process. Returns null when the path is not available.
+ ///
+ /// Path of the executable that started the currently executing process
+ ///
+ /// If the executable is renamed or deleted before this property is first accessed, the return value is undefined and depends on the operating system.
+ ///
+ public static string? ProcessPath
+ {
+ get
+ {
+#if NETCOREAPP
+ return Environment.ProcessPath;
+#else
+ // copied from Environment.ProcessPath
+ string? processPath = s_processPath;
+ if (processPath == null)
+ {
+ // The value is cached both as a performance optimization and to ensure that the API always returns
+ // the same path in a given process.
+ using Process currentProcess = Process.GetCurrentProcess();
+ Interlocked.CompareExchange(ref s_processPath, currentProcess.MainModule.FileName ?? "", null);
+ processPath = s_processPath;
+ Debug.Assert(processPath != null);
+ }
+
+ return (processPath?.Length != 0) ? processPath : null;
+#endif
+ }
+ }
+
+ public static string ProcessName
+ {
+ get
+ {
+ string? processName = s_processName;
+ if (processName == null)
+ {
+ using Process currentProcess = Process.GetCurrentProcess();
+ Interlocked.CompareExchange(ref s_processName, currentProcess.ProcessName, null);
+ processName = s_processName;
+ }
+
+ return processName;
+ }
+ }
public static bool IsWellKnownEnvironmentDerivedProperty(string propertyName)
{
diff --git a/src/Shared/ExceptionHandling.cs b/src/Shared/ExceptionHandling.cs
index bfce3376e3e..16a19dcadc2 100644
--- a/src/Shared/ExceptionHandling.cs
+++ b/src/Shared/ExceptionHandling.cs
@@ -352,7 +352,7 @@ internal static void DumpExceptionToFile(Exception ex)
// because we're a child node with no console to log to, so die
Directory.CreateDirectory(DebugDumpPath);
- var pid = Process.GetCurrentProcess().Id;
+ var pid = EnvironmentUtilities.CurrentProcessId;
// This naming pattern is assumed in ReadAnyExceptionFromFile
s_dumpFileName = Path.Combine(DebugDumpPath, $"MSBuild_pid-{pid}_{guid:n}.failure.txt");
diff --git a/src/Shared/FileUtilities.cs b/src/Shared/FileUtilities.cs
index bbb4413632e..e8fbff8e6e3 100644
--- a/src/Shared/FileUtilities.cs
+++ b/src/Shared/FileUtilities.cs
@@ -128,7 +128,7 @@ internal static string GetCacheDirectory()
{
if (cacheDirectory == null)
{
- cacheDirectory = Path.Combine(TempFileDirectory, String.Format(CultureInfo.CurrentUICulture, "MSBuild{0}-{1}", Process.GetCurrentProcess().Id, AppDomain.CurrentDomain.Id));
+ cacheDirectory = Path.Combine(TempFileDirectory, string.Format(CultureInfo.CurrentUICulture, "MSBuild{0}-{1}", EnvironmentUtilities.CurrentProcessId, AppDomain.CurrentDomain.Id));
}
return cacheDirectory;
@@ -182,7 +182,7 @@ internal static bool CanWriteToDirectory(string directory)
string testFilePath = Path.Combine(directory, $"MSBuild_{Guid.NewGuid().ToString("N")}_testFile.txt");
FileInfo file = new(testFilePath);
file.Directory.Create(); // If the directory already exists, this method does nothing.
- File.WriteAllText(testFilePath, $"MSBuild process {Process.GetCurrentProcess().Id} successfully wrote to file.");
+ File.WriteAllText(testFilePath, $"MSBuild process {EnvironmentUtilities.CurrentProcessId} successfully wrote to file.");
File.Delete(testFilePath);
return true;
}
diff --git a/src/Shared/NamedPipeUtil.cs b/src/Shared/NamedPipeUtil.cs
index 5c5290b40c8..bf31c0193f6 100644
--- a/src/Shared/NamedPipeUtil.cs
+++ b/src/Shared/NamedPipeUtil.cs
@@ -12,7 +12,7 @@ internal static string GetPlatformSpecificPipeName(int? processId = null)
{
if (processId is null)
{
- processId = Process.GetCurrentProcess().Id;
+ processId = EnvironmentUtilities.CurrentProcessId;
}
string pipeName = $"MSBuild{processId}";
diff --git a/src/Tasks/Microsoft.Build.Tasks.csproj b/src/Tasks/Microsoft.Build.Tasks.csproj
index 9c4db39cb77..37d7cece260 100644
--- a/src/Tasks/Microsoft.Build.Tasks.csproj
+++ b/src/Tasks/Microsoft.Build.Tasks.csproj
@@ -37,9 +37,6 @@
-
- EnvironmentUtilities.cs
-
AssemblyDependency\AssemblyFoldersEx.cs
diff --git a/src/Tasks/RoslynCodeTaskFactory/RoslynCodeTaskFactoryCompilers.cs b/src/Tasks/RoslynCodeTaskFactory/RoslynCodeTaskFactoryCompilers.cs
index 2d97134b43c..50a26f7f5f2 100644
--- a/src/Tasks/RoslynCodeTaskFactory/RoslynCodeTaskFactoryCompilers.cs
+++ b/src/Tasks/RoslynCodeTaskFactory/RoslynCodeTaskFactoryCompilers.cs
@@ -6,6 +6,7 @@
using System.Linq;
using System.Runtime.InteropServices;
using Microsoft.Build.Framework;
+using Microsoft.Build.Shared;
using Microsoft.Build.Utilities;
#nullable disable
@@ -52,7 +53,7 @@ protected RoslynCodeTaskFactoryCompilerBase()
if (string.IsNullOrEmpty(_dotnetCliPath))
{
// Fallback to get dotnet path from current process which might be dotnet executable.
- _dotnetCliPath = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
+ _dotnetCliPath = EnvironmentUtilities.ProcessPath;
}
// If dotnet path is not found, rely on dotnet via the system's PATH
diff --git a/src/Utilities/Microsoft.Build.Utilities.csproj b/src/Utilities/Microsoft.Build.Utilities.csproj
index 6b8153dbc9c..e5a0a89b595 100644
--- a/src/Utilities/Microsoft.Build.Utilities.csproj
+++ b/src/Utilities/Microsoft.Build.Utilities.csproj
@@ -48,9 +48,6 @@
Shared\AssemblyFolders\Serialization\AssemblyFolderItem.cs
-
- Shared\EnvironmentUtilities.cs
-
Shared\BuildEnvironmentHelper.cs