-
Notifications
You must be signed in to change notification settings - Fork 466
Use Muxer from .NET SDK for dotnet discovery #4732
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
liliankasem
merged 8 commits into
main
from
liliankasem/use-dotnet-muxer-from-dotnetcli
Nov 18, 2025
Merged
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
5521768
Use dotnet Muxer from .NET SDK for dotnet discovery
liliankasem 02d0c03
Replace CommandChecker.CommandExists with DotnetMuxer
liliankasem cb09667
Add tests
liliankasem 077cd9a
Update release notes
liliankasem ad27fb5
Remove dupe comment
liliankasem 48de81b
Refactor to static and simplify
liliankasem 405f4ae
Update release notes
liliankasem 25c6266
Merge branch 'main' into liliankasem/use-dotnet-muxer-from-dotnetcli
liliankasem File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| // Copyright (c) .NET Foundation. All rights reserved. | ||
| // Licensed under the MIT License. See LICENSE in the project root for license information. | ||
|
|
||
| // Adapted from: https://github.com/dotnet/sdk/blob/main/src/Cli/Microsoft.DotNet.Cli.Utils/Muxer.cs | ||
| using System.Runtime.InteropServices; | ||
|
|
||
| namespace Azure.Functions.Cli.Helpers; | ||
|
|
||
| internal static class DotnetMuxer | ||
| { | ||
| private static readonly string _muxerName = "dotnet"; | ||
| private static readonly string _exeSuffix = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".exe" : string.Empty; | ||
|
|
||
| /// <summary> | ||
| /// Locates the dotnet muxer (dotnet executable). | ||
| /// </summary> | ||
| /// <returns>The full path to the dotnet executable.</returns> | ||
| /// <exception cref="InvalidOperationException">Thrown when the dotnet executable cannot be located.</exception> | ||
| public static string GetMuxerPath() | ||
| { | ||
| string muxerPath; | ||
|
|
||
| // Most scenarios are running dotnet.dll as the app | ||
| // Root directory with muxer should be two above app base: <root>/sdk/<version> | ||
| string rootPath = Path.GetDirectoryName(Path.GetDirectoryName(AppContext.BaseDirectory.TrimEnd(Path.DirectorySeparatorChar))); | ||
| if (rootPath is not null) | ||
| { | ||
| muxerPath = Path.Combine(rootPath, $"{_muxerName}{_exeSuffix}"); | ||
| if (File.Exists(muxerPath)) | ||
| { | ||
| return muxerPath; | ||
| } | ||
| } | ||
|
|
||
| // Best-effort search for muxer. | ||
| muxerPath = Environment.ProcessPath; | ||
|
|
||
| // The current process should be dotnet in most normal scenarios except when dotnet.dll is loaded in a custom host like the testhost | ||
| if (muxerPath is not null && !Path.GetFileNameWithoutExtension(muxerPath).Equals("dotnet", StringComparison.OrdinalIgnoreCase)) | ||
| { | ||
| // SDK sets DOTNET_HOST_PATH as absolute path to current dotnet executable | ||
| muxerPath = Environment.GetEnvironmentVariable("DOTNET_HOST_PATH"); | ||
| if (muxerPath is null) | ||
| { | ||
| // fallback to DOTNET_ROOT which typically holds some dotnet executable | ||
| string root = Environment.GetEnvironmentVariable("DOTNET_ROOT"); | ||
| if (root is not null) | ||
| { | ||
| muxerPath = Path.Combine(root, $"dotnet{_exeSuffix}"); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if (muxerPath is null) | ||
| { | ||
| throw new InvalidOperationException("Unable to locate dotnet multiplexer"); | ||
| } | ||
|
|
||
| return muxerPath; | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| // Copyright (c) .NET Foundation. All rights reserved. | ||
| // Licensed under the MIT License. See LICENSE in the project root for license information. | ||
|
|
||
| using Azure.Functions.Cli.Helpers; | ||
| using Xunit; | ||
|
|
||
| namespace Azure.Functions.Cli.UnitTests.HelperTests | ||
| { | ||
| public class DotnetMuxerTests | ||
| { | ||
| [Fact] | ||
| public void GetMuxerPath_ReturnsMuxerPath_WhenDotnetExists() | ||
| { | ||
| // Act | ||
| var path = DotnetMuxer.GetMuxerPath(); | ||
|
|
||
| // Assert | ||
| Assert.NotNull(path); | ||
| Assert.False(string.IsNullOrWhiteSpace(path)); | ||
| } | ||
|
|
||
| [Fact] | ||
| public void GetMuxerPath_ContainsDotnetExecutable() | ||
| { | ||
| // Act | ||
| var path = DotnetMuxer.GetMuxerPath(); | ||
|
|
||
| // Assert | ||
| Assert.Contains("dotnet", path, StringComparison.OrdinalIgnoreCase); | ||
| } | ||
|
|
||
| [Fact] | ||
| public void GetMuxerPath_PointsToExecutableFile() | ||
| { | ||
| // Act | ||
| var path = DotnetMuxer.GetMuxerPath(); | ||
|
|
||
| // Assert | ||
| // The path should exist as a file | ||
| Assert.True( | ||
| File.Exists(path) || File.Exists(path + ".exe"), | ||
| $"Expected muxer path '{path}' to exist"); | ||
| } | ||
|
|
||
| [Fact] | ||
| public void GetMuxerPath_PointsToFunctionalDotnetExecutable() | ||
| { | ||
| // Act | ||
| var path = DotnetMuxer.GetMuxerPath(); | ||
|
|
||
| // Assert - invoke dotnet --version to verify it's functional | ||
| var startInfo = new System.Diagnostics.ProcessStartInfo | ||
| { | ||
| FileName = path, | ||
| Arguments = "--version", | ||
| RedirectStandardOutput = true, | ||
| RedirectStandardError = true, | ||
| UseShellExecute = false, | ||
| CreateNoWindow = true | ||
| }; | ||
|
|
||
| using var process = System.Diagnostics.Process.Start(startInfo); | ||
| Assert.NotNull(process); | ||
|
|
||
| var output = process.StandardOutput.ReadToEnd(); | ||
| process.WaitForExit(); | ||
|
|
||
| // Assert | ||
| Assert.Equal(0, process.ExitCode); | ||
| Assert.False(string.IsNullOrWhiteSpace(output), "Expected dotnet --version to produce output"); | ||
|
|
||
| // Verify output looks like a version number (e.g., "8.0.100") | ||
| Assert.Matches(@"^\d+\.\d+\.\d+", output.Trim()); | ||
| } | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.