web-dev-qa-db-ja.com

実行時にOSバージョンを確認する方法条件付きコンパイルステートメントを使用しないWindowsまたはLinux

あなたのC#コードが実行されているプラ​​ットフォームを判断する方法を知っている人はいますか?実行時に異なるコードを実行できるように、LinuxまたはWindowsのどちらで実行されているか。

WindowsおよびLinuxプラットフォームをターゲットに構築したいc#windowsアプリがあります。

これまでのところ、同じソースコードファイルのセットを指す2つのプロジェクトファイルを作成しました。次に、LINUXと呼ばれるプロジェクトの1つを条件付きコンパイルステートメントを使用します。

実際のコードに違いがある場合は、条件付きコンパイルステートメントを使用して条件付きステートメントを使用します。

#if (LINUX)
 ' do something
#endif

これを行うより良い方法はありますか?本当に2つのプロジェクトファイルは必要ありません。

前もって感謝します。

38
Bobbo

System.Environment.OSVersion.Platformを使用して実行プラットフォームを検出できます。

public static bool IsLinux
{
    get
    {
        int p = (int) Environment.OSVersion.Platform;
        return (p == 4) || (p == 6) || (p == 128);
    }
}

Mono FAQ から:

実行プラットフォームを検出する方法?

実行プラットフォームは、System.Environment.OSVersion.Platform値を使用して検出できます。ただし、Unixプラットフォームを正しく検出するには、あらゆる場合に、もう少し作業が必要です。フレームワークの最初のバージョン(1.0および1.1)には、UnixのPlatformID値が含まれていなかったため、Monoは値128を使用していました。値:UnixとMacOS Xを区別する4以降の.NETのバージョン。MacOSXにさらに別の値6を導入します。

つまり、Unixプラットフォームで実行されているコードを適切に検出するには、3つの値(4、6、および128)を確認する必要があります。これにより、Mono CLR 1.xランタイムおよびMonoとMicrosoft CLR 2.xランタイムの両方で実行されたときに、検出コードが期待どおりに機能することが保証されます。

74
Martin Buberl

この推奨事項は、Microsoftのブログの1つで見つけました。

プラットフォームのチェックにはRuntimeInformation.IsOSPlatform()を使用することをお勧めします。

参照: https://blogs.msdn.Microsoft.com/dotnet/2017/11/16/announcing-the-windows-compatibility-pack-for-net-core/

IsOSPlatform()は、OSPlatformWindowsLinuxの3つの値をデフォルトで持つOSX型の引数を取ります。次のように使用できます。

if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
  // Do something
}

APIは.NET Standard 2.0の一部であるため、.NET Core 2.0および.NET Framework 4.7.1で使用できます。

29
Alex Sanséau

どう?

System.Environment.OSVersion
10
Andreas Ågren

System.Environment.OSVersionを使用して、実行時に使用しているプラ​​ットフォームの種類を確認できます。

3
Samuel Otter

機能のLinuxとWindowsの実装に互換性がない場合(つまり、特定のプラットフォームでのみ利用可能なライブラリへの参照が必要な場合)、他の答えを拡張するには、インターフェイスを使用して、2つの個別のアセンブリを作成し、このインターフェイスを実装する型で、各プラットフォームでコンパイルされます。次に、チェックに基づいて、Assembly.Load()を使用して適切なアセンブリ(およびプラットフォーム固有の依存関係)のみを読み込み、リフレクションでAssembly内の型を見つけ、Activator.CreateInstance()を使用して型のインスタンスを取得しますその後、正常に作業できるようになります。

2
Joel Coehoorn

次のように、Processを使用してシェルスクリプトを呼び出してunameを取得することもできます。

Process p = new Process {
  StartInfo = {
    UseShellExecute        = false,
    RedirectStandardOutput = true,
    FileName               = "uname",
    Arguments              = "-s"
  }
};
p.Start();
string uname = p.StandardOutput.ReadToEnd().Trim();

if (uname == "Darwin") {
  // OSX
} else {
  // ...
}
0
Zane Claes