Skip to content
⌘ NSIS Forum Archive

MAX_CHAR in UNICODE

11 posts

bnicer#

MAX_CHAR in UNICODE

I read here that when calling kernel32::CopyFile, you can extend the UNICODE path length beyond MAX_PATH characters to 32,767 wide characters by prepending '\\?\' to the path.

Would there be any reason not to prepend '\\?\' to a path, I thought, and I tested kernel32::CopyFile with a ridiculously long install path.

It didn't work, because the MAX_PATH of 256 characters is defined in NSIS. I wonder, shouldn't the UNICODE NSIS version extend the install path length limit?
Anders#
260/MAX_PATH is a common limit in the Windows API, NSIS strings are limited to 1024 TCHAR's by default.

\\?\ is not used when you build Unicode installers because it is only supported by the low-level stuff and not by SHFileOperation, IShellLink etc. I believe the Unicode fork uses \\?\ in some calls...
bnicer#
Thanks, Anders, for your speedy (weekend!) reply.

I fooled around with the path length some more. I thought maybe you could prepend "\\?\" when you use SetOutPath.

SetOutPath "\\?\$INSTDIR", ... ?

Before the installation the path string shown by the setup is:

\\?\'ridiculously long path'.

However the actual path limit, as previously, is 256 characters.

I'm giving up. I read some of the related forum topics also. I don't think anyone has ever made an installer that extends the MAX_PATH limit for the destination folder, which kind of speaks for itself.

I'm glad I could get it off of my chest. The UNICODE installer is a marvellous invention, owing to you, and I will continue to make use of it.

See you all on the next forum. Keep it up.👍
Anders#
SetOutPath and some other instructions try to validate the path and will not accept \\?\. Why? I don't know, maybe kichik knows.

For things like FileOpen I don't see a point to validating the path since the internal call to CreateFile will fail on invalid paths. SetOutPath calls SetCurrentDirectory and that is MAX_PATH limited IIRC...
bnicer#
I suppose, if you were perverse, you could trick the system by first installing to a path and then moving everything to a ridiculously long path. As you say, some file operations work. Calling kernel32::MoveFile should accept the prepended \\?\.

If somebody does build an installer like that, they can post the instructions on the new forum.😉
bnicer#
I ran a few more UNICODE tests and will summarize the findings:

A) 'kernel32::CopyFile(t "C:\path\file.ext", t "C:\path2\file.ext", i 0)i.r0'
B) 'kernel32::CopyFile(t "C:\path\file.ext", t "\\?\C:\path-that-exceeds-256-characters\file.ext", i 0)i.r0'
C) 'kernel32::CopyFileW(t "C:\path\file.ext", t "C:\path2\file.ext", i 0)i.r0'
D) 'kernel32::CopyFileW(t "C:\path\file.ext", t "\\?\C:\path-that-exceeds-256-characters\file.ext", i 0)i.r0'

Out of A, B, C, D only A works. B returns an error, C creates 'C:\path2' but does not copy 'file.ext', and D does nothing.

E) 'kernel32::GetFileAttributes(t "C:\path-that-exceeds-256-characters\file.ext")i .R2'

E works too. In short, '\\?\' doesn't make much difference.
Anders#
This works fine in 2.46:
Section

!define longname "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678 9abcde" ; Path elements are length limited to 255 even with \\? (GetVolumeInformation lpMaximumComponentLength)

System::Call 'kernel32::CreateDirectoryW(w "\\?\$temp\${longname}", i0)i.r0?e'
Pop $1
DetailPrint $0,gle=$1
System::Call 'kernel32::CopyFileW(w "$exepath", w "\\?\$temp\${longname}\${longname}", i 0)i.r0'?e'
Pop $1
DetailPrint $0,gle=$1

System::Call 'kernel32:😁eleteFileW(w "\\?\$temp\${longname}\${longname}")i.r0?e'
Pop $1
DetailPrint $0,gle=$1
System::Call 'kernel32::RemoveDirectoryW(w "\\?\$temp\${longname}", i0)i.r0?e'
Pop $1
DetailPrint $0,gle=$1

SectionEnd
bnicer#
To confirm your example, Anders, creating a long path by calling CreateDirectoryW is possible. I didn't know you had to create the folder first. I guess that's always better. Thanks.👍
Anders#
Just be careful not to install programs in a path that long because it is not going to work and you will not be able to create a shortcut or anything.
bnicer#edited
I noticed Windows Explorer won't go anywhere near a path element that has 255 characters. (You can't delete the path.) I used several 'shorter' sub-folders -- easier to delete. But I take your point. This isn't recommended.
grishas#
I got the same message recently and installed "Long Path Tool" program which solved the problem.