# Detect MS Windows

### Challenge

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).

### Rules

• 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.

• Can the programs output by exit code? (normally allowed) Jan 8 '17 at 12:33
• Can you give a definite list of which operating systems this needs to work on? Jan 8 '17 at 14:46
• What should the result be under Windows RT?
Jan 8 '17 at 18:56
• 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. Jan 9 '17 at 11:12
• 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.
– user62131
Jan 10 '17 at 6:17

## FPC, 61 chars

begin{$ifdef win32}write('f');{$else}write('nf');{$endif}end;  • you can shave some bytes by using only one write begin write({$ifdef win32}1{$else}0{$endif});end.
– hdrz
Jan 9 '17 at 6:21
• Or to work on win64 as well: begin write({$ifdef windows}1{$else}0{$endif})end. – hdrz Jan 9 '17 at 6:42 • @hdrz, yes, you right, thanks ;) – user64239 Jan 9 '17 at 7:47 • @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. Jan 9 '17 at 8:02 • @manatwork, FPC and Delphi supports various types in writeln. And boolean is can be only 0 or 1 in pascal – user64239 Jan 9 '17 at 8:21 ## Lua, 21 Bytes os.execute"dir c:\\"  It will error if not on windows and list the C:\ directory if on windows. • Welcome to Programming Puzzles and Code Golf! Jan 13 '17 at 4:55 • Debian has a /bin/dir that seems almost identical to /bin/ls. If I do mkdir C:\ I can fool this script. Jun 10 at 10:31 # IBM/Lotus Notes Formula Language, 22 21 bytes @Like(@Platform;"W%")  Previous versions: @Left(@Platform;1)="W"  or @Begins(@Platform;"W")  Computed field formula on a Notes form. @Platform returns 1 of: AIX/64 Linux/64 Macintosh OS/400® UNIX Windows/32 Windows/64  So the formula returns 1 (@True) if the platform starts with "W" and 0 (@False) if not. # LibreOffice Calc / OpenOffice Calc, 21 bytes Code: =INFO("system")="WNT"  # Microsoft Excel, 23 bytes Code: =INFO("system")="pcdos"  Result: Returns TRUE if Windows; FALSE otherwise. • +1 for LibreOffice Oct 8 '18 at 16:48 # tcl, 51 puts [string match windows$tcl_platform(platform)]


I don't have a Windows machine online, but on http://rextester.com/live/OVTY1488 replace windows by unix to see it output 1 instead of 0.

2nd attempt:

# tcl, 40

puts [string match W* $tcl_platform(os)]  assuming Windows is the only system the name begins on a W. 3rd attempt: # tcl, 26 puts [info exists env(OS)]  assuming Windows is the only system the OS environment variable is defined. # Ruby, 38 bytes Stealing the code from here: exit (RUBY_PLATFORM=~/(?<!r)win/)!=nil  Return 0 on OK, to keep with shell conventions. We need the funny (?<!r) negative look-behind to avoid matching darwin, although if Microsoft device to make a vrwin Windows version for virtual reality the code will fail... On JRuby, though, this doesn't work so well, so instead: # Ruby including JRuby, 52 bytes exit (RbConfig::CONFIG['host_os']=~/(?<!r)win/)!=nil  I don't have raw Windows, just Cygwin, but if the host_os is windows then we need to distinguish nil and 0. # Ruby plus gem install os, 25 (+9?) This needs an extra gem, so we might have to add an extra 9 bytes for gem i os at the command line: require 'os' exit OS.windows?  This also avoids the darwin problem completely! • According to other answer in the question you linked to, your code will reach the conclusion that “darwin” is also “win”. If the question not requires otherwise, by default the answers are expected to be either full programs or functions (or whatever callable entities exist in your language), which should return or output the result explicitly or rely on the interpreter doing it implicitly. As it looks now, your code is a snippet, leaving the generated value in the memory. Jan 11 '17 at 7:33 • Oops! Filtering out darwin makes things lengthier. And let me add an exit... Jan 11 '17 at 8:20 # PHP, 18 bytes <?=!(PHP_EOL^'=');  ## Explanation PHP_EOL, as its name might suggest, returns the line separator on a given system. On Windows, this is CRLF, and on other platforms, this is LF. ^ is binary XOR. '=' XOR "\r" is '0', and PHP's string bitwise operations truncate to the length of the shortest string, so "\r\n" XOR '=' is also '0'. ! is boolean NOT. In PHP, "0" is considered falsy. So, when we're on Windows, PHP will negate this to true. When we're not on Windows, we get a truthy value ('7') which PHP negates to false. <?= is the short opening tag for echo. # Ruby 2, 17 14 bytes 17 byte solution: Gem.win_platform? This only works on the newer versions of ruby, as in the older versions you would have to require rubygems. ### 14 byte solution: system 'del a' This command outputs true if on windows, because there is a command called del in Windows, but outputs nil (falsey) on Linux and Mac because there is no such command as del in Unix. Oh, and if you are on windows it will delete a file called a in your current directory, that's an unintended side effect :P # Powershell 6, 10 bytes $isWindows


