Archive: install folder name length limitation


install folder name length limitation
What is the length limitation for the folder you wish to install to?

When installing into a folder with a name of about 200 characters, a write error is issued and nothing is copied.


Windows
#define MAX_PATH 260


Then why does the installer show the error box as in the attached image?

The folder name is not that long. Is this a bug?


This limit includes both path and file name.
Use CreateDirectory or SetOutPath to dest. folder first to ensure that folder exists. GetLastError can give error code http://forums.winamp.com/showthread....t=GetLastError


I think the MAX_PATH limit is only on relative paths, and any individual component of a path name. At least that's my reading of http://msdn.microsoft.com/en-us/libr...47(VS.85).aspx.

That page says the limit of an absolute path is ~32,000 characters.

I ran into a snag where I entered a long filename as the installation directory. The directory name is valid according to the above page, but I also have C code that can create it, remove it, etc. I used:

C:\Program Files\foo\XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXX\foo

The snag is that GetInstDirError tells me the directory is valid but SetOutPath fails to create the directory and sets the error flag.

If I don't trap the error, I see a dialog box for the first File statement after SetOutPath that says "Error opening file for writing."

What are the chances of adding support for file/directory names > MAX_PATH? In the meantime, I have a feeling it'd be more consistent for GetInstDirError to report an invalid directory but I've only got a bit of experience with this function so I'm not sure yet.

Thanks.

-DB


Only some of the windows api supports long paths, but you need to prefix the path with \\?\ and only the unicode api's supports this, so you will never see support for this in the ansi version of nsis


I didn't realize there was an ansi version of nsis. Does this mean there's also a unicode version?

What do you think about how GetInstDirErr handles this directory? Shouldn't it report it as invalid?

-DB


the "normal" version you get from nsis.sf.net is ansi, unicode fork is @ http://www.scratchpaper.com/


Thanks for the link. Still curious about the directory verification / GetInstDirErr.

I just peeked into the NSIS source for the first time, but changing the EW_CREATEDIR code in exehead/exec.c to build a unicode string, prefix it with \\?\ and call CreateDirectoryW doesn't seem so bad. It wouldn't get me all the way, but it seems like a step in the right direction.

I'd probably need to call GetProcAddress to make sure the function is available...got to look around the code to see the nsis way of dealing with that.

I took a quick look at is_valid_instpath. I'll have to dig deeper to see what it would take to decide the path is invalid. Looks like an explicit length check may be it. I haven't found the definition of NSIS_MAX_STRLEN but it looks like is_valid_instpath only looks at that many characters of whatever it's passed.

Any idea what the chances of patches for either place getting accepted are?

-DB


k, here is the deal, only the low level file api's support those long paths, not the shell stuff like ShellExecute(ExecShell) and probably CreateShortcut. So if you change nsis so it uses \\?\, some stuff would work and other stuff would not. NSIS_MAX_STRLEN is 1024 in default build


I realize that not all the windows APIs work with long filenames. Just having SetOutPath and File work could be enough for some folks (like me) though. Having some support seems better than none.

Since Windows Explorer doesn't handle long filenames in all cases, maybe I'm just barking up the wrong tree. Or maybe there are places where calling GetShortPathName to get things to work is the way to go. That worked for me to get CreateProcessW to execute processes that have long names. Maybe it would work for ShellExecute as well.

A NSIS_MAX_STRLEN of 1024 means I need to dig in further. The path I gave isn't that long so it wasn't getting truncated but somehow it's still considered valid which doesn't seem right.

-DB


you can use FileMon/Process Monitor to see if the path nsis tries to access is invalid or not


Interesting. For a path of:

C:\Program Files\foo\XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXX\foo

the only paths that show up in ProcMon are C:\, C:\Program Files and c:\Program Files\foo.

From looking at the code, it seems like the FindFirstFile in file_exists returns INVALID_HANDLE_VALUE if the path is too long, so file_exists returns NULL. That makes the code in is_valid_instpath just skip over that part of the path.

I just did a quick test and FindFirstFile fails with GetLastError() set to ERROR_FILENAME_EXCED_RANGE (206) when given a filename that's too long. Not sure what the most pleasing way to use that info is...the simplest way is probably to check

if (!fd && (GetLastError() == ERROR_FILENAME_EXCED_RANGE))
return 0;

in is_valid_instpath but that's a bit unclean. Keeping the GetLastError() code in file_exists probably means changing the signature of that function.

I am suffering this problem too. Are you saying that the Unicode build will allow long filenames?

I just need File and SetOutPath to support long filenames...

Cheers.