最近在做一个.NET跨平台的小工具,需要在程序中做了客户端运行在什么操作系统上的判断。
.NET Api提供了 System.Environment.OSVersion 封装,可以获取所在操作系统的信息。
因此我做了个小程序来测试一下各个平台返回的信息。当然,为了跨平台使用了MONO作为中间层进行部署。
我用的版本是 mono 2.6.7
namespace OSInfoTest
{
class Program
{
static void Main(string[] args)
{
string osInfo = System.Environment.OSVersion.VersionString;
Console.WriteLine("VersionString : {0}", osInfo);
string platform = System.Environment.OSVersion.Platform.ToString();
Console.WriteLine("Platform : {0}", platform);
Console.ReadLine();
}
}
}
将编译之后的OSInfoTest.exe分别部署到 MacOS 和 Linux Red Hat 上。
MacOS的运行结果:
Linux的运行结果:
如上图红色标记部分,Platform居然都是Unix!
System.Environment.OSVersion.Platform 返回的是一个 PlatformID 的枚举,里面可是定义着MacOSX的哦。
一顿查找之后发现这原来是一个MONO的Bug:[Mono-bugs] [Bug 515570]
找到原因了,但是这个Bug还没有被修正,还需要自己来解决这个问题啊:
不过好在可以利用MacOS的控制台信息来进行判断。
代码修改一下,加入了 IsRunningMacOS , GetMacOsInfo 两个方法。
一个方法是直接判断现在运行的OS是否是Mac,一个是通过调用Mac控制台获取当前OS版本信息。
namespace OSInfoTest
{
class Program
{
static void Main(string[] args)
{
bool isRuningMac = IsRunningMacOS();
string osInfo = "";
if (isRuningMac)
osInfo = GetMacOsInfo();
else
osInfo = System.Environment.OSVersion.VersionString;
Console.WriteLine("VersionString : {0}", osInfo);
string platform = "";
if (isRuningMac)
platform = "MacOSX";
else
platform = System.Environment.OSVersion.Platform.ToString();
Console.WriteLine("Platform : {0}", platform);
Console.ReadLine();
}
[DllImport("libc")]
static extern int uname(IntPtr buf);
static bool IsRunningMacOS()
{
IntPtr buf = IntPtr.Zero;
try
{
buf = Marshal.AllocHGlobal(8192);
if (uname(buf) == 0)
{
string os = Marshal.PtrToStringAnsi(buf);
if (os == "Darwin")
return true;
}
}
catch
{ }
finally
{
if (buf != IntPtr.Zero)
Marshal.FreeHGlobal(buf);
}
return false;
}
static string GetMacOsInfo()
{
string macOsInfo;
try
{
Process getMacOSInfoProcess = new Process();
getMacOSInfoProcess.StartInfo.FileName = "sw_vers";
getMacOSInfoProcess.StartInfo.Arguments = "";
getMacOSInfoProcess.StartInfo.UseShellExecute = false;
getMacOSInfoProcess.StartInfo.RedirectStandardOutput = true;
getMacOSInfoProcess.Start();
getMacOSInfoProcess.WaitForExit();
if (getMacOSInfoProcess.ExitCode == 0)
{
macOsInfo = getMacOSInfoProcess.StandardOutput.ReadToEnd();
macOsInfo = macOsInfo.Replace('/n', ' ');
macOsInfo = macOsInfo.Replace("ProductName:/t", "");
macOsInfo = macOsInfo.Replace("ProductVersion:/t", " ");
macOsInfo = macOsInfo.Replace("BuildVersion:/t", " ");
}
else
{
macOsInfo = "";
}
}
catch
{
macOsInfo = "";
}
return macOsInfo;
}
}
}
好,再来运行一下:
比较一下直接在 MacOS 上运行 "sw_vers" 的结果:
OK~ 搞定。