Powershell 6 intoduce 3 predefined variables: $isWindows, $isLinux and \$IsMacOs.

# Python 3, 29 bytes

import os;exit(os.name!='nt')


Probably should have tryed that first....

## Previous answer (41 bytes)

Two answers I found that are the same size

import os;exit(-hasattr(os,"P_DETACH")+1)


and

import sys;exit(-hasattr(sys,"winver")+1)


also -+1 is a neat way to negate the output, gonna keep that one noted

• -n+1 <-> 1-n? Oct 20 '18 at 19:52
• @JonathanFrech true, although I found even more savings by not being fancy :( Oct 20 '18 at 20:02
• -2 bytes by using os.name>'o' (linux and mac is posix, while windows is nt) May 12 at 15:30

# Elixir, 19 bytes

{:win32,_}=:os.type


Exit code 0 for Windows, 1 for others.

## Scala, 71 bytes

object W extends App{print(sys.env.get("OS").get.contains("Windows"))}


# Dartlang, 43 bytes

import'dart:io';main()=>Platform.isWindows;


First answer one here, so I hope this is okay :)

# D, 43 bytes

int f(){version(Windows)return 0;return 1;}


D ... is horrible at golfing. But it does have a version construct, so I thought I'd post an answer in D.

And ... there's really no point in putting a TIO link, since TIO is ran on only one type of OS.

# SQL 2017, 61 bytes

SELECT IIF(host_platform='Linux',0,1)FROM sys.dm_os_host_info


SQL 2017 is the first MS SQL version that can run on a platform other than Windows. The system view sys.dm_os_host_info returns either Linux or Windows, so (at least in this version) anything that isn't on Linux is on Windows.

• Nice solution!! Oct 18 '18 at 13:44

# Rust, 14 bytes

||!cfg!(unix);


The target_family attribute is windows on Windows and (most) others have unix.

# Julia 0.6, 8 bytes

!is_unix


Try it online!

# Julia 1.0, 11 bytes

!Sys.isunix


Try it online!

• This will give the same value for Windows as macOS. May 12 at 16:36
• i don't have a mac device to test it should give the same output as linux (macOS is unix-based) see the doc May 12 at 20:22
• nvm, you're right May 12 at 20:34
• you can save a byte btw by removing the ! and outputting reversed values (false if on windows) May 12 at 20:35

# Factor, 11 bytes

os windows?


Try it online!

# Nim, 20 bytes

echo defined windows


Try it online!

# 05AB1E, 26 19 bytes

'ª¬7£’ÿ :ï´.ƒª’.E2å


Try it online!

'ª¬7£’...’.E2å  # trimmed program
å  # is...
2   # literal...
å  # in...
.E    # result of running...
’...’      # "ÿ :os.type"...
# (implicit) with ÿ replaced by...
£           # first...
7            # literal...
£           # characters of...
'ª¬             # "inspection"...
.E    # as Elixir code...
å  # ?
# implicit output

=================================================

inspect :os.type  # full program
:os.type  # return tuple of OS family and OS name...
inspect           # as a string


:os.type return values:

Family Names
unix A result from running uname -s. No Unix kernels have 2 in their name, so if the machine is running Unix, the program will return 0.
win32 nt or windows

# 05AB1E (legacy), 21 bytes

’__£Ø__('ï´').ˆ³’.EÇÈ


