Old 13th December 2013, 23:19   #1
bnicer
Senior Member
 
Join Date: Feb 2005
Location: London
Posts: 218
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?
bnicer is offline   Reply With Quote
Old 14th December 2013, 02:09   #2
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,358
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...

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 14th December 2013, 13:52   #3
bnicer
Senior Member
 
Join Date: Feb 2005
Location: London
Posts: 218
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.
bnicer is offline   Reply With Quote
Old 14th December 2013, 14:19   #4
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,358
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...

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 14th December 2013, 15:54   #5
bnicer
Senior Member
 
Join Date: Feb 2005
Location: London
Posts: 218
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 is offline   Reply With Quote
Old 16th December 2013, 05:28   #6
bnicer
Senior Member
 
Join Date: Feb 2005
Location: London
Posts: 218
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.
bnicer is offline   Reply With Quote
Old 16th December 2013, 15:07   #7
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,358
This works fine in 2.46:
Quote:
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::DeleteFileW(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

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 16th December 2013, 18:56   #8
bnicer
Senior Member
 
Join Date: Feb 2005
Location: London
Posts: 218
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.
bnicer is offline   Reply With Quote
Old 16th December 2013, 22:02   #9
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,358
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.

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 17th December 2013, 00:09   #10
bnicer
Senior Member
 
Join Date: Feb 2005
Location: London
Posts: 218
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.

Last edited by bnicer; 17th December 2013 at 02:21.
bnicer is offline   Reply With Quote
Old 27th March 2015, 18:56   #11
grishas
Junior Member
 
Join Date: Mar 2015
Posts: 1
I got the same message recently and installed "Long Path Tool" program which solved the problem.
grishas is offline   Reply With Quote
Reply
Go Back   Winamp & Shoutcast Forums > Developer Center > NSIS Discussion

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump