Reputation: 67
I use the ProgramFiles64Folder in wix to get the Program Files folder in my installer.
The problem is it displays c:\Program Files instead of c:\Programmes which is the french value.
It still installs to the correct folder but my users are asking why they don't see the french value.
I have opened the msi with orca and i see ProgramFiles64Folder so I guess it's not a wix specific issue but a windows installer one.
How can I get the localized value for Program Files folder with wix ?
Upvotes: 2
Views: 416
Reputation: 27766
What you are seeing is the Win32 file system path, which is no longer localized beginning with Windows Vista. What you want instead is the shell's localized display path.
Windows Installer displays only file system paths in its build-in UI. I'm not exactly sure about WiX Burn UI, but most likely it will also show the file system path only.
You could write a DLL custom action (see MSDN and WiX reference) to get the display path.
The following is C++ code of a simple console application that demonstrates how to convert a file system path to a display path. In a custom action you would call MsiGetProperty
to get the value of the directory property that contains the installation path, convert it to a display path using code similar to my example and finally call MsiSetProperty
to assign the display path to another property that you would show in the UI.
#include <Windows.h>
#include <ShlObj.h> // Shell API
#include <Propkey.h> // PKEY_* constants
#include <atlcomcli.h> // CComPtr
#include <atlbase.h> // CComHeapPtr
#include <iostream>
#include <io.h>
#include <fcntl.h>
// Convert a filesystem path to the shell's localized display path.
HRESULT GetDisplayPathFromFileSystemPath( LPCWSTR path, PWSTR* ppszDisplayPath )
{
CComPtr<IShellItem2> pItem;
HRESULT hr = SHCreateItemFromParsingName( path, nullptr, IID_PPV_ARGS( &pItem ) );
if( FAILED( hr ) )
return hr;
return pItem->GetString( PKEY_ItemPathDisplay, ppszDisplayPath );
}
int main()
{
CoInitialize( nullptr ); // TODO: check return value
_setmode( _fileno( stdout ), _O_U16TEXT ); // for proper UTF-16 console output
LPCWSTR fileSystemPath = L"C:\\Users\\Public\\Pictures";
CComHeapPtr<WCHAR> displayPath;
if( SUCCEEDED( GetDisplayPathFromFileSystemPath( fileSystemPath, &displayPath ) ) )
{
// Output the localized display path
std::wcout << static_cast<LPCWSTR>( displayPath ) << std::endl;
}
CoUninitialize();
}
The only really important code here is in the GetDisplayPathFromFileSystemPath()
function. It calls SHCreateItemFromParsingName()
to create an IShellItem2
object from a file system path. From this object it retrieves the value of the property PKEY_ItemPathDisplay
, which contains the display path we are interested in.
Upvotes: 2