September 19, 2018
On Wednesday, 19 September 2018 at 06:26:21 UTC, Vladimir Panteleev wrote:
> Someone mentioned in this thread that .NET runtime does do the long-path workaround automatically.

AFAIK, CoreFX does, but .net doesn't. .net did its own path normalization and length check, which can be turned off since 4.6.2.
September 19, 2018
On Wednesday, 19 September 2018 at 09:58:30 UTC, Kagamin wrote:
> On Wednesday, 19 September 2018 at 06:26:21 UTC, Vladimir Panteleev wrote:
>> Someone mentioned in this thread that .NET runtime does do the long-path workaround automatically.
>
> AFAIK, CoreFX does, but .net doesn't. .net did its own path normalization and length check, which can be turned off since 4.6.2.

Thanks. I had a quick look. It looks pretty involved. Here are some of the relevant parts:

https://github.com/dotnet/corefx/blob/0566028e42a8f2fa86b8e0dd856d1f13d0fdce05/src/Common/src/CoreLib/System/IO/PathHelper.Windows.cs#L16-L43
https://github.com/dotnet/corefx/blob/0566028e42a8f2fa86b8e0dd856d1f13d0fdce05/src/Common/src/CoreLib/System/IO/PathHelper.Windows.cs#L68-L95
https://github.com/dotnet/corefx/blob/0566028e42a8f2fa86b8e0dd856d1f13d0fdce05/src/Common/src/CoreLib/System/IO/Path.Windows.cs#L37-L63
https://github.com/dotnet/corefx/blob/0566028e42a8f2fa86b8e0dd856d1f13d0fdce05/src/Common/src/CoreLib/System/IO/PathInternal.Windows.cs#L82-L99
https://github.com/dotnet/corefx/blob/0566028e42a8f2fa86b8e0dd856d1f13d0fdce05/src/Common/src/CoreLib/System/IO/PathInternal.Windows.cs#L118-L141

And for example directory deletion:

https://github.com/dotnet/corefx/blob/0566028e42a8f2fa86b8e0dd856d1f13d0fdce05/src/System.IO.FileSystem/src/System/IO/Directory.cs#L296-L300
https://github.com/dotnet/corefx/blob/0566028e42a8f2fa86b8e0dd856d1f13d0fdce05/src/Common/src/Interop/Windows/kernel32/Interop.RemoveDirectory.cs#L19-L23

Some things stood out to me:

- GetFullPathName is documented as also having the MAX_PATH limit, but the framework seems to use it for normalization BEFORE prepending the prefix.

  https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-getfullpathnamea

- GetFullPathName has a big warning on it about how you shouldn't use it in multithreaded programs.

- The code seems to compare the length against 260 characters, but in my tests, the limit is actually about 12 characters shorter. The same file defines MaxShortDirectoryPath = 248, but that constant isn't used anywhere in the code.

Maybe we shouldn't use this as a reference after all...

September 19, 2018
On Wednesday, 19 September 2018 at 09:27:29 UTC, Vladimir Panteleev wrote:
> This might be a change which we won't be able to back out of if it turns out to be a bad idea, because then we break other classes of programs that depend on this change. See https://forum.dlang.org/post/eepblrtjmqzbtopylfib@forum.dlang.org for an example.

Case in point:

https://msdn.microsoft.com/ru-ru/office/mt762842%28v=vs.90%29?f=255&MSPPError=-2147217396

September 19, 2018
On Wednesday, 19 September 2018 at 05:49:41 UTC, Nick Sabalausky (Abscissa) wrote:
> 2. Detect and reject any non-\\?\ path longer than MAX_PATH-12 bytes[5].

This is not a good criteria: relative paths whose pointing to objects whose absolute path exceeds MAX_PATH will fail, too. So, it looks like Phobos would need to expand relative paths unconditionally.

September 19, 2018
On Wednesday, 19 September 2018 at 11:04:13 UTC, Vladimir Panteleev wrote:
> On Wednesday, 19 September 2018 at 05:49:41 UTC, Nick Sabalausky (Abscissa) wrote:
>> 2. Detect and reject any non-\\?\ path longer than MAX_PATH-12 bytes[5].
>
> This is not a good criteria: relative paths whose pointing to objects whose absolute path exceeds MAX_PATH will fail, too. So, it looks like Phobos would need to expand relative paths unconditionally.

