{"id":2595,"date":"2018-02-28T16:40:09","date_gmt":"2018-03-01T00:40:09","guid":{"rendered":"http:\/\/blogs.msdn.microsoft.com\/commandline\/?p=2595"},"modified":"2019-02-25T20:10:18","modified_gmt":"2019-02-26T04:10:18","slug":"per-directory-case-sensitivity-and-wsl","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/commandline\/per-directory-case-sensitivity-and-wsl\/","title":{"rendered":"Per-directory case sensitivity and WSL"},"content":{"rendered":"<p>If you have used the Windows Subsystem for Linux, you\u2019re probably aware that it allows you to treat your Windows file systems (mounted under \/mnt\/c, \/mnt\/d, etc.) as case sensitive. This means, among other things, that you can create files whose names differ only by case (e.g. foo.txt and FOO.TXT).<\/p>\n<p>However, using those files in Windows was not really possible. Since Windows applications treat the file system as case insensitive, they cannot distinguish between files whose names only differ in case. While File Explorer would show both files, only one would be opened regardless of which one you clicked.<\/p>\n<p>Starting with Windows insider build 17093, we\u2019ve introduced a new way to handle case sensitive files in Windows: per-directory case sensitivity. We use this ability in the Windows Subsystem for Linux to give you better interoperability when using case sensitive files, and you can also use it yourself with regular Windows applications. As of insider build 17110, this behavior is the default.<\/p>\n<h2>Case sensitivity in Windows<\/h2>\n<p>The Windows NT family of operating systems (including Windows 10) has always had the ability to perform case sensitive file system operations. Applications can pass the <code>FILE_FLAG_POSIX_SEMANTICS<\/code> flag to the <code>CreateFile<\/code> API to indicate that they want the path to be treated as case sensitive. However, for compatibility reasons, there is a global registry key that overrides this behavior; when this key is set, all file operations are case insensitive, even when the <code>FILE_FLAG_POSIX_SEMANTICS<\/code> flag is specified. Since Windows XP, this has been the default.<\/p>\n<p>The Windows Subsystem for Linux uses another mechanism, which itself bypasses that registry key, allowing us to perform case sensitive file system operations. This is what allows Linux applications running in WSL to use file names that differ only by case, just like they can on real Linux, even with that global registry key set.<\/p>\n<p>Unfortunately, this leaves you with files that can\u2019t be accessed by Windows applications. While you could change the global registry key, that still would only work for those applications that use <code>FILE_FLAG_POSIX_SEMANTICS<\/code>, and this would change the behavior for all files on all drives, which may not be intended and may break some applications.<\/p>\n<h2>Per-directory case sensitivity<\/h2>\n<p>To solve this problem, we added a new case sensitive flag that can be applied to directories. For directories that have this flag set, all operations on files in that directory are case sensitive, regardless of whether <code>FILE_FLAG_POSIX_SEMANTICS<\/code> was specified. This means that if you have two files that differ only by case in a directory marked as case sensitive, all applications will be able to access them.<\/p>\n<p>In Windows insider build 17107, we have added the ability to view and modify this flag to the fsutil.exe command. To check if a directory is case sensitive, run the following command: <code>fsutil.exe file queryCaseSensitiveInfo &lt;path&gt;<\/code><\/p>\n<p>To mark a directory as case sensitive, or case insensitive respectively: <code>fsutil.exe file setCaseSensitiveInfo &lt;path&gt; enable<\/code> <code>fsutil.exe file setCaseSensitiveInfo &lt;path&gt; disable<\/code><\/p>\n<p>Note that the per-directory case sensitivity flag is not inherited; directories created in a case sensitive directory are not automatically case sensitive themselves. You must explicitly mark each directory as case sensitive. Changing the flag requires \u201cwrite attributes\u201d permission to the directory.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/33\/2019\/02\/casesensitive.gif\" alt=\"fsutil demo\" class=\"alignnone wp-image-2615 size-full\" width=\"857\" height=\"450\" \/><\/p>\n<h2>Per-directory case sensitivity in WSL<\/h2>\n<p>The Windows Subsystem for Linux makes use of the per-directory case sensitivity flag to improve its interoperability with the Windows file systems mounted under \/mnt\/c, \/mnt\/d, etc. We have several new case sensitivity modes, which can be controlled with the \u201ccase\u201d mount option for DrvFs. This option controls which directories are treated as case sensitive, and whether new directories created with WSL will have the flag set. There are three values: dir, off, and force. Their behavior is listed in the table below.<\/p>\n<table style=\"border: solid 1px #bbbbbb;border-collapse: separate\">\n<tbody>\n<tr>\n<th style=\"border: solid 1px white;padding: 0.5em;background-color: #eeeeee\" width=\"222\">\n      <\/th>\n<th style=\"border: solid 1px white;padding: 0.5em;background-color: #eeeeee\" width=\"132\">\n        case=dir\n      <\/th>\n<th style=\"border: solid 1px white;padding: 0.5em;background-color: #eeeeee\" width=\"132\">\n        case=off\n      <\/th>\n<th style=\"border: solid 1px white;padding: 0.5em;background-color: #eeeeee\" width=\"138\">\n        case=force\n      <\/th>\n<\/tr>\n<tr>\n<th style=\"border: solid 1px white;padding: 0.5em\" width=\"222\">\n        Directory with flag enabled\n      <\/th>\n<td style=\"border: solid 1px white;padding: 0.5em\">\n        Case sensitive\n      <\/td>\n<td style=\"border: solid 1px white;padding: 0.5em\">\n        Case sensitive\n      <\/td>\n<td style=\"border: solid 1px white;padding: 0.5em\">\n        Case sensitive\n      <\/td>\n<\/tr>\n<tr>\n<th style=\"border: solid 1px white;padding: 0.5em;background-color: #eeeeee\" width=\"222\">\n        Directory with flag disabled\n      <\/th>\n<td style=\"border: solid 1px white;padding: 0.5em;background-color: #eeeeee\">\n        Case insensitive\n      <\/td>\n<td style=\"border: solid 1px white;padding: 0.5em;background-color: #eeeeee\">\n        Case insensitive\n      <\/td>\n<td style=\"border: solid 1px white;padding: 0.5em;background-color: #eeeeee\">\n        Case sensitive\n      <\/td>\n<\/tr>\n<tr>\n<th style=\"border: solid 1px white;padding: 0.5em\" width=\"222\">\n        Flag on directories created in WSL\n      <\/th>\n<td style=\"border: solid 1px white;padding: 0.5em\">\n        Enabled\n      <\/td>\n<td style=\"border: solid 1px white;padding: 0.5em\">\n        Disabled\n      <\/td>\n<td style=\"border: solid 1px white;padding: 0.5em\">\n        Enabled\n      <\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Essentially, directories with the case sensitivity flag set are always treated as case sensitive. Directories without the flag set are treated as case insensitive, unless you\u2019re using case=force. New directories created by DrvFs get the flag set unless you\u2019re using case=off.<\/p>\n<p>Using case=force is equivalent to WSL\u2019s old behavior (except for the fact that the flag gets set on new directories).<\/p>\n<p>To mount DrvFs with a specific case sensitivity setting, <a href=\"https:\/\/devblogs.microsoft.com\/commandline\/automatically-configuring-wsl\/\">use \/etc\/wsl.conf<\/a> to set the default mount options for all drives, or \/etc\/fstab to specify options for a specific drive.<\/p>\n<p>Not all file systems support per-directory case sensitivity; currently, it only works on local NTFS drives. To make sure your drive was successfully mounted with the desired case sensitivity option, use the <code>mount<\/code> command and see if the option was applied.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/33\/2019\/02\/mount-case-dir.png\" alt=\"mount command output\" class=\"alignnone wp-image-2605 size-full\" width=\"607\" height=\"262\" \/><\/p>\n<p>Using per-directory case sensitivity has a number of advantages. Not only can you create files that differ by case and have them accessible in Windows, you can also create case-differing files in Windows in those directories. And, since all other directories on your system are not marked case sensitive, you don\u2019t need to care about case sensitivity from within WSL when accessing common Windows files. This means for example that you can launch applications using interop without matching the exact case of the\u00a0 executable file (e.g. running \u201cNOTEPAD.EXE\u201d now works in WSL the same \u00a0as it does in Windows). NT symlinks whose targets don\u2019t use the exact case of the actual file now also work \u00a0in WSL.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/33\/2019\/02\/casesensitive_notepad.gif\" alt=\"Notepad demo\" class=\"alignnone wp-image-2625 size-full\" width=\"855\" height=\"510\" \/><\/p>\n<p>If you need to create a case insensitive directory while using \u201ccase=dir\u201d or \u201ccase=force\u201d, or want to create a case sensitive directory while using \u201ccase=off\u201d, you can simply use fsutil.exe after creating the directory. You can, of course, invoke fsutil.exe from WSL using interop.<\/p>\n<p><strong>Note:<\/strong> if you change the case sensitive flag on an existing directory while WSL is running, please make sure WSL has no references to that directory. That means no WSL processes may have that directory, or any of its descendants, open. That includes using that directory, or its descendants, as the current working directory. If you don\u2019t, WSL continues to act like the directory has its old case sensitivity setting, which may lead to unexpected results.<\/p>\n<p>Starting with build 17110, DrvFs\u2019s default behavior is now equivalent to using \u201ccase=dir\u201d. This means that any directories you created with WSL before build 17093 will not be treated as case sensitive anymore. To fix this, use fsutil.exe to mark your existing directories as case sensitive.<\/p>\n<p>If you require the old behavior, you can still mount DrvFs using \u201ccase=force\u201d, though we strongly recommend using per-directory case sensitivity going forward. As of build 17110, using \u201ccase=force\u201d requires setting a registry key, which you can do by running the following command from an elevated command prompt:<\/p>\n<p><code>reg.exe add HKLM\\SYSTEM\\CurrentControlSet\\Services\\lxss \/v DrvFsAllowForceCaseSensitivity \/t REG_DWORD \/d 1<\/code><\/p>\n<p>As you can see, per-directory case sensitivity improves interoperability between files created with WSL and Windows significantly. Let us know what you think in the comments!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you have used the Windows Subsystem for Linux, you\u2019re probably aware that it allows you to treat your Windows file systems (mounted under \/mnt\/c, \/mnt\/d, etc.) as case sensitive. This means, among other things, that you can create files whose names differ only by case (e.g. foo.txt and FOO.TXT). However, using those files in [&hellip;]<\/p>\n","protected":false},"author":1030,"featured_media":4352,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[9],"tags":[35,41,72],"class_list":["post-2595","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-bash-on-ubuntu-on-windows","tag-drvfs","tag-interop","tag-wsl"],"acf":[],"blog_post_summary":"<p>If you have used the Windows Subsystem for Linux, you\u2019re probably aware that it allows you to treat your Windows file systems (mounted under \/mnt\/c, \/mnt\/d, etc.) as case sensitive. This means, among other things, that you can create files whose names differ only by case (e.g. foo.txt and FOO.TXT). However, using those files in [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/commandline\/wp-json\/wp\/v2\/posts\/2595","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/commandline\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/commandline\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/commandline\/wp-json\/wp\/v2\/users\/1030"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/commandline\/wp-json\/wp\/v2\/comments?post=2595"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/commandline\/wp-json\/wp\/v2\/posts\/2595\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/commandline\/wp-json\/wp\/v2\/media\/4352"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/commandline\/wp-json\/wp\/v2\/media?parent=2595"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/commandline\/wp-json\/wp\/v2\/categories?post=2595"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/commandline\/wp-json\/wp\/v2\/tags?post=2595"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}