language_util_win.cc 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. // Copyright (c) 2020 GitHub, Inc.
  2. // Use of this source code is governed by the MIT license that can be
  3. // found in the LICENSE file.
  4. #include "shell/common/language_util.h"
  5. #include <roapi.h>
  6. #include <windows.system.userprofile.h>
  7. #include <wrl.h>
  8. #include "base/strings/sys_string_conversions.h"
  9. #include "base/win/core_winrt_util.h"
  10. #include "base/win/i18n.h"
  11. #include "base/win/win_util.h"
  12. #include "base/win/windows_version.h"
  13. namespace electron {
  14. std::vector<std::string> GetPreferredLanguages() {
  15. std::vector<base::string16> languages16;
  16. // Attempt to use API available on Windows 10 or later, which
  17. // returns the full list of language preferences.
  18. if (!GetPreferredLanguagesUsingGlobalization(&languages16)) {
  19. base::win::i18n::GetThreadPreferredUILanguageList(&languages16);
  20. }
  21. std::vector<std::string> languages;
  22. for (const auto& language : languages16) {
  23. languages.push_back(base::SysWideToUTF8(language));
  24. }
  25. return languages;
  26. }
  27. bool GetPreferredLanguagesUsingGlobalization(
  28. std::vector<base::string16>* languages) {
  29. if (base::win::GetVersion() < base::win::Version::WIN10)
  30. return false;
  31. if (!base::win::ResolveCoreWinRTDelayload() ||
  32. !base::win::ScopedHString::ResolveCoreWinRTStringDelayload())
  33. return false;
  34. base::win::ScopedHString guid = base::win::ScopedHString::Create(
  35. RuntimeClass_Windows_System_UserProfile_GlobalizationPreferences);
  36. Microsoft::WRL::ComPtr<
  37. ABI::Windows::System::UserProfile::IGlobalizationPreferencesStatics>
  38. prefs;
  39. HRESULT hr =
  40. base::win::RoGetActivationFactory(guid.get(), IID_PPV_ARGS(&prefs));
  41. if (FAILED(hr))
  42. return false;
  43. ABI::Windows::Foundation::Collections::IVectorView<HSTRING>* langs;
  44. hr = prefs->get_Languages(&langs);
  45. if (FAILED(hr))
  46. return false;
  47. unsigned size;
  48. hr = langs->get_Size(&size);
  49. if (FAILED(hr))
  50. return false;
  51. for (unsigned i = 0; i < size; ++i) {
  52. HSTRING hstr;
  53. hr = langs->GetAt(i, &hstr);
  54. if (SUCCEEDED(hr)) {
  55. base::WStringPiece str = base::win::ScopedHString(hstr).Get();
  56. languages->emplace_back(str.data(), str.size());
  57. }
  58. }
  59. return true;
  60. }
  61. } // namespace electron