Skip to content

Commit

Permalink
Windows SDKs Registry (#287)
Browse files Browse the repository at this point in the history
* Load windows sdk from registry
* Discover net fx sdk
  • Loading branch information
mwasplund authored Jan 1, 2025
1 parent 3d75bd9 commit fe17acd
Show file tree
Hide file tree
Showing 8 changed files with 1,954 additions and 181 deletions.
20 changes: 20 additions & 0 deletions code/generate-sharp/opal/System/ISystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// <copyright file="ISystem.cs" company="Soup">
// Copyright (c) Soup. All rights reserved.
// </copyright>

using System.Runtime.Versioning;

namespace Opal.System;

/// <summary>
/// The system access interface
/// Interface mainly used to allow for unit testing client code.
/// </summary>
public interface ISystem
{
/// <summary>
/// Gets the registry value
/// </summary>
[SupportedOSPlatform("windows")]
object? GetRegistryValue(string keyName, string? valueName, object? defaultValue);
}
56 changes: 56 additions & 0 deletions code/generate-sharp/opal/System/MockSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// <copyright file="MockSystem.cs" company="Soup">
// Copyright (c) Soup. All rights reserved.
// </copyright>

using System.Collections.Generic;

namespace Opal.System;

/// <summary>
/// The mock system
/// TODO: Move into test project.
/// </summary>
public class MockSystem : ISystem
{
private readonly List<string> requests;
private readonly Dictionary<(string, string?), object?> registryValues;

/// <summary>
/// Initializes a new instance of the <see cref='MockProcessManager'/> class.
/// </summary>
public MockSystem()
{
this.requests = [];
this.registryValues = [];
}

/// <summary>
/// Register a value
/// </summary>
public void RegisterRegistryValue(string keyName, string? valueName, object? value)
{
this.registryValues.Add((keyName, valueName), value);
}

/// <summary>
/// Get the load requests.
/// </summary>
public IReadOnlyList<string> Requests => this.requests;

/// <summary>
/// Gets the registry value
/// </summary>
public object? GetRegistryValue(string keyName, string? valueName, object? defaultValue)
{
var message = $"GetRegistryValue: {keyName} {valueName}";
this.requests.Add(message);
if (this.registryValues.TryGetValue((keyName, valueName), out var value))
{
return value;
}
else
{
return null;
}
}
}
30 changes: 30 additions & 0 deletions code/generate-sharp/opal/System/RuntimeSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// <copyright file="RuntimeSystem.cs" company="Soup">
// Copyright (c) Soup. All rights reserved.
// </copyright>

using Microsoft.Win32;
using System.Runtime.Versioning;

namespace Opal.System;

/// <summary>
/// A windows platform specific process executable using system
/// </summary>
public class RuntimeSystem : ISystem
{
/// <summary>
/// Initializes a new instance of the <see cref='RuntimeProcessManager'/> class.
/// </summary>
public RuntimeSystem()
{
}

/// <summary>
/// Gets the registry value
/// </summary>
[SupportedOSPlatform("windows")]
public object? GetRegistryValue(string keyName, string? valueName, object? defaultValue)
{
return Registry.GetValue(keyName, valueName, null);
}
}
20 changes: 0 additions & 20 deletions code/generate-sharp/package-manager.core/Recipe.sml

This file was deleted.

1,914 changes: 1,781 additions & 133 deletions code/generate-sharp/swhere.core.unittests/utilities/SwhereManagerUnitTests.cs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion code/generate-sharp/swhere/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ public static async Task<int> Main(string[] args)
TraceEvents.Warning |
TraceEvents.Error;
Log.RegisterListener(new ConsoleTraceListener(new EventTypeFilter(traceFlags), false, false));
LifetimeManager.RegisterSingleton<ISystem, RuntimeSystem>();
LifetimeManager.RegisterSingleton<IFileSystem, RuntimeFileSystem>();

LifetimeManager.RegisterSingleton<IProcessManager, RuntimeProcessManager>();

bool includePrerelease = false;
Expand Down
65 changes: 42 additions & 23 deletions code/generate-sharp/swhere/SwhereManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Soup.Build.Utilities;
using System;
using System.Collections.Generic;
using System.Runtime.Versioning;
using System.Threading.Tasks;
using Path = Opal.Path;

Expand All @@ -30,7 +31,9 @@ public static async Task DiscoverAsync(OSPlatform platform, bool includePrerelea
switch (platform)
{
case OSPlatform.Windows:
#pragma warning disable CA1416 // Validate platform compatibility
await DiscoverWindowsPlatformAsync(includePrerelease, userConfig);
#pragma warning restore CA1416 // Validate platform compatibility
break;
case OSPlatform.Linux:
await DiscoverLinuxPlatformAsync(platform, userConfig);
Expand All @@ -49,6 +52,7 @@ private static async Task DiscoverSharedPlatformAsync(OSPlatform platform, Local
DiscoverNuget(userConfig);
}

[SupportedOSPlatform("windows")]
private static async Task DiscoverWindowsPlatformAsync(bool includePrerelease, LocalUserConfig userConfig)
{
Log.HighPriority("Discover Windows Platform");
Expand All @@ -66,30 +70,45 @@ private static async Task DiscoverWindowsPlatformAsync(bool includePrerelease, L
{ "VCToolsRoot", msvcInstallPath.ToString() },
});

var (windowsSDKVersion, windowsSDKInstallPath) = WindowsSDKUtilities.FindWindows10Kit();
var windowsSDK = userConfig.EnsureSDK("Windows");
windowsSDK.SourceDirectories =
[
windowsSDKInstallPath,
];
windowsSDK.SetProperties(
new Dictionary<string, string>()
{
{ "Version", windowsSDKVersion },
{ "RootPath", windowsSDKInstallPath.ToString() },
});
var windowsSDK = WindowsSDKUtilities.TryFindWindows10Kit();

var netFXToolsPath = WindowsSDKUtilities.FindNetFXTools();
var netFXToolsSDK = userConfig.EnsureSDK("NetFXTools");
netFXToolsSDK.SourceDirectories =
[
netFXToolsPath,
];
netFXToolsSDK.SetProperties(
new Dictionary<string, string>()
{
{ "ToolsRoot", netFXToolsPath.ToString() },
});
if (windowsSDK is not null)
{
var windowsSDKConfig = userConfig.EnsureSDK("Windows");
windowsSDKConfig.SourceDirectories =
[
windowsSDK.Value.InstallPath,
];
windowsSDKConfig.SetProperties(
new Dictionary<string, string>()
{
{ "Version", windowsSDK.Value.Version },
{ "RootPath", windowsSDK.Value.InstallPath.ToString() },
});
}
else
{
Log.Warning("No Windows SDKs installed");
}

var netFXToolsPath = WindowsSDKUtilities.TryFindNetFXTools();
if (netFXToolsPath is not null)
{
var netFXToolsSDK = userConfig.EnsureSDK("NetFXTools");
netFXToolsSDK.SourceDirectories =
[
netFXToolsPath,
];
netFXToolsSDK.SetProperties(
new Dictionary<string, string>()
{
{ "ToolsRoot", netFXToolsPath.ToString() },
});
}
else
{
Log.Warning("No NetFx SDK installed");
}
}

private static async Task DiscoverLinuxPlatformAsync(OSPlatform platform, LocalUserConfig userConfig)
Expand Down
28 changes: 24 additions & 4 deletions code/generate-sharp/swhere/WindowsSDKUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,43 @@
using Opal;
using Opal.System;
using System.Linq;
using System.Runtime.Versioning;
using Path = Opal.Path;

namespace Soup.Build.Discover;

[SupportedOSPlatform("windows")]
internal static class WindowsSDKUtilities
{
public static (string Version, Path Path) FindWindows10Kit()
private static string WindowsSDKRegistryKey => @"HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Microsoft SDKs\Windows\v10.0";

private static string WindowsNetFxSDKRegistryKey => @"HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Microsoft SDKs\NETFXSDK\4.8\WinSDK-NetFx40Tools";

private static string InstallationFolderValue => "InstallationFolder";

public static (string Version, Path InstallPath)? TryFindWindows10Kit()
{
var windowsSDKInstallPath = new Path("C:/Program Files (x86)/Windows Kits/10/");
var installFolder = (string?)LifetimeManager.Get<ISystem>().GetRegistryValue(
WindowsSDKRegistryKey, InstallationFolderValue, null);

if (installFolder is null)
return null;

var windowsSDKInstallPath = Path.Parse(installFolder);
var windowsSDKVersion = FindNewestWindows10KitVersion(windowsSDKInstallPath);

return (windowsSDKVersion, windowsSDKInstallPath);
}

public static Path FindNetFXTools()
public static Path? TryFindNetFXTools()
{
return new Path("C:/Program Files (x86)/Microsoft SDKs/Windows/v10.0A/bin/NETFX 4.8 Tools/");
var installFolder = (string?)LifetimeManager.Get<ISystem>().GetRegistryValue(
WindowsNetFxSDKRegistryKey, InstallationFolderValue, null);

if (installFolder is null)
return null;
else
return Path.Parse(installFolder);
}

private static string FindNewestWindows10KitVersion(Path windowsSDKInstallPath)
Expand Down

0 comments on commit fe17acd

Please sign in to comment.