Archive: Quoted path to file not found. Should it be?


Quoted path to file not found. Should it be?
I've run into an annoying situation. My installer reads a registry key to get the path to some executable. In this case it's the default value of HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\wmplayer.exe.

It then checks to see if the path I read actually exists. In general this works fine, but on some machines (I've seen in on 64-bit Win7, a European version I believe) the path that's there is surrounded by quotes. As in

"%ProgramFiles(x86)%\Windows Media Player"

To be brutally explicit, the quotes above are actually in the registry.

Normally, I see the default value of this key with no quotes.

My installer isn't working because it takes the value figured out by ReadRegStr and passes it to IfFileExists. IfFileExists ends up calling file_exists in Source/exehead/util.c which calls FindFirstFile which thinks the file doesn't exist.

I can add logic to my installer to look for these quotes and remove them, but I wonder how many other folks will run into this, and with who knows what other registry keys. Another approach is to patch file_exists to look for surrounding quotes and to remove them before calling FindFirstFile, or perhaps changing the IfFileExists implementation instead so all the other callers of file_exists don't change.

I can see the slippery slope here...Does this mean FileOpen needs to handle surrounding quotes as well? And I'm sure there are others. It's annoying. And it could be that one of my customers or some non-MS program edited the registry so it's not a widespread thing. But, I figured I'd throw this out there to see what people think. Maybe you think changing file_exists is reasonable? Or maybe you have another solution.

Thanks for your help.


I think if you suspect a path could have quotes you should put the code in there. If the code is in IfFileExists and it's not used in most cases then that is (albeit small) extra overhead.

In script, it's just 6 lines:


StrCpy $R0 $Path 1
StrCmp $R0 `"` 0 +2
StrCpy $Path $Path `` 1
StrCpy $R0 $Path `` -1
StrCmp $R0 `"` 0 +2
StrCpy $Path $Path -1

Stu

I bet you're right that changing NSIS itself to handle this isn't right. Here's what I came up with to remove the quotes -- only when a string both starts and ends with a quote do I remove them. Thanks for a push in the right direction.

Function RemoveSurroundingQuotes
Exch $0 ; The string in question
Push $2 ; the first character
Push $3 ; the last character

StrCpy $2 $0 1
StrCpy $3 $0 "" -1

StrCmp $2 '"' 0 no_leading_quote
StrCmp $3 '"' 0 no_trailing_quote
StrCpy $0 $0 -1 1

no_leading_quote:
no_trailing_quote:
Pop $3
Pop $2
Exch $0
FunctionEnd

StrCpy $0 `"C:\Program Files\Internet Explorer\iexplore.exe"`
System::Call 'Shlwapi::PathUnquoteSpaces(t r0r0)'
# $0=C:\Program Files\Internet Explorer\iexplore.exe


Fancy, though http://msdn.microsoft.com/en-us/libr...8VS.85%29.aspx says it's limited to MAX_PATH characters. With any luck NSIS will support \\?\-prefixed filenames one day and we'll moved beyond that limitation.