Create a program that returns a truthy value when run on Microsoft Windows (for simplicity we'll stick with Windows 7, 8.1 and 10) and a falsey value when run on any other operating system (OSX, FreeBSD, Linux).


  • Code that fails to run/compile on a platform doesn't count as a falsey value.

Winning criteria

I'm labelling this as , so lowest score wins, but I'm also very interested in seeing creative solutions to this problem.

  • 7
    \$\begingroup\$ Can the programs output by exit code? (normally allowed) \$\endgroup\$ – FlipTack Jan 8 '17 at 12:33
  • 14
    \$\begingroup\$ Can you give a definite list of which operating systems this needs to work on? \$\endgroup\$ – FlipTack Jan 8 '17 at 14:46
  • 2
    \$\begingroup\$ What should the result be under Windows RT? \$\endgroup\$ – Adám Jan 8 '17 at 18:56
  • 7
    \$\begingroup\$ You may want to specify a few specific non-Windows systems that must be supported. There's some debates in comments about things like DOS and OS2. \$\endgroup\$ – jpmc26 Jan 9 '17 at 11:12
  • 2
    \$\begingroup\$ We probably need a consensus about what counts as truthy and falsey for exit codes; the normal convention is 0 for true and anything else for false, but many answers are treating it as the opposite, and the "if statement" definition doesn't obviously apply. \$\endgroup\$ – user62131 Jan 10 '17 at 6:17

50 Answers 50


Vim, 2 bytes


On Windows, <C-a> (ctrl+a) is mapped by default to Select All. If you type a 1 in select mode in Windows, it replaces the selection with what you typed (1) leaving a 1 in the buffer.

On other operating systems, <C-a> by default is mapped to Increment number. Because there's no number to increment, it's a no-op, and then the 1 increases the count but in terms of the buffer is a no-op.

1 is truthy in Vim, and an empty string is falsy

  • \$\begingroup\$ Looks like 3 keystrokes. Ctrl+a+1 \$\endgroup\$ – Pavel Jan 8 '17 at 23:51
  • 13
    \$\begingroup\$ I think per this meta post meta.codegolf.stackexchange.com/questions/8995/… Vim answers are generally scored without the modifiers (especially given that the first answer on the post uses <ctrl+a> as an example for 1 byte) \$\endgroup\$ – nmjcman101 Jan 8 '17 at 23:54
  • 4
    \$\begingroup\$ @Pavel it's Ctrl + a, 1. If it were Ctrl + a + 1 it'd be counted as 1 keystroke. \$\endgroup\$ – Captain Man Jan 9 '17 at 21:34
  • 7
    \$\begingroup\$ Beautiful, I love this answer! \$\endgroup\$ – James Jan 10 '17 at 7:08
  • \$\begingroup\$ That's rather elegant, I like it. \$\endgroup\$ – Dan Jan 11 '17 at 18:20

MATLAB, 4 bytes


From the documentation:

tf = ispc returns logical 1 (true) if the version of MATLAB® software is for the Microsoft® Windows® platform. Otherwise, it returns logical 0 (false).

There are also the functions ismac and isunix. I'll leave it to the reader to figure out what those functions do. Mego kindly asked for diagrams explaining ismac and isunix so I've tried to illustrate it here:

enter image description here

It was not asked for a diagram of ispc but I can reveal that the behaviour is pretty similar, except substitute OSX and Unix with Windows.

Second approach:

Here's a second approach with getenv using 23 bytes that should be bullet proof, unless there's another operating system starting with W:


getenv 'name' searches the underlying operating system environment list for text of the form name=value, where name is the input character vector. If found, MATLAB® returns the character vector value. If the specified name cannot be found, an empty matrix is returned.

  • 4
    \$\begingroup\$ Comments are not for extended discussion; this conversation has been moved to chat. \$\endgroup\$ – Dennis Jan 11 '17 at 20:46

Python 2.7.10, 24 bytes

import os

Thanks to FlipTack for 3 bytes

This program takes advantage of the fact that Windows is the only OS to use \ as a path separator. Normally this is frustrating and bad, but for once it is actually an advantage. On Windows, '['>os.sep is false, and thus 0/0 is computed, causing a ZeroDivisionError and exiting with a non-zero exit code. On non-Windows platforms, '['>os.sep is true, making the expression 0/1, which does nothing, and the program exits with exit code 0.

  • \$\begingroup\$ DOS also uses a backslash as the path separator and it has at least one Python 2 implementation. \$\endgroup\$ – isanae Jan 8 '17 at 15:50
  • 5
    \$\begingroup\$ @isanae I've edited the title to specify Python 2.7 - the only Python 2 implementation on DOS is an archaic, buggy 2.4.2 \$\endgroup\$ – user45941 Jan 8 '17 at 15:56
  • \$\begingroup\$ OS/2 also uses a backslash and has a Python 2.7 implementation ;) \$\endgroup\$ – isanae Jan 8 '17 at 16:02
  • 9
    \$\begingroup\$ @isanae There, I specified 2.7.10. Good luck finding a port of that. \$\endgroup\$ – user45941 Jan 9 '17 at 0:08
  • 2
    \$\begingroup\$ apparently it only needs to give correct results on 3 recent windows versions and presumably similarly recent versios of the three other systems listed, OS2 and DOS don't matter, \$\endgroup\$ – Jasen Jan 9 '17 at 1:22

