Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OS version information #14294

Closed
blobor opened this issue Feb 25, 2015 · 101 comments
Closed

OS version information #14294

blobor opened this issue Feb 25, 2015 · 101 comments
Assignees
Labels
api-needs-work API needs work before it is approved, it is NOT ready for implementation
Milestone

Comments

@blobor
Copy link

blobor commented Feb 25, 2015

I want to write cross-platform class library based on .NET Core. I need to invoke native libraries in Windows (kernel32) and in UNIX (libc).

Currently Environment class is missing OSversion property. Is there some way to determine in what OS currently my assembly is running?

@ellismg
Copy link
Contributor

ellismg commented Feb 27, 2015

This seems like a reasonable addition to me. I know we are nervous to add back version properties, but some way to figure out if you are on Linux/OSX/Windows seems reasonable.

@blobor
Copy link
Author

blobor commented Feb 27, 2015

Thank you 👍

@davkean
Copy link
Member

davkean commented Feb 28, 2015

I've seen a similar request for ARM32 vs other platforms, checking pointer size is not good enough in that situation.

@HellBrick
Copy link

I would have upvoted this issue if it were possible =) I have a project that uses quite a few Environment.OSVersion.Platform checks in the common code that's supposed to work on both Windows and Linux, so missing this API would really hurt. (Don't really care for the Version, VersionString and ServicePack properties though.)

@ellismg
Copy link
Contributor

ellismg commented Mar 26, 2015

I think we do need to expose something like the Platform your are running on (Linux/Windows/Mac) and the processor.

For example, Kestrel does the following to figure out if they are running on windows or not:

        public static bool IsWindows()
        {
#if DNXCORE50
            return true;
#else
            var p = (int)Environment.OSVersion.Platform;
            return (p != 4) && (p != 6) && (p != 128);
#endif
        }

Which is completely busted when you want to run .NET Core on CoreCLR. If we don't provide an API I can imagine the next best thing being just trying to P/Invoke to random Windows or Unix APIs and determine the answer that way.

I have also seen cases where parts of ASP.NET vNext sniff PROCESSOR_ARCHIECTURE environment variable to detect x86 vs x64. I have been moving that code to use IntPtr.Size, but as David says, there's no way to figure out ARM or not with that.

@Priya91 Priya91 assigned Priya91 and unassigned terrajobst Apr 17, 2015
@Priya91
Copy link
Contributor

Priya91 commented Apr 17, 2015

Exposing the desktop types in cloud platform, is not desired, as we need to keep adding support back to desktop. A good way to go will be to create a new contract, with the following api-definition:

namespace System.XPlatform
{
    public struct OSName
    {
        public OSName(string osName) { }
        public static OSName Windows { get; }
        public static OSName Linux { get; }
        public static OSName OSX { get; }
    }

    public static class RuntimeInfo
    {
         public static bool IsOSPlatform(OSName osName) { return default(bool); }
    }
}

cc @KrzysztofCwalina @ellismg @weshaggard @davkean @stephentoub : If this api design is agreeable i'll start implementing this.

@davkean
Copy link
Member

davkean commented Apr 17, 2015

Can you help me understand that conclusion? Adding enum values to .NET Framework ("desktop") is extremely easy, especially given NET Framework will never have to return them or plumb them through. In fact, it already contains the values (Unix/Linux, MacOS and Win32NT) that currently we're planning to port to.

Adding this into a new assembly is even more problematic, and we're now forced to introduce a new library (with one type!) that we'll need to build for each platform, even though we're already building mscorlib/CoreCLR for each one and it already contains the APIs.

I believe we should stick with the previous plan and expose the existing APIs.

cc @terrajobst @nguerrera @jaredpar @ericstj the rest of the Framework Design Core.

@ellismg
Copy link
Contributor

ellismg commented Apr 17, 2015

Can you help me understand that conclusion? Adding enum values to .NET Framework ("desktop") is extremely easy, especially given NET Framework will never have to return them or plumb them through. In fact, it already contains the values (Unix/Linux, MacOS and Win32NT) that currently we're planning to port to.

The BSD port of CoreCLR is underway by the community now and they are making good progress. I assume as soon as they are done, we will want to be answer the question "am I running on BSD". So we would have to version the contract anyway. With the above design we can say call RuntimeInfo.IsOSPlatform(new OSName("BSD")) even if we can't quickly rev the contract.

