预处理器:获取操作系统 .Net Core [英] Preprocessor : Get Operating System .Net Core

查看:24
本文介绍了预处理器:获取操作系统 .Net Core的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个我希望在 Windows 和 Windows 上使用的类Linux.

此类中的方法之一是访问 Windows 注册表

我希望实现的是在使用 Linux 机器时以某种方式禁用此特定方法.

首先,我做了一些研究,看看是否有适合
一个 href="https://en.wikipedia.org/wiki/.NET_Core" rel="nofollow noreferrer">.Net Core 可以让我检查正在使用的操作系统,我发现 这个,果然行得通.

当我将它实施到我的代码在访问一个方法时,我希望禁用访问 Windows 注册表的方法,但是我最接近的是使用 switch 语句,就像这样

I'm writing a class that I wish to use on both Windows & Linux.

One of the methods that is in this class is accessing the Windows Registry

What I'm hoping to achieve is to somehow disable this particular method from being used when using a Linux machine.

First of all I did some research to see if there was something for .Net Core that would allow me to check which operating system is in use, I found this and sure enough that works.

When I implemented it into my code when accessing a method, I was hoping to disable the method that's accessing the windows registry, however the closest I could get to this was using a switch statement, something like this

switch (OS)
{
    case OSX:
    return;

    case LINUX:
    return
}

return 如果操作系统不受支持,这行得通,但是我然后认为禁用它被一起访问会好得多,而不是为不受支持的操作系统抛出错误对于该特定方法

然后我继续查看 预处理器指令 认为如果我能够根据框架等检测和禁用部分代码,也许我可以使用这样的方法来根据操作系统禁用部分代码即使在尝试访问该方法时,它们也永远不会被调用

我从那里继续查看是否可以使用 预处理器指令禁用部分代码.
我发现 这个.

我知道这是为了C++ 但是它似乎是我在 中尝试实现的最接近的.Net Core

在完美的世界中,它看起来像这样

To return if the operating system was not supported, this worked, however I then thought disabling it from being accessed all together would be much better rather than throwing an error for an operating system thats not supported for that particular method

I then went on to look at preprocessor directives thinking that if I'm able to detect and disable parts of code depending the frameworks etc, maybe I could use something like this to disable parts of code depending on the operating system that way they could never be called even when trying to access the method

I went on from there to see if I could disable parts of code using preprocessor directives.
I found this.

I understand that it is for C++ however it seems to be the closest I could find for what I'm trying to achieve within .Net Core

In a perfect world, it would look something like this

    /// <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 一起添加到我的班级中但是,如果我希望一遍又一遍地重用静态类,我无法看到如何更改该值.

I did see #Define so I tried something like this #define IS_WINDOWS and added it to my class along with #if IS_WINDOWS however, I couldn't see how to change that value if I'm hoping to just reuse the static class over and over.

推荐答案

虽然你可以追求一条涉及 #define 的路线,但它是编译时的,你会失去很多 .Net 的多平台善良.您还必须兼顾多个配置、多个构建等.

While you could pursue a route involving #define, it's compile-time and you'll loose a lot of .Net's multi-platform goodness. You'll also have to juggle multiple configurations, multiple builds, etc.

在可能的情况下,将平台相关行为隐藏在独立于平台的抽象之后,并在运行时使用 System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform:

Where possible, hide the platform-dependent behavior behind a platform-independent abstraction and do the check at runtime using 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 会更容易.

This works well for many things including PInvoke. You will be able to use the same binaries on either platform, and it will be easier to add OSX later.

如果你需要在编译时隔离平台相关的代码(也许一个包是只支持 Windows 的),MEF2/System.Composition 可以帮你制作一个插件框架,每个平台都有自己的程序集:

If you need to isolate the platform-dependent code at compile-time (perhaps a package is Windows-only), MEF2/System.Composition can help you make a plugin framework where each platform gets its own assembly:

// 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();

这篇关于预处理器:获取操作系统 .Net Core的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