x86 Assembly, 7 bytes (Inspired by Runemoro's answer)

31 DB 89 D8 40 CD 80


xor ebx, ebx 
mov eax, ebx
inc eax
int 0x80


First of all, we'll set eax to 1 (the system call number for exit(int val) for Linux, FreeBSD and OSX). Then, we'll call the interrupt gate 0x80 which is the system call gate for Linux, FreeBSD and OSX. That would cause the program to exit with status of ebx which is 0 (false).

On Windows int 0x80 is an invalid gate (It uses 2e as a syscall gate) and would crash the program, causing it to end with a positive exit code (true).

Edit: Would not work on OSX since it has a different argument-passing convention on 32 bit (by the stack).

References and further reading

  • 3
    \$\begingroup\$ That's brilliant! \$\endgroup\$ – z0rberg's Jan 9 '17 at 17:46
  • \$\begingroup\$ Why does the crash cases a truthy value? Is it because EAX (typically the return value) is 1? Also, is EAX guaranteed to be 0 at program start? Or do you need xor eax, eax in there? \$\endgroup\$ – Cole Johnson Jan 9 '17 at 22:13
  • 3
    \$\begingroup\$ @ColeJohnson: OS-detected crashes (on the operating systems typically used with x86) never leave an exit code of 0, because that's reserved for successful termination. (Normally the exit code is some wonky value that the OS reserves specifically for this circumstance.) However, I'm not sure it makes sense to count 0 as falsey and 1 as truthy in program exit codes, given that the normal convention is the exact opposite (with 0 being the only truthy vaue, e.g. the standard UNIX/Linux/POSIX program false exits with code 1 whilst true exits with code 0). \$\endgroup\$ – user62131 Jan 10 '17 at 6:10
  • 1
    \$\begingroup\$ This answer implicitly assumes that registers eax and ebx are cleared to zero on program start (on non-Windows), which is not guaranteed if I remember correctly. It also explicitly assumes that the syscall argument-passing convention for Linux matches that for FreeBSD and OSX, which would be very surprising indeed. \$\endgroup\$ – zwol Jan 11 '17 at 21:45
  • 1
    \$\begingroup\$ @Sebastian-LaurenţiuPlesciuc Good question. mov eax, 1 would be translated to \xB8\x01\x00\x00\x00, which is a lot longer that just moving register and calling inc. \$\endgroup\$ – Shmuel H. Jan 13 '17 at 12:48

C, 44 43 38 36 bytes

Thanks to @Downgoat for a byte! crossed out 44 is still regular 44
Thanks to @Neil for two bytes!

#ifdef WIN32
  • \$\begingroup\$ Originally I was going to suggest that you can save a bunch of bytes by moving the 0 out of the ifdef and changing the 1 to !, but I think _WIN32+0 works even better still. \$\endgroup\$ – Neil Jan 8 '17 at 13:52
  • \$\begingroup\$ If c99 is OK you can change f to main and stick return 1; inside the ifdef and remove the else, since main without return in c99 must return 0. \$\endgroup\$ – simon Jan 8 '17 at 13:56
  • 11
    \$\begingroup\$ That's a compiler directive. If it's compiled on a Windows system and run on a Linux system, for example, it will still return 1. \$\endgroup\$ – Micheal Johnson Jan 8 '17 at 14:44
  • 4
    \$\begingroup\$ @MichealJohnson no. I can compile it on linux (using mingw32gcc msvc) snd get code that returns true when run on windows. I don't know of any windows-hosted linux compiler. if you want to argue emulation layers like "wine" all the other answers probably suffer the same problem \$\endgroup\$ – Jasen Jan 9 '17 at 1:29
  • 1
    \$\begingroup\$ Not sure if WIN32 is just defined, but is defined to non-zero. If it's the later case, you can just say #if WIN32. On non-windows, since WIN32 is not defined, the preprocessor is required to treat it as 0. \$\endgroup\$ – Shahbaz Jan 9 '17 at 23:15

PHP, 22 bytes


prints 1 if the path separator is semicolon (colon or empty for all other OSs except for DOS and OS/2), else nothing.

also 22 bytes, but not that safe:


prints a positive integer if the file path contains a backslash; else nothing.
A safe alternative with 27 bytes: <?=DIRECTORY_SEPARATOR>"/"; prints 1 or nothing.

A strange find: <?=__FILE__[1]==":"; (20 bytes) should be, not safe either, but ok. But although __FILE__ pretends to be a string (I tried var_dump and gettype), indexing it throws an error, unless you copy it somewhere else (concatenation also works) or use it as a function parameter.

<?=(__FILE__)[1]==":"; (also 22 bytes) works in PHP 7; but that´s because the parentheses copy the constant´s value to a temporary variable.

27 bytes: <?=stripos(PHP_OS,win)===0;
tests if predefined PHP_OS constant starts with win (case insensitive; Windows,WIN32,WINNT, but not CYGWIN or Darwin); prints 1 for Windows, else nothing.

17/18 bytes:


prints 1 if it was stored with Windows linebreak (also on DOS, OS/2 and Atari TOS - although I doubt that anyone ever compiled PHP for TOS), else 0.

You could also check the constant PHP_EOL.

more options:

PHP_SHLIB_SUFFIX is dll on Windows, but not necessarily only there.
php_uname() returns info on the operating system and more; starts with Windows for Windows.
$_SERVER['HTTP_USER_AGENT'] will contain Windows when called in a browser on Windows.
<?=defined(PHP_WINDOWS_VERSION_BUILD); (38 bytes) works in PHP>=5.3


The only failsafe way to tell if it´s really Windows, not anything looking like it, seems to be a check on the OS name. For PHP: php_os() may be disabled for security reasons; but PHP_OS will probably always contain the desired info.

  • 4
    \$\begingroup\$ File names on *nix can contain backslashes, so this isn't really foolproof. The rules don't say it has to be foolproof, though, so ¯\_(ツ)_/¯ \$\endgroup\$ – Jordan Jan 8 '17 at 15:10
  • \$\begingroup\$ @Jordan: You´re right. I added that info to the description. Thanks. \$\endgroup\$ – Titus Jan 8 '17 at 15:57
  • 4
    \$\begingroup\$ An alternative: <?=class_exists(COM);. The class COM is only available under Windows, as far as I know. That should save you one byte. \$\endgroup\$ – Ismael Miguel Jan 8 '17 at 22:28
  • \$\begingroup\$ @IsmaelMiguel That's enough of a different answer for you to post it as such. (However, it may not be worth it to do so; this answer is very well written.) \$\endgroup\$ – wizzwizz4 Jan 9 '17 at 18:35
  • 1
    \$\begingroup\$ @wizzwizz4 It isn't worth it. The answer would be pushed to oblivion. That's why I simply left the comment, instead of writting my own answer. \$\endgroup\$ – Ismael Miguel Jan 9 '17 at 18:45

Befunge-98, 7 bytes


Try it online!

This works by querying the system path separator, which is \ on Windows and / on other operating systems.

6y            System information query: #6 returns the path separator.
  2%          Test the low bit - this will be 1 for '/' and 0 for '\'.
    !         Not the value, so it becomes 0 for '/' and 1 for '\'.   
     .@       Output the result and exit.

Mathematica, 28 bytes

  • \$\begingroup\$ What's the point in making it a function? You could remove the ampersand saving one byte, and the code would just directly evaluate whether it's executed is on a Windows-ish system. \$\endgroup\$ – Ruslan Jan 8 '17 at 18:01
  • \$\begingroup\$ @Ruslan All answers must be either full programs that print the result or callable functions. If this is declared a Mathematica notebook answer, then you might get away with calling it a full program, but if I invoke the thing from the command-line without the &, it won't print anything (and it's then also not a callable function, but merely a snippet/expression). \$\endgroup\$ – Martin Ender Jan 8 '17 at 19:04
  • \$\begingroup\$ @MartinEnder Really no output? I get Out[1]= False output from this: ~/opt/Mathematica/11.0/Executables/math <<< '$OperatingSystem=="Windows"' \$\endgroup\$ – Ruslan Jan 8 '17 at 19:33
  • \$\begingroup\$ @Ruslan I believe that also starts a notebook environment (just a command-line based one). What I mean by running a program from the command-line is using script mode. \$\endgroup\$ – Martin Ender Jan 8 '17 at 20:07

