How to work with long paths on Windows?

Preetpal preetpal.sohal at gmail.com
Wed Sep 14 01:53:10 UTC 2022


On Tuesday, 13 September 2022 at 19:54:15 UTC, Preetpal wrote:
> In Windows 10, Version 1607 (and later), you can [enable long 
> paths](https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=registry) which bypasses the MAX_PATH limitation for local paths (e.g., C:\Users\you\log.txt). Currently if you iterate over a directory with a file exceeding the MAX_PATH limitation for local paths, an exception is thrown. There is no limitation on Linux (tested using GDC on the Windows Subsystem for Linux) and this issue occurs when using either the LDC2 or DMD compilers on Windows. It's very common to have these sorts of paths if you use [npm](https://www.npmjs.com/).
>
> Example code:
>
>
> ```
> import std.file;
> import std.stdio;
>
> /// Command line tool to find files in directories
> int main(string[] args) {
>     if (args.length < 2) {
>         writefln("Usage: %s wildcard", args[0]);
>         return 1;
>     }
>     string wildcard = args[1];
>
>     auto results = dirEntries(".", wildcard, SpanMode.depth);
>     foreach(string result; results) {
>         writeln(result);
>     }
>     return 0;
> }
> ```

This issue technically isn't an issue as things are working as 
expected IMO. All you have to do is create an manifest file for 
the executable (this changes the behavior of how the file 
management functions in the Windows API (which are being used in 
std.file) deal with the MAX_PATH restriction). This manifest file 
can either be named exactly the same name as the executable and 
placed in the same directory (in this case if you named the 
program executable "find_file.exe" you would name the manifest 
file "find_file.exe.manifest") or it can be embedded in the 
executable (did not test this myself). The manifest file is just 
an XML file:

```
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<assembly manifestVersion="1.0" 
xmlns="urn:schemas-microsoft-com:asm.v1" 
xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
     <asmv3:application>
     <asmv3:windowsSettings 
xmlns:ws2="http://schemas.microsoft.com/SMI/2016/WindowsSettings">
       <ws2:longPathAware>true</ws2:longPathAware>
     </asmv3:windowsSettings>
     <asmv3:windowsSettings 
xmlns:ws3="http://schemas.microsoft.com/SMI/2019/WindowsSettings">
       <ws3:activeCodePage>UTF-8</ws3:activeCodePage>
     </asmv3:windowsSettings>
   </asmv3:application>
   <assemblyIdentity type="win32" 
name="YourOrganization.file_name" 
version="1.0.0.7"></assemblyIdentity>
</assembly>
```

> Example problem:
>
>   If you run it in a directory with paths containing exceeding 
> MAX_PATH, it fails.
>
>
> ```
> std.file.FileException at std\file.d(4648): 
> .\my_webproject\my_webproject\my_webproject\node_modules\bootswatch\docs\3\node_modules\bower\node_modules\update-notifier\node_modules\request\node_modules\har-validator\node_modules\chalk\node_modules\has-ansi\node_modules\ansi-regex: The system cannot find the path specified.
> ```
>
> How do you work around this issue on Windows? The issue has 
> already been 
> [reported](https://issues.dlang.org/show_bug.cgi?id=8967).

If you use the manifest file for your executable, you will be 
able to deal with long paths on Windows. By using the manifest 
file, my program (see example code) no longer threw an exception 
when dealing with long paths. I think that the [open 
issue](https://issues.dlang.org/show_bug.cgi?id=8967) should be 
closed as you have to opt-in to make your program long path aware.


More information about the Digitalmars-d-learn mailing list