Adding this into a new assembly is even more problematic, and we're now forced to introduce a new library (with one type!) that we'll need to build for each platform, even though we're already building mscorlib/CoreCLR for each one and it already contains the APIs.

Not having a dependency on the runtime when possible feels like a win to me. I don't understand the pushback about having to build multiple times. We're already going to be in that boat for many pieces of CoreFX.

I also see no reason why long term the implementation of the contract could not be a façade over the runtime itself, if we find that that's the correct factoring.

@davkean
Copy link
Member

davkean commented Apr 17, 2015

Not having a dependency on the runtime when possible feels like a win to me. I don't understand the pushback about having to build multiple times.

For every port to a new OS, the runtime is going to have to rev, so I'm not understanding that concern. It's not just building multiple times; it's creating the contract, the multiple projects, NuGet packages, etc. It feels like we're adding complexity to an area that is not needed. The APIs already exist and given the large amount of code already in mscorlib that probably needs to do something similar, we'd probably need to keep them around anyway - or put these new APIs into mscorib.

With the above design we can say call RuntimeInfo.IsOSPlatform(new OSName("BSD")) even if we can't quickly rev the contract.

You can achieve the same thing with enums OSVersion.Platform == (PlatformID)10. In the same way that '10' is a magic handshake, so is the hardcoded BSD.

@ellismg
Copy link
Contributor

ellismg commented Apr 17, 2015

@Priya91 I really like what you have here. My only piece of feedback is around the namespace. Could we use something like System.Runtime.InteropServices instead? Do you have an idea for the contract name itself?

@Priya91
Copy link
Contributor

Priya91 commented Apr 17, 2015

@ellismg : Yes, system.runtime.interopservices sounds good. Since these apis relate to runtime environment information how about System.Runtime.Environment..

@ellismg
Copy link
Contributor

ellismg commented Apr 17, 2015

I like that a lot!

@davkean
Copy link
Member

davkean commented Apr 17, 2015

(Side note that will clash with Environment class in the System namespace)

@ellismg
Copy link
Contributor

ellismg commented Apr 17, 2015

@davkean What clashes? If the contract is called System.Runtime.Environment?

@davkean
Copy link
Member

davkean commented Apr 17, 2015

Ah, I thought you were talking about the namespace.

@Priya91
Copy link
Contributor

Priya91 commented Apr 17, 2015

Ok, sounds like we have reached a conclusion with the latest proposal. I'll mark the issue with accepting PRs. Going along with the API review process @blobor: will you be providing PR, or only contributing the issue?

@weshaggard
Copy link
Member

The API looks good overall to me as well but I was curious about why you need the OSName struct? Is there a particular reason that is necessary instead of just using a string? We could still use OSName as a place holder for predefined sets.

@Priya91
Copy link
Contributor

Priya91 commented Apr 17, 2015

@weshaggard : Any string parsing that has to be done, can be abstracted in OSName instead of IsOSPlatform, moreover, we expect a string that represents an OSName, instead of any string.

@ellismg
Copy link
Contributor

ellismg commented Apr 17, 2015

It also helps with discoverability. You know you need an OSName and that guides you to the static properties.

@akoeplinger
Copy link
Member

How is this supposed to work under the hood, i.e. will it end up calling uname?
Linux also seems to be quite broad (there are many different flavors), are there plans to expose more detailed info?

Just to confirm I understand this correctly: this can't be put into Environment because it'd mean it needs to be backported into Desktop .NET ?

@ellismg
Copy link
Contributor

ellismg commented Apr 18, 2015

How is this supposed to work under the hood, i.e. will it end up calling uname ?
Linux also seems to be quite broad (there are many different flavors), are there plans to expose more detailed info?

The current thinking is we would provide a different implementation assembly for each platform, which would hard-code the result, so we wouldn't call uname. We don't have current plans to expose something like Distro information from this type, but that's more because we don't understand the scenarios where one might want to do that.

We are hesitant, however, to do something like expose a Version of the OS your are running on.

Just to confirm I understand this correctly: this can't be put into Environment because it'd mean it needs to be backported into Desktop .NET?

Yeah, that is the basic problem.