Java 8, 33 bytes

Special thanks to Olivier Grégoire for suggesting separatorChar, and Kritixi Lithos for -1 byte!

This is a lambda expression which returns a boolean. This can be assigned to Supplier<Boolean> f = ...; and called with f.get().


Try it online! - the server isn't windows, so this prints false. However, in my windows machine, the same code prints true.

What this code does is get the System's file seperator, and check whether its codepoint is larger than the character [. This true for Windows, as it uses \ as the seperator - but every other OS uses /, which has a lower code in the ASCII table.

  • \$\begingroup\$ Won't this break on other OSes which start with W? \$\endgroup\$ – Downgoat Jan 8 '17 at 14:44
  • \$\begingroup\$ ()->java.io.File.separatorChar=='\\' is only 36 bytes. \$\endgroup\$ – Olivier Grégoire Jan 8 '17 at 15:11
  • 1
    \$\begingroup\$ @OlivierGrégoire nice one - and I can golf it to 34 using ()->java.io.File.separatorChar>'['! \$\endgroup\$ – FlipTack Jan 8 '17 at 15:16
  • 2
    \$\begingroup\$ @Titus WebOS, Whonix. Probably even more. \$\endgroup\$ – Olivier Grégoire Jan 8 '17 at 16:54
  • 3
    \$\begingroup\$ @Titus Wait, what about WAITS? \$\endgroup\$ – NoOneIsHere Jan 9 '17 at 17:33

