预处理器:获取操作系统.Net Core

问题描述 投票:1回答:1

我正在编写一个我希望在Windows和Linux上使用的类。 本课程中的一种方法是访问Windows Registry 我希望实现的是以某种方式禁用在使用Linux机器时使用此特定方法。 首先,我做了一些研究,看看是否有一些.Net Core的东西可以让我检查哪个操作系统正在使用,我发现this并且确定有效。 当我在访问方法时将其实现到我的代码中时,我希望禁用访问Windows注册表的方法,但是我能得到的最接近的是使用switch语句,类似这样的

switch (OS)
{
    case OSX:
    return;

    case LINUX:
    return
}

对于return,如果不支持操作系统,这是有效的,但是我认为禁止它一起访问会更好,而不是为不支持该特定方法的操作系统抛出错误 然后我继续看看preprocessor directives认为如果我能够根据框架等检测和禁用部分代码,也许我可以使用这样的东西来禁用部分代码,具体取决于操作系统,他们永远不会这样做即使在尝试访问该方法时也会调用 我继续从那里看看我是否可以使用preprocessor directives禁用部分代码。 我找到了this。 我明白这是为了C++然而它似乎是我能找到的最接近我想在.Net Core内实现的目标 在一个完美的世界里,它会看起来像这样

    /// <summary>
    /// Get the file mime type
    /// </summary>
    /// <param name="filePathLocation">file path location</param>
    /// <returns></returns>
    `#if WINDOWS`
    public static string GetMimeType(this string filePathLocation)
    {
        if (filePathLocation.IsValidFilePath())
        {
            string mimeType = "application/unknown";
            string ext = Path.GetExtension(filePathLocation).ToLower();
            Microsoft.Win32.RegistryKey regKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(ext);

            if (regKey != null && regKey.GetValue("Content Type") != null)
            {
                mimeType = regKey.GetValue("Content Type").ToString();
            }
            return mimeType;
        }
        return null;
    }
`#endif`

我确实看到了#Define,所以我尝试了类似这样的#define IS_WINDOWS并将它与#if IS_WINDOWS一起添加到我的班级但是,如果我希望一次又一次地重复使用静态类,我无法看到如何更改该值。

c# .net-core preprocessor-directive
1个回答
2
投票

虽然你可以追求一个涉及#define的路线,但它是编译时间,你将失去很多.Net的多平台优点。您还必须处理多个配置,多个构建等。

在可能的情况下,隐藏与平台无关的抽象背后的平台相关行为,并使用System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform在运行时进行检查:

interface IPlatform
{
    void DoSomething();
}

class WindowsImpl : IPlatform
{
    public void DoSomething()
    {
        // Do something on Windows
    }
}

class LinuxImpl : IPlatform
{
    public void DoSomething()
    {
        // Do something on Linux
    }
}

// Somewhere else
var platform = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? new WindowsImpl() : new LinuxImpl();
platform.DoSomething();

这适用于许多事情,包括PInvoke。您将能够在任一平台上使用相同的二进制文件,以后更容易添加OSX。

如果您需要在编译时隔离依赖于平台的代码(可能是一个仅限Windows的软件包),MEF2/System.Composition可以帮助您创建一个插件框架,其中每个平台都有自己的程序集:

// In Windows.dll class library project
using System.Composition;

[Export(typeof(IPlatform))]
public class WindowsImpl : IPlatform
{
    public void DoSomething()
    {
        //...
    }
}

然后在你的主程序中:

using System.Composition.Hosting;

var configuration = new ContainerConfiguration();
var asm = Assembly.LoadFrom(pathToWindowsDll);
configuration.WithAssembly(asm);
var host = configuration.CreateContainer();
var platform = host.GetExports<IPlatform>().FirstOrDefault();
© www.soinside.com 2019 - 2024. All rights reserved.