Вы могли бы go с тем, что предлагает @DavidBrowne в своем ответе. Используя System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName
«зная», что это dotnet.exe
(с полным путем), а затем используя это. И учтите, что в зависимости от вашей ситуации это может быть «достаточно хорошо», а ниже - слишком сложно. Сказав это ...
Однако у этого есть две проблемы:
- Что если процесс, пытающийся выполнить другой, сам по себе не является. NET основным процессом (но a. NET Основанное на платформе одно или несколько IIS / ASP. NET Основное внутрипроцессное приложение)?
- Что если процесс, пытающийся выполнить другое, сам по себе основан на NET Core 3 .x исполняемый файл (то есть запускается через
MyProc.exe
, а не dotnet.exe MyProc.dll
)?
Если вы пишете приложение, которое выполняет только другие исполняемые файлы, которые вы также контролируете, вы можете по крайней мере обойти 2-й проблема заключается в том, чтобы убедиться, что все построено одинаково (с использованием dotnet.exe
или с использованием NET исполняемых файлов Core 3.x).
Однако, если по какой-либо причине это невозможно (например, выдайте номер один) выше), то вам нужно найти местоположение dotnet.exe
в системе. Логика c для этого не является тривиальной, и существующий код на GitHub показывает, как это делается. Найдите DotNetMuxer.cs
, и вы получите несколько реализаций. Например, один из ASP. NET Core .
Еще более сложный, также рассмотрит переменную окружения FX_DEPS_FILE
и может выглядеть так:
// One of the many muxer-locator implementations that can be found on github.com
// (Example azure-sdk, asp.net core sources, etc.)
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
namespace ProcessIsolation
{
/// <summary>
/// Utilities for finding the "dotnet.exe" file from the currently running .NET Core application
/// </summary>
internal static class DotNetMuxer
{
private const string MuxerName = "dotnet";
static DotNetMuxer()
{
MuxerPath = TryFindMuxerPath();
}
/// <summary>
/// The full filepath to the .NET Core muxer.
/// </summary>
public static string MuxerPath { get; }
/// <summary>
/// Finds the full filepath to the .NET Core muxer,
/// or returns a string containing the default name of the .NET Core muxer ('dotnet').
/// </summary>
/// <returns>The path to <c>dotnet.exe</c> or <c>null</c> if not found.</returns>
public static string MuxerPathOrDefault()
=> MuxerPath ?? MuxerName;
private static string TryFindMuxerPath()
{
var fileName = MuxerName;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
fileName += ".exe";
}
var mainModule = Process.GetCurrentProcess().MainModule;
if (!string.IsNullOrEmpty(mainModule?.FileName)
&& Path.GetFileName(mainModule.FileName).Equals(fileName, StringComparison.OrdinalIgnoreCase))
{
return mainModule.FileName;
}
// if Process.MainModule is not available or it does not equal "dotnet(.exe)?", fallback to navigating to the muxer
// by using the location of the shared framework
var fxDepsFile = AppContext.GetData("FX_DEPS_FILE") as string;
if (string.IsNullOrEmpty(fxDepsFile))
{
return null;
}
var muxerDir = new FileInfo(fxDepsFile) // Microsoft.NETCore.App.deps.json
.Directory? // (version)
.Parent? // Microsoft.NETCore.App
.Parent? // shared
.Parent; // DOTNET_HOME
if (muxerDir == null)
{
return null;
}
var muxer = Path.Combine(muxerDir.FullName, fileName);
return File.Exists(muxer)
? muxer
: null;
}
}
}