R, 15 bytes


Thanks to plannapus for the suggestion to use partial matching for list element extraction.

.Platform is a list with some details of the platform under which R was built. There is an element OS.type (the only element with name starting with "O") which is character string, giving the Operating System (family) of the computer. One of "unix" or "windows".

So "unix" is less then "v", but "windows" is greater then "v". Other valid 15 bytes answers are


R is being developed for the Unix-like, Windows and Mac families of operating systems. Other OS families are not supported.

  • 1
    \$\begingroup\$ there are platforms other than unix that aren't windows you know... \$\endgroup\$ – Blue Jan 8 '17 at 20:28
  • 2
    \$\begingroup\$ @muddyfish: .Platform[[1]] is defined as either "unix" or "windows" in R documentation. github.com/wch/r-source/blob/… \$\endgroup\$ – liori Jan 8 '17 at 21:20
  • \$\begingroup\$ Sorry, that's ok then. The answer should probably be modified to include this fact to stop that being asked again \$\endgroup\$ – Blue Jan 8 '17 at 22:37

J, 7 bytes


This is a verb (similar to a function) that uses the builtin foreign conjunction 9!:12 to acquire the system type where 5 is Unix and 6 is Windows32.

  • \$\begingroup\$ J Official documentation shows it returns this value for older Windows. "6 Windows32 (95/98/2000/NT)" Does the documentation need to be updated? What happens when it is 64 bit Windows? jsoftware.com/help/dictionary/dx009.htm \$\endgroup\$ – Keeta - reinstate Monica Jan 12 '17 at 14:05
  • \$\begingroup\$ Tested on 64 bit Windows 7 and it returns a 6. Documentation seems to be quite old. \$\endgroup\$ – Keeta - reinstate Monica Jan 12 '17 at 14:17
  • \$\begingroup\$ @Keeta Yes I think it is old but it still returned a 6 for me on Windows 10 64 bit. \$\endgroup\$ – miles Jan 12 '17 at 20:23

Perl, 11 bytes


^O should be replaced by a literal Control-O.

Outputs 1 on windows, nothing on another OS.

Note that I'm not using say as it adds a trailing newline, which is truthy in Perl.

-2 bytes thanks to primo. (and fixed potential issues)
-1 bytes thanks to ais523.

  • \$\begingroup\$ AFAIR this won't work in Cygwin Perl. \$\endgroup\$ – Igor Skochinsky Jan 9 '17 at 11:43
  • \$\begingroup\$ This won't work in mingw Perl either. Perl treats those both as distinct operating systems from Windows, though (as they generally obey UNIX rather than Windows conventions), and it's not clear whether they should count for the purpose of the question. In other news, you can save a byte here by using a literal control-O character rather than ^O. \$\endgroup\$ – user62131 Jan 10 '17 at 6:16
  • \$\begingroup\$ @ais523 I edited that, thanks. As for Cygwin and Mingw, I'll delete the post if they should be considered as Windows, but as you say, it would make more sense to consider them like separate OS (or at least, like not-Windows OS). \$\endgroup\$ – Dada Jan 10 '17 at 6:40
  • \$\begingroup\$ Regex delimiters shouldn't be necessary $^O=~W, although, I would probably match against MS. Alternatively, you could also match $^X=~':'. \$\endgroup\$ – primo Jan 11 '17 at 12:21
  • \$\begingroup\$ @primo right, thanks. I don't know any other OS with a W in it so I assumed checking for a W for fine.. any reasons why you suggest MS instead? \$\endgroup\$ – Dada Jan 11 '17 at 12:24