Here is my test program:
https://gist.github.com/CyberShadow/049cf06f4ec31b205dde4b0e3c12a986

September 19, 2018
On Wednesday, 19 September 2018 at 10:29:11 UTC, Vladimir Panteleev wrote:
> - GetFullPathName is documented as also having the MAX_PATH limit, but the framework seems to use it for normalization BEFORE prepending the prefix.
>
>   https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-getfullpathnamea

That part is erroneous :)
Recent additions to msdn are too often incompetent, e.g. long path registry switch in windows 10 doesn't enable the feature, it's only the first of two gates, manifest is not optional. Don't ask me who does it. They can't even get backslashes right.
Passing unparsed path to GetFullPathName makes no sense because such unparsed path must be already full normalized path, and it doesn't have MAX_PATH limit, probably because it doesn't talk to file system.

> - GetFullPathName has a big warning on it about how you shouldn't use it in multithreaded programs.

I wonder about that too, shouldn't the system do the same to resolve the absolute path? Theoretically it can keep an open handle to the current directory and get its path from that.
September 19, 2018
On Wednesday, 19 September 2018 at 09:58:00 UTC, Vladimir Panteleev wrote:
> On my Windows VM, I get:
>
> C:\(long path here): The filename or extension is too long. (error 206)
>
> This seems like a completely reasonable error message to me, so I think we're good there already.

It can be a long file name. Each individual component in the path still should not exceed MAX_PATH even when you use unparsed path.
September 19, 2018
On Wednesday, 19 September 2018 at 08:13:31 UTC, Ecstatic Coder wrote:
> On Wednesday, 19 September 2018 at 05:32:47 UTC, Vladimir Panteleev wrote:
>> On Wednesday, 19 September 2018 at 05:24:24 UTC, Ecstatic Coder wrote:
>>> None would ever be, considering you obviously have decided to ignore such a simple solution to the 260 character limit...
>>
>> Add "ad hominem" to your pile of fallacies, I guess.
>
> Now I will, thanks :)
>
> Once again, this forum proves to be very effective at removing any motivation from D users to get involved and contribute to the D language.

Sorry, I didn't intend to make you feel unwelcome.

But, you did say I was ignoring something, after I've addressed it twice in the same thread. That wasn't nice of you either.

In any case, the solution in question won't work:
https://forum.dlang.org/post/riuqfngyzfumehsmontk@forum.dlang.org

September 19, 2018
On Wednesday, 19 September 2018 at 08:54:42 UTC, Vladimir Panteleev wrote:
> BTW, something follows from the above:
>
> write(`C:\` ~ (short path) ~  `con`) will fail
>
> but:
>
> write(`C:\` ~ (long path) ~ `con`) will succeed.
>
> This is just one issue I've noticed... there's probably more lurking.

Also, according to the internet:

write(chainPath(shortDirectory, "A "), "Win32 API strips trailing space");
readText(chainPath(shortDirectory, "A")); // Win32 API strips trailing space

But:
write(chainPath(longDirectory, "A "), "Win32 API strips trailing space");
readText(chainPath(longDirectory, "A")); // File not found

write(chainPath(shortDirectory, "A."));  // fails
write(chainPath(longDirectory, "A."));  // succeeds

> This is why I think the whole idea is bankrupt.

This is why we should use the exact same behavior in all cases. Always use `\\?\` or never use it.

Since Windows path handling is weird by default, I'd prefer always using `\\?\`. It's overhead, but not a huge amount of additional overhead compared to filesystem manipulation.
September 19, 2018
On 09/19/2018 02:33 AM, Jonathan Marler wrote:
> 
> What drives me mad is when you have library writers who try to "protect" you from the underlying system by translating everything you do into what they "think" you're trying to do.

What drives me mad is when allegedly cross-platform tools deliberately propagate non-cross-platform quirks that could easily be abstracted away and pretend that's somehow "helping" me instead of making a complete wreck of the whole point of cross-platform. Bonus points if they're doing it mainly to help with my C++-standard premature optimizations.

If I actually want to deal with platform-specific quirks, then I'll use the platform's API directly. (And then I'll beat myself with a brick, just for fun.)