@blobor
Copy link
Author

blobor commented Apr 18, 2015

@Priya91 For now, only contributing the issue.

@justinvp
Copy link
Contributor

I'd vote for just exposing the existing Environment.OSVersion.Platform API. This has been in .NET forever; introducing a new API that does the same thing is going to confuse and annoy developers.

@jaredpar
Copy link
Member

@justinvp wanted to avoid the use of enum for the platform portion which is how OperatingSystem defines the platform.

@davkean
Copy link
Member

davkean commented Apr 22, 2015

@jaredpar For reasons I still don't understand. :)

@akoeplinger
Copy link
Member

I also don't fully grok why all of this is necessary.

@ellismg can you summarize the problems again?

@HellBrick
Copy link

Frankly, I don't see how the proposed API is better than the old one. From the readability point of view, OSName.Windows is not that different from PlatformID.Windows, and all these values are going to be exposed anyway, whether through static properties or through enum values. However, using enum simplifies discovery a bit: you immediately have Intellisense suggesting correct values. Compare this to the OSName experience: the first intuitive thing to do when you need to provide an instance is to call a constructor... which needs a name for some reason. Is it "Windows"? "windows"? "Windows 8.1"? "Microsoft Windows [Version 6.3.9600]"? "Linux"? "Unix"? "Ubuntu"? This is going to be confusing until you stumble upon those static properties one way or another.

And a separate obscure class somewhere in System.Runtime.InteropServices isn't making this API more discoverable either. I wasn't googling Environment.OSVersion when I needed it, I just followed an obvious hunch that if there's an API that exposes the current platform, it's most likely located in the Environment class - and that's exactly where I found it.

@KrzysztofCwalina
Copy link
Member

Sorry, my post was a bit tongue in cheek. I know the deeper problem is complex. We discussed the complex issue many time and could not come up with a great small dunk solution. If we can come up with something great in this thread, it would be great. But for this, the discussion needs to focus on the deeper (scenario) problems, not on whether the thing is an enum, int, expanded acronym or not, etc.

@richlander
Copy link
Member

@whoisj I'm personally satisfied with the scenarios that you and @HellBrick gave. Certainly, we could make a longer list. @Priya91 is the one to say if she has enough requirements to make an update to her design.

Do you have any comments on whether the current design is adequate or not?

@KrzysztofCwalina Agree with you. The core issue is not the metadata representation of the API.

@whoisj
Copy link

whoisj commented Jun 2, 2015

Other than I prefer to not use [Flags] for the enum value because the [Flags] attribute indicates that they can coexist; and they cannot. I know the intent was to enable use of osPlatform.HasFlag(OSPlatform.OSX|OSPlatform.Linux) combined clause, but I argue that it no more readable, and not much less verbose, than osPlatform == OSPlatform.OSX || osPlatform == OSPlatform.Linux but likely less performant,

Otherwise, I'm happy as this as a starting point. I like to get general agreement that there's a lot more information that needs to be surfaced to make the API truely useful (see mentioned above about file system case sensitivity and preservation, etc).

@richlander
Copy link
Member

I meant something a bit different, which I didn't properly ask. Oops.

There is a q much higher in the thread about how one would do checks on Android. Would that be "Linux" or "Android" or would both be true? That's not an implementation detail. I'm interested in exploring the scenarios where the currently simple API might fall down.

Android is also interesting because there is the Dalvik / ART divide. That's divide won't be relevant for .NET Core. The interesting thing is that scenario. If .NET Core had 5 years of apps on Android, would people have had to do checks for runtime, or would that have been handled by the Java APIs? I assume so. It's still relevant for this discussion.

@Priya91
Copy link
Contributor

Priya91 commented Jun 2, 2015

@richlander :
Regarding the scenario that triggered this api proposal:

The primary use case for this feature arose from the x-plat work that we have been doing in corefx. Code specific to different platforms has been organized into separate files that are conditionally included during compile time in product. Writing tests for the product is a scenario that consumes the product and implements the different use-cases of this product. Now while writing tests, we had this problem where there was just this one line of code that differs between the different platforms. Of the ways that we could solve the problem at that time was to have different compilation for different platforms, which is too much effort for a single line of code. Having different compilation to test a single line of code leads to defining different pre-processor symbols and changes to build script to automate building for different platforms. All of this for a single line of code, and given the examples from @HellBrick it is evident the same kind of workarounds are being applied for simple scenarios. Another solution one might propose is to have a custom runtime platform detection, which is the temporary solution used in corefx here. So in essence people are coming up with creative ways to fill this void, when we should provide a good way to solve this problem in .NET Core, this being a common scenario.