julia, 10 bytes


A function that returns true for windows


x86 machine code, 9 bytes

40 39 04 24 75 02 CD 80 C3

Compiled from:

inc eax        ; set eax to 1
cmp [esp], eax ; check if [esp] == 1 (linux)
jne windows    ; jump over "int 0x80" if on windows
int 0x80       ; exit with exit code 0 (ebx)
ret            ; exit with exit code 1 (eax)
  • 3
    \$\begingroup\$ pure binary (COM) won't run on Windows or Linux so not sure if this is valid \$\endgroup\$ – Igor Skochinsky Jan 9 '17 at 11:44
  • \$\begingroup\$ @IgorSkochinsky There must be an interpreter for assembly. \$\endgroup\$ – Shmuel H. Jan 9 '17 at 14:59
  • \$\begingroup\$ You can make the code even shorter by leaving only inc eax and int 0x80, I think it should fail on windows and terminate the process. \$\endgroup\$ – Shmuel H. Jan 9 '17 at 15:00
  • 2
    \$\begingroup\$ @IgorSkochinsky There are programs that run raw binary too. See the link in my previous comment. \$\endgroup\$ – Shmuel H. Jan 9 '17 at 15:18
  • 1
    \$\begingroup\$ Bochs and QEMU simulate bare metal environment and do not run the binary code under the host OS. So they won't work IMO. But this all could be a discussion for the meta. \$\endgroup\$ – Igor Skochinsky Jan 10 '17 at 23:53

JavaScript, 42 30 26 25 bytes