Try it online!

’...’.EÇÈ  # trimmed program
È  # push 1 minus...
Ç   # codepoint of...
.E    # result of running...
’...’      # "__import__('os').sep"...
.E    # as python code...
È  # modulo 2
# implicit output

=================================================

__import__('os').sep  # full program
__import__(    )      # return...
'os'       # operating system...
.sep  # file path separator


# C (gcc), x64 only, 37 bytes

asm("m:_m:.int 50066");f(){m(2,1,0);}


Try it online!

Function called f(). Returns 1 for Windows, 0 for non-Windows.

You wanted a "creative solution"? Here you go. Unfortunately, it isn't as short or portable as the other C solution. (TODO: x86, ARM, and ARM64 polyglot /s)

Expanded:

// ASM
// We need both m and _m because macOS uses leading underscores for
// C symbols, while Windows and Linux do not.
m:
_m:
// We manually encode these in the golfed code to save space.
// eax = edx
xchg    eax, edx // 0x92
ret              // 0xC3
// C
int m(int, int, int);
int f()
{
// The first parameter can be anything, I use 2 for ease of explanation.
return m(2, 1, 0);
}


What does it do? It uses the fact that Windows and Linux (and Mac, BSD, etc) use different calling conventions on x64.

So, when GCC tries to call m(2, 1, 0), on Windows it will use the Microsoft x64 calling convention (rcx, rdx, r8, r9):

    mov     ecx, 2
mov     edx, 1
mov     r8d, 0
call    m

However, on Linux, Mac, BSD, etc, it will use the System V calling convention (rdi, rsi, rdx, rcx, r8, r9):

    mov     edi, 2
mov     esi, 1
mov     edx, 0
call    m

As I have bolded, edx is used on both platforms, but since they represent different parameters in the calling conventions, Windows and non-Windows will get different values.

With some inline assembly, we can get GCC to return the value of edx instead of the third parameter.

To test how it would function on Windows, simply uncomment the prototype at the top, which uses an attribute to force GCC to use the Microsoft ABI.

• I thought Windows was the one that prefixes C symbol names with underscore, or do I mis-remember? Jun 9 at 10:59

# Racket, 26 17 bytes

Shameless plug for the TCL answer I saw that used the OS environment variable.

(and(getenv"OS"))


Pretty straight forward. system-type with no argument returns a symbol indicating the system operating system type.

(eq?'windows(system-type))


Nim, 37 bytes

quit when defined(windows): 0 else: 1


Returns exit code 0 for Windows, 1 for all other operating systems. Uses conditional compilation with when.

# PowerShell, 17

gdr|? P* -like *y


Abusing the fact that there's no Registry PSProvider on non-Windows systems.

# Node.js, 23 bytes

_=>os.platform=="win32"


# GNU AWK, 45 bytes

BEGIN{print PROCINFO["platform"]~/^d|^m/?1:0}


Try it online!

Evaluates the PROCINFO["platform"] built-in variable, and returns 1 if it begins with the letters d or m; returns 0 otherwise. Why, you ask? According to the GNU AWK manual:

PROCINFO["platform"]

This element gives a string indicating the platform for which gawk was compiled.
The value will be one of the following:

"djgpp"
"mingw"

Microsoft Windows, using either DJGPP or MinGW, respectively.


# Lua (LuaJIT), 17 bytes

print(jit.os>"V")


Try it online!

# Python 3, 78 bytes

Raises a KeyError exception if it can't determine if running on Windows. On not-Windows it can return either None or 0 (both are falsy), on Windows it returns 1.

def f():
try:open(':','x')
except Exception as e:return{17:0,22:1}[e.errno]


: is a forbidden character on Windows (also on DOS, etc.)

• The colon is also an invalid character in file names on macOS, so this seems like it would produce a lot of false-positives, if the goal is to detect Windows. In fact, it specifically violates the rules of the challenge, which was to fail to detect OS X. Have you actually verified that this does not result in an error on macOS? Jun 10 at 20:54
• @CodyGray I remember having tested this on my Hackintosh, but I'll check again just in case. Jun 10 at 20:58
• It does actually work on Mac OS Sierra (10.12). Jun 10 at 21:02