On Linux:

Right now Linux implies desktop OS (we are not differentiating between different distros, and we may provide support for this later, note, that itself is another issue, what are the distros to be supported, etc). If we ever supported .NET core apps on android (mobile platform), we would add another value to the OSPlatform for Android. If this is confusing as to why Linux is not returning true for Android, then what would be a good name to differentiate linux desktop OS with android?

@richlander
Copy link
Member

@Priya91 What you wrote is not a use-case. That's mechanically how the feature is used. It doesn't help me understand if your proposal satisfies your need.

I was thinking of Linux as a kernel, similar to this thread: http://www.linux.org/threads/the-linux-kernel-android.5459/. My understanding is that Android uses the standard Linux kernel. Is that right?

@Priya91
Copy link
Contributor

Priya91 commented Jun 2, 2015

@richlander Forgive my ignorance, but can you define what you are expecting by use-case. This is what i think you are expecting:

Scenario: Develop a wallpaper changer app that runs on linux and windows, a very basic code sample:

namespace MyApp
{
    internal enum OSEnum
    {
        Windows, 
        Linux
    }

    public class WallpaperChanger
    {
        private void ChangeWindowsWallpaper() { }
        private void ChangeLinuxWallpaper() { }

        private OSEnum DetectOS()
        {
            /*In the absence of .NET Core platform detection API, I will have some custom logic here.*/
            return default(OSEnum);
        }

        internal void ShowImagesFromWeb() { }

        public void StartApp()
        {
            ShowImagesFromWeb();
            /*Wait for image select event to fire*/

            switch(DetectOS())
            {
                case OSEnum.Linux:
                    ChangeLinuxWallpaper();
                    break;

                case OSEnum.Windows:
                    ChangeWindowsWallpaper();
                    break;

                default:
                    throw new PlatformNotSupportedException();
            }
        }
    }
}

@richlander
Copy link
Member

@Priya91 These examples from @HellBrick are what I was looking for: https://github.com/dotnet/corefx/issues/1017#issuecomment-107797361.They describe actual platform differences that one must workaround. I'm sure that there are others.

Your example, while appreciated, displays a particular technique for differentiating behavior for an OS, but isn't really a use-case, since I cannot see the code that needs to differ. If I could see that, then it would be more clear which patterns and APIs would satisfy it. As it stands, I just have to trust you that the coding pattern that you chose is the right one.

@Priya91
Copy link
Contributor

Priya91 commented Jun 2, 2015

@richlander : In the previous example, to set the wallpaper i will have to interop into the linux/windows specific library and call the native api to actually do the change. The actual code that changes the wallpaper is irrelevant here, the focus should be on which library you are going to choose to interop to based on the platform. Those platform specific differences given by @HellBrick should be answered by the various framework apis that manipulate that data, for example, filesystem has path.directoryseparatorchar which will give the right path, similarly process.start to handle the differences, etc. I wouldn't even need to use this api for such scenarios, when i can directly call the cross plat .net framework api for that. It is in examples like above that this API is actually useful.

@nexussays
Copy link
Member

@whoisj

User-agent is kind of a hack and makes for a terrible API.

But so is this. That's exactly my point. Just because it's hidden behind enums and classes instead of strings doesn't make the conceptual intent of the API any different.
What is good about user-agent is that it is obvious that it is a hack and everyone uses feature checking now. That is, now one would check "does X exist in my current environment" versus "is my current environment Internet Explorer." (to wit, "am I running Linux" vs "is this filesystem case sensitive")

It would be better to have a "platform string" and admit where a kludge is a kludge than to have an enum which is out of date or provides a misleading API. ([edit] The point here being that an enum would have to be provided by corefx and I don't think the BCL should have any notion of what platforms it can run on.)

@HellBrick

One might argue that checking the platform type is not the best way to solve some of these problems

Yes, that is in fact exactly what I have been arguing.

@nexussays
Copy link
Member

@richlander

That's not an implementation detail. I'm interested in exploring the scenarios where the currently simple API might fall down.

Thank you :)