Tested with Firefox. (Chrome doesn't have the oscpu property.) Since lowercase letters have a higher character code than uppercase letters, this depends on the first letter of navigator.oscpu being uppercase and not being W, X, Y or Z on any platform that Firefox supports (other than Windows, of course). According to this post, that is the case.


  1. Saved 12 bytes thanks to Neil.
  2. Saved another four bytes
  3. Saved another byte thanks to Blender.
  • \$\begingroup\$ oscpu is probably the shortest navigator property that you can use. Also, testing a regexp will probably work out shorter, but I haven't measured it. \$\endgroup\$ – Neil Jan 8 '17 at 13:54
  • \$\begingroup\$ You can remove !=-1 and add a ~ right after the fat arrow, saving 3 bytes. \$\endgroup\$ – Luke Jan 8 '17 at 16:06
  • \$\begingroup\$ Do you have to create a function? Can't you just console.log the regex test? Also would navigator.oscpu[0]=='W' work or is there another OS that also starts with W. \$\endgroup\$ – user64039 Jan 9 '17 at 11:17
  • 2
    \$\begingroup\$ Hmm, for some reason my Chrome doesn't have oscpu. \$\endgroup\$ – Muzer Jan 9 '17 at 13:46
  • 2
    \$\begingroup\$ navigator.oscpu>'V' might work as well \$\endgroup\$ – Blender Jan 11 '17 at 3:03

C#, 61 48 bytes


Saved 13 bytes thanks to TheLethalCoder

Or a full program at 83 bytes:

class P{static int Main(){return(int)System.Environment.OSVersion.Platform<4?1:0;}}

Various Windows variants use enum values 0 to 3 in the Microsoft .NET implementation. 4 is Unix, 5 is Xbox [360] (which I won't consider "Windows"), 6 is MacOSX. Mono uses the same values, adding 128 for Unix/Linux in earlier versions.

Therefore, anything < 4 is Windows, and everything else is not Windows.

  • 2
    \$\begingroup\$ Not sure if I'm missing something, but why are you casting the value to an int? \$\endgroup\$ – auhmaan Jan 10 '17 at 15:18
  • \$\begingroup\$ @auhmaan CS0019 Operator '<' cannot be applied to operands of type 'PlatformID' and 'int' -- basically, C#'s typing rules says I can't compare a PlatformID and int directly, and there's no implicit cast from PlatformID to int. But there is an explicit cast from all enums to their values, which I take advantage of here... \$\endgroup\$ – Bob Jan 10 '17 at 21:59
  • 1
    \$\begingroup\$ @MustafaAKTAŞ Also, I have to point out that this is targeting C#/.NET Framework/.NET Core. On Xbox One it's only possible to run UWP apps, which use a different API not including System.Environment.OSVersion at all. If you're going to take issue with that, then you should also delete every other non-UWP answer. It also turns out that you can't (currently) run UWP apps on non-Windows platforms, so you can go delete all those too. Which leaves you with 0 answers, and an unanswerable question. \$\endgroup\$ – Bob Jan 11 '17 at 12:08
  • 1
    \$\begingroup\$ You can compile to an Action<bool> in the first example for 48 bytes (I haven't tested it but believe it will work) _=>(int)System.Environment.OSVersion.Platform<4; It might need to be ()=>... for 49 bytes though \$\endgroup\$ – TheLethalCoder Jan 11 '17 at 12:58
  • 1
    \$\begingroup\$ Compiling to anonymous functions such as Funcs and Actions are used all the time here. I believe it's in the golfing tips page and I use them almost all the time. Also anonymous functions are used in other languages a lot so I think it is safe to use them here \$\endgroup\$ – TheLethalCoder Jan 11 '17 at 14:23

Batch, 50 bytes

@if %OS%==Windows_NT if not exist Z:\bin\sh echo 1

Edit: Fixed to ignore DOS instead of claiming that it's Windows.

The only other way I know of running Batch outside of Windows is to use WINE which by default will map Z: to /. Therefore if Z:\bin\sh exists, chances are that it's /bin/sh, so not MS Windows.

I don't know what WINE sets %OS% to, but if it's not Windows_NT then I could save 23 bytes.

  • 1
    \$\begingroup\$ Another way is DOS, which is not Windows. \$\endgroup\$ – Ruslan Jan 8 '17 at 18:03
  • \$\begingroup\$ Not only does this fail under DOS, but also, on a computer where Z: is mapped, and happens to contain such a path. \$\endgroup\$ – Adám Jan 8 '17 at 18:49
  • 1
    \$\begingroup\$ At least I'm trying to detect WINE. None of the other answers will give the correct result when run under WINE either. \$\endgroup\$ – Neil Jan 8 '17 at 18:51
  • 3
    \$\begingroup\$ @Adám Sure and if you compile the C answer with -DWIN32=1 then it fails too. Your point? \$\endgroup\$ – Neil Jan 8 '17 at 19:13
  • 1
    \$\begingroup\$ yes, wine sets OS=Windows_NT \$\endgroup\$ – Jasen Jan 9 '17 at 1:31

QBasic, 31 bytes


Prints non-zero under Windows, 0 under everything else.

COMSPEC is an environment variable unique to Microsoft OSs. It points to the command interpreter, typically command.com or cmd.exe. Under Windows, the command interpreter sits somewhere in the Windows directory; under MS-DOS, it sits in the DOS directory or on the root of the disk, and under any other OS, it doesn't exist.

By checking to see if the value of COMSPEC contains a "W", we can tell the difference between Windows and not-Windows.

  • \$\begingroup\$ COMSPEC isn't reserved to mean anything in particular under Linux (meaning it's under user control by default), so isn't it possible that the user's set it to a value that they're using for their own purposes (and happens to contain a W)? Admittedly, that's a bit of an edge case. \$\endgroup\$ – user62131 Jan 10 '17 at 6:12
  • 1
    \$\begingroup\$ @ais523: Also, the Windows directory doesn't have to contain a W. It's brittle in either case. \$\endgroup\$ – Joey Jan 10 '17 at 8:13

Node.js, 27 16 15 13 bytes

Thanks to @Patrick, who shaved 12 bytes off my solution using Node's REPL:


Original solution:

  • \$\begingroup\$ If you change this to Node.js REPL, you can save 16 bytes by just using _=>path.sep!='/' \$\endgroup\$ – Patrick Roberts Jan 10 '17 at 9:44
  • \$\begingroup\$ I'm new to codegolf. Am I allowed to do that? \$\endgroup\$ – GilZ Jan 10 '17 at 9:45
  • \$\begingroup\$ Yes, otherwise I wouldn't have suggested it. REPL means read, execute, print loop, the program that runs when you enter node on the console. From there, all the system node modules are available without the need to require() them. \$\endgroup\$ – Patrick Roberts Jan 10 '17 at 9:48
  • \$\begingroup\$ Oh yeah sorry. I meant 11. You can save another byte by changing != to > since the ASCII index for \ is 92 and / is 47. \$\endgroup\$ – Patrick Roberts Jan 13 '17 at 9:13

Excel VBA, 41 40 30 29 26 24 Bytes

Immediate windows function that returns true if the system's OS code starts is longer than length 3, because the info is restricted to output either else mac or pcdos this returns true only on windows pcs


Previous Versions

''# Ignore the second `"` that follows every `\` - its only there for highlighting 

?Left(Environ("OS"),1)="W"                 # 24 Bytes

?InStr(ThisWorkbook.Path,"\"")             # 29 Bytes

?Mid(ThisWorkbook.Path,3,1)="\""           # 30 Bytes, Restricted to local Files

?Application.PathSeparator="\""            # 30 Bytes

?Left(Application.OperatingSystem,1)="W"   # 40 Bytes


-1 Thanks to Neil for using Left(...,1) over Mid(...,1,1)

-10 Thanks to ChrisH for pointing out @Mego's Path Separator Trick

-1 For Checking the WorkbookPath for "\" rather than using Application.Path Separator

-4 For switching to Environ()

-2 For switching to [Len(Info(...

Novel Solution, 51 bytes

Novel subroutine that outputs, to the VBE immediates window, a 1 (truthy) under windows and 0 (falsey) under mac by method of conditional compilation.

Sub a
#If Mac Then
#End If
End Sub
  • 1
    \$\begingroup\$ left saves you a byte. \$\endgroup\$ – Neil Jan 9 '17 at 8:49
  • \$\begingroup\$ Have you tried it on office365 online? Does that even support VBA? Just curious. \$\endgroup\$ – Chris H Jan 10 '17 at 11:21
  • \$\begingroup\$ @ChrisH To my knowledge office.com does not support online VBA scripting (though if anyone else knows better please do tell me, that would make my life significantly easier); However, with O365 you have the rights to download a copy of Office 2016 (or whatever is current) to your desktop, and that does support VBA scripting. \$\endgroup\$ – Taylor Scott Jan 10 '17 at 15:08
  • \$\begingroup\$ I've so far manage to avoid it; given your comment that looks set to continue (the only windows machines I use have a desktop copy of office, personal machines are all linux) \$\endgroup\$ – Chris H Jan 10 '17 at 15:13
  • 1
    \$\begingroup\$ @Mego's path separator trick (?Application.PathSeparator)="\" would be 32 as it's a single char) \$\endgroup\$ – Chris H Jan 10 '17 at 15:18

Perl 6,  19  18 bytes

put $*DISTRO.is-win
put ?($*CWD~~/\\/)

Both output True␤ or False␤ depending on the system it is run on.

  • \$\begingroup\$ the second one relies on the non windows values of CWD not containing any `` - there's no guarantee of that, \$\endgroup\$ – Jasen Jan 9 '17 at 1:39

APL (Dyalog), 21 bytes


Try it online!

#⎕WG'APLVersion' Root (#) Window Get property APL Version

 enlist (flatten)

'W'∊ is W a member? (no non-Windows return values contain a capital W)


tcl, 38 bytes

 expr [lsearch $tcl_platform windows]>0

PHP 17 Bytes

The following will output 1 if windows and nothing if anything else. Ignoring notices of string convertion.


Try online Online tests for linux because the sandbox is linux for PoC.

  • \$\begingroup\$ Sure that is enough? Asking because Possible Values For: PHP_OS. \$\endgroup\$ – manatwork Jan 9 '17 at 8:05
  • 1
    \$\begingroup\$ '<?=PHP_OS[0]==W;` is both 1 byte shorter and catches all the other windows values in the question linked by manatwork. >V might work too. \$\endgroup\$ – user59178 Jan 9 '17 at 10:18
  • \$\begingroup\$ manatwork depends on which windows version PHP was compiled on, since Windows Visa\7, Windows version has been represented with WINNT because of the NT Authority Kernel. before windows XP and below was WIN32 and Windows server 2003 was Windows. \$\endgroup\$ – DrWhat Jan 24 '17 at 11:17

Java 8, 49 bytes


Longer than the other Java answer, but takes a different approach.

This lambda fits in a Supplier<Boolean> and can be tested with the following program:

public class DetectMSWindows {

  public static void main(String[] args) {
    System.out.println(f(() -> System.getenv().get("OS").contains("Windows")));

  private static boolean f(java.util.function.Supplier<Boolean> s) {
    return s.get();

  • \$\begingroup\$ It's very, very similar to the initial answer that you link (before the edits). \$\endgroup\$ – Olivier Grégoire Jan 9 '17 at 11:45
  • \$\begingroup\$ Why not just .contains("W")? \$\endgroup\$ – Cyoce Jan 11 '17 at 0:11
  • \$\begingroup\$ @Cyoce actually, the variable OS appears to be Windows-specific. \$\endgroup\$ – user18932 Jan 11 '17 at 2:43

bash + coreutils, 5 bytes

rm $0

Also works in most other POSIXy shells. (Note that Windows ports of bash and rm exist; even though they're only normally used with more heavily POSIXy operating systems, this isn't an entirely vacuous entry.) Outputs via exit code (0 = false, 1 = true). Can be counted as 4 bytes if you're allowed to assume a filename (e.g. rm a). Note that this can potentially fail in the case of very weird filenames (which rm will interpret as arguments due to the lack of quoting, and possibly delete files you care about, so I'd advise against running this program from a file with a weird name).

Note: deletes the program from disk as a side effect, or at least tries to. In the case where we're running on Windows, the OS will fail to delete the running file (an operation that Windows disallows either by default or full stop), and thus rm will error out. bash catches the error and converts it into an exit code (thus the program as a whole terminates normally). Most of the other entries here are using 0 for falsey and 1 for truthy in exit codes, so this does the same; note that bash's if statement doesn't accept integers at all (rather, it accepts commands and branches based on whether they run successfully, and arithmetic tests are done via the means of programs like test that intentionally report a "crash" on a failed comparison), so this is on shakier ground in terms of legality than programs that output via exit code in languages where 0 is valid in an if statement test and sends the program to the else branch.


8th, 11 bytes

os 1- not .

Prints true on Windows, false on Linux and macOS. Other platforms supported by 8th are Android, iOS and Raspberry Pi, but I am not able to test on them.

Ungolfed version (with comments)

G:os  \ Return a number n indicating the operating system 
      \ 0 for Linux
      \ 1 for Windows 
      \ 2 for macOS
      \ 3 for Android 
      \ 4 for iOS 
      \ 5 for Raspberry Pi
n:1-  \ Subtract 1
G:not \ If Windows --> true, otherwise --> false
.     \ Print result

Python 3 (13 bytes)

import winreg

Returns with exit code zero (generally true in shells) if on windows, and with a non-zero exit code otherwise.

If you prefer it the other way round, there is a 12 bytes solution: import posix.

  • \$\begingroup\$ I think this will not work if there is a file called winreg.py in the same directory. \$\endgroup\$ – Zacharý Jul 20 '17 at 16:00
  • 2
    \$\begingroup\$ Also, per the rules: "Code that fails to run/compile on a platform doesn't count as a falsey value." \$\endgroup\$ – Zacharý Jul 20 '17 at 16:01

TrumpScript, 17 bytes

America is great.

Try it online!

This program, if run on windows, will print:

The big problem this country has is being PC

This is considered a truthy value.

Empty output and the following value are falsy:

Boycott all Apple products  until such time as Apple gives cellphone info to authorities regarding radical Islamic terrorist couple from Cal

The empty output will occur on any linux system (for this program), the long apple response obviously occurs on Mac (for any program). On TIO, the backend (I'm assuming) is a Unix operating system, so you can only get the falsy value; on my computer I get the PC message.

Not 100% sure if this counts as an error message (which would invalidate the answer), but if you didn't know about this it was probably worth a laugh for you.

  • \$\begingroup\$ What has the world come to... \$\endgroup\$ – ooransoy Jul 20 '17 at 12:52
  • \$\begingroup\$ @avaragecoder MAKE PYTHON GREAT AGAIN! \$\endgroup\$ – Magic Octopus Urn Jul 20 '17 at 14:47

FPC, 61 chars

begin{$ifdef win32}write('f');{$else}write('nf');{$endif}end;
  • \$\begingroup\$ you can shave some bytes by using only one write begin write({$ifdef win32}1{$else}0{$endif});end. \$\endgroup\$ – hdrz Jan 9 '17 at 6:21
  • \$\begingroup\$ Or to work on win64 as well: begin write({$ifdef windows}1{$else}0{$endif})end. \$\endgroup\$ – hdrz Jan 9 '17 at 6:42
  • \$\begingroup\$ @hdrz, yes, you right, thanks ;) \$\endgroup\$ – user64239 Jan 9 '17 at 7:47
  • \$\begingroup\$ @hdrz, sure that would be correct? 1 and 0 are not truthy/falsey in Pascal. I would go with begin write(1={$ifdef windows}1{$endif}+0)end. \$\endgroup\$ – manatwork Jan 9 '17 at 8:02
  • \$\begingroup\$ @manatwork, FPC and Delphi supports various types in writeln. And boolean is can be only 0 or 1 in pascal \$\endgroup\$ – user64239 Jan 9 '17 at 8:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.