Archive: Problem with $PROGRAMFILES under German Windows Vista


Problem with $PROGRAMFILES under German Windows Vista
Have problems with $PROGRAMFILES under German Windows Vista. In German Windows Vista program files are usually copied to "c:\programme\..." but got "c:\program files\...". Works fine under Windows XP. Any hints?


Program Files is the proper name of the directory. The changed name is a result of all Vista editions being MUI-based: the directory is always called Program Files, and the localized name is a virtual folder, pointing to the "real" one.

The reason you see Programme in Explorer, is that it uses API calls to format the displayed path according to the active language pack.


Many thanks for your clarification and you're right. The installation also works with "Program Files" but I'm afraid German / non English end customers will get confused. On other Microsoft operation systems the Installation Folder dialog (Destination Folder) shows the localized name. Any ideas / pointers how I can get the virtual folder name?


Actually, you shouldn't expect it to work if you wrote "Programme" - the handling of that virtual folder can be a bit peculiar at times.

Displaying the localized path: Take a look at http://blogs.msdn.com/michkap/archiv...4.aspx#1736328 - there's some sample C code to get the path. I think it might need to be integrated in the NSIS executable, though - I'm not sure if it's doable using only NSIS scripts.

As for confusion - you're right that this happens, but in my experience, people learn to deal with it after their first install of a program that doesn't use this approach (which is pretty much anything not MSI-based).


Hi all,

I stumbled over this thread by searching for the $PROGRAMFILES problem under german Windows Vista / Windows 7.

Well, I need to write the $INSTDIR Path, which consists of the $PROGRAMFILES constant, to the registry to get an external program starting the installed application.
The problem is that the external program cannot start the application, because of the wrong path.

During installation he shows "C:\Program Files\Application"
and thats the path he writes to the registry, but the application will be installed to "C:\Programme\Application".

Im getting really frustrated ... there must be a solution for this I think?

I hope you can help me out :(


The situation is no different: C:\Programme doesn't really exist, the folder is really called C:\Program Files and Vista/7 uses the API call mentioned in my previous to localize the displayed path in Explorer.

You can verify this for yourself by opening a command prompt and navigating there, since that doesn't localize anything.

Your other application should not fail as long as Program Files is what's being written to the registry. If it does, then you probably have some other problem - like having told your installer to not elevate (in which case it *can't* write to Program Files if UAC is on).


Originally posted by Pidgeot
having told your installer to not elevate (in which case it *can't* write to Program Files if UAC is on).
Actually in that case you can't write to Program Files even if UAC is off.

thanks guys for bringing this topic up.
simple question: is there a way to just extract the localized name of the "Program Files" from the registry or something ?

which means, do we have a way to extract the strings like: "Programme" or "Archivos De Programma" which are equivalent to "Program Files" ?

thanks in anticipation :D


This is rather old thread, but I have the same problem now. Is there a new idea how I can show the virtual name when the user selects the installation path? Is there a plug-in for this?


Converting that code to the System plug-in:

!define DONT_RESOLVE_DLL_REFERENCES 0x00000001
!define LOAD_LIBRARY_AS_DATAFILE 0x00000002

System::Call `shell32::SHGetLocalizedName(t "$PROGRAMFILES", i ${NSIS_MAX_STRLEN}, i .R0) i .R1`
${If} $R1 == 0
ExpandEnvStrings $R0 $R0
${If} ${FileExists} $R0
System::Call `kernel32::LoadLibraryEx(t R0, i 0, i ${DONT_RESOLVE_DLL_REFERENCES}|${LOAD_LIBRARY_AS_DATAFILE}) i .R1`
${If} $R1 != 0
System::Call `user32::LoadString(i R1, i R0, t .R2, i ${NSIS_MAX_STRLEN}) i .R3`
${If} $R3 != 0
MessageBox MB_OK $R2
${EndIf}
System::Call `kernel32::FreeLibrary(i R1)`
${EndIf}
${EndIf}
${EndIf}
This has not been tested.

Stu

Hi Afrow,
Thank for the code. I compiled it, but the message box doesn't appear. It looks that R3 is always 0, but I don't know why. I don't understand too much from this code. Can you help me to start it up, please?


SetShellVarContext all ;accessing all users startmenu
System::Call 'SHELL32::SHGetLocalizedName(w "$SMPrograms\Accessories\Welcome Center.lnk",w.r1,i ${NSIS_MAX_STRLEN},*i.r2)i.r0'
${If} $0 = 0
ExpandEnvStrings $1 $1
System::Call 'KERNEL32::LoadLibraryEx(tr1,i0,i 0x23)i.r1'
${If} $1 <> 0
System::Call 'USER32::LoadString(ir1,ir2,t.r2,i ${NSIS_MAX_STRLEN})i.r0'
${If} $0 <> 0
DetailPrint LocalizedName=$2
${EndIf}
System::Call 'KERNEL32::FreeLibrary(ir1)'
${EndIf}
${EndIf}
This prints "LocalizedName=Getting Started" on this English Win7 system.