These are the examples @HellBrick provided, all of which (IMO) need a different and specific check.

  1. Choosing what folders to use for the data stored by our app: they are obviously different between Windows and Linux.

You want something like Environment.SpecialFolders. Also is it a guarantee that all distros of Linux are the same?

  1. Lowercasing all file names on Linux, to make it easier to live with the case-sensitive file system.

If this is a concern you should just do this universally to avoid the problem altogether. Clearly you need some FileSystem entity to check for capabilities of the particular environment you find yourself it. NTFS is case sensitive but Win32 isn't. There are Linux file systems that allow case-insensitivity. You probably don't care about that, would others?

  1. Adding an executable flag to a file if running on Unix.

Seems like this should be a property of a cross-platform file interaction API. Also isn't this a Posix API? Does OSX care about the executable bit?

  1. Using a different native library on Unix.

Available universally on any Linux distro? (if so, then yes, valid use-case for this feature!)

  1. Changing the way a child process is launched (on Windows it's just %path% %arguments%, on Unix it's mono %path% %arguments%.

This should absolutely be handled by some API, you shouldn't have to pass strings around like this.

  1. Switching in a different HttpClientHandler on Unix to work around a Mono bug.

Admittedly an edge case and not recommended behavior, no?

@nexussays
Copy link
Member

@Priya91 I know this was a quick example you just tossed together, so don't take this personally, but that is the sort of code that everyone should be moving away from. One's code should not be littered with platform checks. It shouldn't even be lightly dusted with platform checks. You would want some IDesktopWallpaper API which each platform implements and which you call from your application code -- application code that is agnostic to the platform on which it is running.

@mellinoe
Copy link
Contributor

mellinoe commented Jun 3, 2015

Coming into the discussion a bit late, but it seems like the main use case we are aiming to enable (and correct me if I'm wrong) is letting a library developer create implementations for multiple platforms without multiple compilations, and therefore without multiple release binaries. To me, that seems to be the one "thing" this library is aiming to solve. Apologies if this seems obvious, I thought I'd mention it anyways to try to get some clarity/consensus on that point. So to me, the use case is:

"Creating a cross-platform library which uses platform-specific logic, without shipping platform-specific binaries"

or even simpler:

"Use platform-specific logic within a platform-agnostic assembly"

A few more thoughts that pop to my mind:

  • As a library dev, shipping a single portable assembly that works everywhere is MUCH easier than shipping one-per-platform, when you think of build complexity, packaging, distribution, support, etc.
    • If you only have a single instance where you need to account for platform differences in a giant codebase, it is easier to swallow the downsides of this "runtime-detection" approach than to bite the bullet and build/ship multiple binaries.
    • If the "Wallpaper" example above was a part of a giant, platform-agnostic imaging library (bear with me...), it might be palpable for the dev to just say "screw it" and throw in a runtime platform check, rather than ship multiple binaries for that single difference.
  • The single "fat-assembly" will have wasted space, dead code, etc. when running on any single platform. There is also an obvious runtime cost to using this approach and is conceptually very "messy" when compared with conditional compilation. The overhead of this obviously depends on how much you actually make use of these runtime checks.
  • Our framework assemblies are going to be platform-specific; i.e. we will not be using this feature in the core libraries. So for someone releasing an app with a bundled runtime/framework, they will already need platform-specific distributions and the platform-portability of a single dependency is unimportant to them. It could actually be a downside due to the second bullet point above.

@nexussays brings up a very good point regarding the potential usages of the library. When you are pivoting around file paths or file names, you are really trying to make a decision based on the machine's file system behavior, not the name of the operating system. By pivoting on the operating system name, you are relying on your prior knowledge of OS and filesystem differences. From an API purity and usage standpoint, that is not ideal. It would be awesome if the libraries could abstract these important differences in a more meaningful and user-friendly way, but that's obviously not an easy problem in all cases.

@richlander
Copy link
Member

@Priya91 Your point is also my point. You and @nexussays say that most of the platform-specific operations would be covered by platform-agnostic facades, with platform-specific implementations, provided by .NET Core. That's definitely what we want.

So, your use case then is:

"My app relies on OS (or otherwise provided) functionality that is not provided by .NET Core and that differs by OS and that requires differentiated calls per OS."

Without seeing the actual P/Invokes, it was hard to see what the scenario was.

My question, then, is what the other scenarios are. I'm wondering if there are some cases where .NET Core APIs return results that are platform-specific that require differentiated handling.

@nexussays
Copy link
Member

@mellinoe (I doubt anyone minds you jumping in late. I jumped in like a week ago and now I'm trying to hijack the thread :))

That seems like a very good explanation; working off of that, my pushback is on the "use platform-specific logic" part, in which I will continuously ask: what logic? and why?

We should consider any time you need to "break out" of .NET and use platform-specific logic to be a "hole" in CoreFX. Could be it's an edge case that no one has addressed, could be it's too expensive, maybe it's already an open issue. Point being we ("we" the community) should address each such case individually and figure out what .NET Core API can provide for this platform-specific functionality.

It would be awesome if the libraries could abstract these important differences in a more meaningful and user-friendly way, but that's obviously not an easy problem in all cases.

I agree, but I'm saying show me those cases; specifically, enumerate what those cases are and then we can address them individually. Once we come across some platform-specific functionality that stumps this question then we can say ok, so we can't integrate this use-case into .NET, what's the next level of abstraction up that we can implement.

We've basically started at the highest possible level of abstraction with some abstract notion of "Operating System" in which Linux is a singular entity. That's my objection.

@HellBrick
Copy link

You want something like Environment.SpecialFolders. Also is it a guarantee that all distros of Linux are the same?

Not exactly. The concept is similar, but the folders that we use are specific to our system and Environment.SpecialFolders wouldn't really help to calculate them. And they actually are distro-agnostic, so possible migration to another distro shouldn't be a problem for us. Think of these paths as of our own conventions where to put our custom stuff, and these conventions are different between Windows and Linux.

If this is a concern you should just do this universally to avoid the problem altogether. Clearly you need some FileSystem entity to check for capabilities of the particular environment you find yourself it. NTFS is case sensitive but Win32 isn't. There are Linux file systems that allow case-insensitivity. You probably don't care about that, would others?

I'm with you on this one; like I said earlier, something like FileSystem.IsCaseSensitive would be perfect here.

Seems like this should be a property of a cross-platform file interaction API. Also isn't this a Posix API? Does OSX care about the executable bit?

I don't know if this flag is important to OSX, since we only use Windows and Linux servers. But come to think of it, I've never tested what will happen if I try to append Executable attribute to a file on Windows. If it works fine, then the platform check isn't really needed here.

Available universally on any Linux distro? (if so, then yes, valid use-case for this feature!)

We deploy this dependency with our app, both Windows and Ubuntu versions, and then choose one in runtime to avoid managing 2 separate builds and deployments. I'm not really sure if it works on the other distros, but even if it doesn't, it's hard to imagine scenario where we would choose to use two different Linux distros simultaneously in our cluster. Worst-case scenario, we could be forced to replace the platform type check with a distro check here, but I really don't think it will ever come to this.

This should absolutely be handled by some API, you shouldn't have to pass strings around like this.

Sorry, I don't get your point here. We're just launching a child process, and on different platforms we use different executables that obviously have slightly different argument strings. Some better API to manage argument strings would obviously be of help here, but it has nothing to do with the platform-dependent choice we're discussing here.

Admittedly an edge case and not recommended behavior, no?

It sure it is an edge case, but this is still a good example of a completely unpredictable yet real problem the platform check could help with. In case of this specific bug checking the platform is way easier than analyzing the types loaded into the current app domain to detect we're running on Mono, since in our case we're running on Mono if and only if we're running on Linux.

@whoisj
Copy link

whoisj commented Jun 3, 2015

A simple use-case for knowing what platform you're on (Linux, Mac, or Windows): scanning the file system to compare files present with a list of expected files present.

On Mac and/or Linux you're best off grabbing a bunch of strings (paths) then stating them as necessary. The same logic flow on Windows is a nightmare (performance is horrible). On Windows you want to use GetFirst/GetNext logic to traverse the tree caching data as you go.

The logic is different, it simply has to be or one platform will suffer performance penalties and have unhappy users. Can this be hidden behind some API facade? Sure - does it need to be? No. Will there be plenty of other topics like this? Yes.

Is this API sufficient? No. Is it a start in the right direction? I think so, but I'd like to see if flushed out more before we proceed.

@AbhishekTripathi
Copy link

@Priya91 I know this was a quick example you just tossed together, so don't take this personally, but that is the sort of code that everyone should be moving away from. One's code should not be littered with platform checks. It shouldn't even be lightly dusted with platform checks. You would want some IDesktopWallpaper API which each platform implements and which you call from your application code -- application code that is agnostic to the platform on which it is running.

@nexussays do you mind providing some pseudo code? I think your point is no different from what @Priya91 says. The actual logic to change the wallpaper is abstracted. It could be a native call or some IsA kind implementation. The jist is that you need to identify which of the descendants or the native API to call based on the current platform.

var wallpaperChanger = WallpaperChangerFactory( DetectOS() ) as IWallpaperChanger;
wallpaperChanger.ChangeWallpaper();

I am sorry if I didn't understand your point. May I please request you to elaborate a bit more?

@gluck
Copy link

gluck commented Jun 9, 2015

Having listened to the API review (thanks for hosting it !), I'm wondering if uname -s (aka sysname) would be a better fit for the reasons below (not mentioned during the talk):

  • even the review board is having a hard time deciding what is a platform and what's not (e.g. Raspberry Pi, Open/Free BSD), relying on "whatever uname -s gives you is what you get here" has a very low adoption barrier (and avoids re-writing new mapping tables such as the uname one )
    • that will also prevent the "will we accept this PR to add FooBar as an OSName value" that was mentioned and I think scared everyone
  • I believe this feature will be used mostly when porting to Unix systems
    • Windows has no use of it - yet - plus it already has APIs for accessing the Windows families
    • uname is the de-facto standard on Unix, openly accessible on NodeJS & Python, devs are used to that
    • dnx uses PInvoke to Uname to get platform information, and Mono.Posix exposes it, people need that
    • the chance that one can write a better API are small-ish

Also using uname, you may lack information, you may lack flexibility (won't be able to hack your own values in), you may lack enum niceties, but you can't make it wrong (on Unix).

I'm not 100% sure on this one, and I don't like the fact that it'd be an simple wrapper over the OS, but given the uncertainty/confusion around the topic during the review (flags/exclusive or not, versions or not, feature/capability or not), I can't help thinking than something else will fail.

@terrajobst
Copy link
Contributor

We've reviewed this proposal today. It has been approved with feedback.

@yufeih
Copy link
Contributor

yufeih commented Jun 12, 2015

Please also consider these use cases if corefx runs on Android/iOS:

  • Get the platform name/version of an app and report it back to the server for usage analysis
  • Get the platform name/version of an app to generate a crash report in case of exceptions

The API can only test if we are running on a given platform, but there is no way to retrieve the current platform.

@Priya91
Copy link
Contributor

Priya91 commented Jun 15, 2015

Closing this issue, as the scope of this issue was to get a query api into corefx to query for the underlying os platform.

@Priya91 Priya91 closed this as completed Jun 15, 2015
shrayasr referenced this issue in shrayasr/itko Nov 25, 2015
- Adds a new dependency to
  System.Runtime.InteropServices.RuntimeInformation.

More info can be found
  - On this issue: https://github.com/dotnet/corefx/issues/1017
  - On this PR: dotnet/corefx#1999
jp7677 referenced this issue in jp7677/NLog May 29, 2016
…. Using OperationSystem is not sufficient, e.g. it returns just "fedora" on Fedora Linux. See also https://github.com/dotnet/corefx/issues/1017.
304NotModified referenced this issue in NLog/NLog May 31, 2016
* Use RuntimeInformation.IsOSPlatform to determine the runtime platform. Using OperationSystem is not sufficient, e.g. it returns just "fedora" on Fedora Linux. See also  https://github.com/dotnet/corefx/issues/1017.

* Remove whitespaces.
@msftgits msftgits transferred this issue from dotnet/corefx Jan 31, 2020
@msftgits msftgits added this to the 1.0.0-rtm milestone Jan 31, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Jan 7, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api-needs-work API needs work before it is approved, it is NOT ready for implementation
Projects
None yet
Development

No branches or pull requests