static WCHAR *GetXPSViewerPath() { // the XPS-Viewer seems to always be installed into %WINDIR%\system32 WCHAR buffer[MAX_PATH]; UINT res = GetSystemDirectory(buffer, dimof(buffer)); if (!res || res >= dimof(buffer)) return NULL; ScopedMem<WCHAR> exePath(path::Join(buffer, L"xpsrchvw.exe")); if (file::Exists(exePath)) return exePath.StealData(); #ifndef _WIN64 // Wow64 redirects access to system32 to syswow64 instead, so we // disable file system redirection using the recommended method from // http://msdn.microsoft.com/en-us/library/aa384187(v=vs.85).aspx if (IsRunningInWow64()) { res = GetWindowsDirectory(buffer, dimof(buffer)); if (!res || res >= dimof(buffer)) return NULL; exePath.Set(path::Join(buffer, L"Sysnative\\xpsrchvw.exe")); if (file::Exists(exePath)) return exePath.StealData(); } #endif return NULL; }
static void GetOsVersion(str::Str<char>& s) { OSVERSIONINFOEX ver; ZeroMemory(&ver, sizeof(ver)); ver.dwOSVersionInfoSize = sizeof(ver); #pragma warning(push) #pragma warning(disable: 4996) // 'GetVersionEx': was declared deprecated // starting with Windows 8.1, GetVersionEx will report a wrong version number // unless the OS's GUID has been explicitly added to the compatibility manifest BOOL ok = GetVersionEx((OSVERSIONINFO*)&ver); #pragma warning(pop) if (!ok) return; const char *os = OsNameFromVer(ver); int servicePackMajor = ver.wServicePackMajor; int servicePackMinor = ver.wServicePackMinor; int buildNumber = ver.dwBuildNumber & 0xFFFF; #ifdef _WIN64 const char *arch = "64-bit"; #else const char *arch = IsRunningInWow64() ? "Wow64" : "32-bit"; #endif if (0 == servicePackMajor) s.AppendFmt("OS: Windows %s build %d %s\r\n", os, buildNumber, arch); else if (0 == servicePackMinor) s.AppendFmt("OS: Windows %s SP%d build %d %s\r\n", os, servicePackMajor, buildNumber, arch); else s.AppendFmt("OS: Windows %s %d.%d build %d %s\r\n", os, servicePackMajor, servicePackMinor, buildNumber, arch); }
static void GetOsVersion(str::Str<char>& s) { OSVERSIONINFOEX ver; ZeroMemory(&ver, sizeof(ver)); ver.dwOSVersionInfoSize = sizeof(ver); BOOL ok = GetVersionEx((OSVERSIONINFO*)&ver); if (!ok) return; char *os = OsNameFromVer(ver); int servicePackMajor = ver.wServicePackMajor; int servicePackMinor = ver.wServicePackMinor; int buildNumber = ver.dwBuildNumber & 0xFFFF; #ifdef _WIN64 char *arch = "64-bit"; #else char *arch = IsRunningInWow64() ? "Wow64" : "32-bit"; #endif if (0 == servicePackMajor) s.AppendFmt("OS: Windows %s build %d %s\r\n", os, buildNumber, arch); else if (0 == servicePackMinor) s.AppendFmt("OS: Windows %s SP%d build %d %s\r\n", os, servicePackMajor, buildNumber, arch); else s.AppendFmt("OS: Windows %s %d.%d build %d %s\r\n", os, servicePackMajor, servicePackMinor, buildNumber, arch); }
// TODO: since we have a variable UI, for better layout (anchored to the bottom, // not the top), we should layout controls starting at the bottom and go up void OnCreateWindow(HWND hwnd) { // TODO: this button might be too narrow for some translations gHwndButtonInstUninst = CreateDefaultButton(hwnd, _TR("Install SumatraPDF"), 140); RectI rc(WINDOW_MARGIN, 0, dpiAdjust(96), PUSH_BUTTON_DY); ClientRect r(hwnd); rc.y = r.dy - rc.dy - WINDOW_MARGIN; gHwndButtonOptions = CreateWindow(WC_BUTTON, _TR("&Options"), BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, rc.x, rc.y, rc.dx, rc.dy, hwnd, (HMENU)ID_BUTTON_OPTIONS, ghinst, NULL); SetWindowFont(gHwndButtonOptions, gFontDefault, TRUE); int staticDy = dpiAdjust(20); rc.y = TITLE_PART_DY + WINDOW_MARGIN; gHwndStaticInstDir = CreateWindow(WC_STATIC, _TR("Install SumatraPDF in &folder:"), WS_CHILD, rc.x, rc.y, r.dx - 2 * rc.x, staticDy, hwnd, NULL, ghinst, NULL); SetWindowFont(gHwndStaticInstDir, gFontDefault, TRUE); rc.y += staticDy; gHwndTextboxInstDir = CreateWindow(WC_EDIT, gGlobalData.installDir, WS_CHILD | WS_TABSTOP | WS_BORDER | ES_LEFT | ES_AUTOHSCROLL, rc.x, rc.y, r.dx - 3 * rc.x - staticDy, staticDy, hwnd, NULL, ghinst, NULL); SetWindowFont(gHwndTextboxInstDir, gFontDefault, TRUE); gHwndButtonBrowseDir = CreateWindow(WC_BUTTON, L"&...", BS_PUSHBUTTON | WS_CHILD | WS_TABSTOP, r.dx - rc.x - staticDy, rc.y, staticDy, staticDy, hwnd, (HMENU)ID_BUTTON_BROWSE, ghinst, NULL); SetWindowFont(gHwndButtonBrowseDir, gFontDefault, TRUE); rc.y += 2 * staticDy; ScopedMem<WCHAR> defaultViewer(GetDefaultPdfViewer()); BOOL hasOtherViewer = !str::EqI(defaultViewer, APP_NAME_STR); BOOL isSumatraDefaultViewer = defaultViewer && !hasOtherViewer; // only show the checbox if Sumatra is not already a default viewer. // the alternative (disabling the checkbox) is more confusing if (!isSumatraDefaultViewer) { gHwndCheckboxRegisterDefault = CreateWindow( WC_BUTTON, _TR("Use SumatraPDF as the &default PDF reader"), WS_CHILD | BS_AUTOCHECKBOX | WS_TABSTOP, rc.x, rc.y, r.dx - 2 * rc.x, staticDy, hwnd, (HMENU)ID_CHECKBOX_MAKE_DEFAULT, ghinst, NULL); SetWindowFont(gHwndCheckboxRegisterDefault, gFontDefault, TRUE); // only check the "Use as default" checkbox when no other PDF viewer // is currently selected (not going to intrude) Button_SetCheck(gHwndCheckboxRegisterDefault, !hasOtherViewer || gGlobalData.registerAsDefault); rc.y += staticDy; } gHwndCheckboxRegisterBrowserPlugin = CreateWindow( WC_BUTTON, _TR("Install PDF &browser plugin for Firefox, Chrome and Opera"), WS_CHILD | BS_AUTOCHECKBOX | WS_TABSTOP, rc.x, rc.y, r.dx - 2 * rc.x, staticDy, hwnd, (HMENU)ID_CHECKBOX_BROWSER_PLUGIN, ghinst, NULL); SetWindowFont(gHwndCheckboxRegisterBrowserPlugin, gFontDefault, TRUE); Button_SetCheck(gHwndCheckboxRegisterBrowserPlugin, gGlobalData.installBrowserPlugin || IsBrowserPluginInstalled()); rc.y += staticDy; // only show this checkbox if the CPU arch of DLL and OS match // (assuming that the installer has the same CPU arch as its content!) #ifndef _WIN64 if (!IsRunningInWow64()) #endif { gHwndCheckboxRegisterPdfFilter = CreateWindow( WC_BUTTON, _TR("Let Windows Desktop Search &search PDF documents"), WS_CHILD | BS_AUTOCHECKBOX | WS_TABSTOP, rc.x, rc.y, r.dx - 2 * rc.x, staticDy, hwnd, (HMENU)ID_CHECKBOX_PDF_FILTER, ghinst, NULL); SetWindowFont(gHwndCheckboxRegisterPdfFilter, gFontDefault, TRUE); Button_SetCheck(gHwndCheckboxRegisterPdfFilter, gGlobalData.installPdfFilter || IsPdfFilterInstalled()); rc.y += staticDy; } // for Windows XP, this means only basic thumbnail support gHwndCheckboxRegisterPdfPreviewer = CreateWindow( WC_BUTTON, _TR("Let Windows show &previews of PDF documents"), WS_CHILD | BS_AUTOCHECKBOX | WS_TABSTOP, rc.x, rc.y, r.dx - 2 * rc.x, staticDy, hwnd, (HMENU)ID_CHECKBOX_PDF_PREVIEWER, ghinst, NULL); SetWindowFont(gHwndCheckboxRegisterPdfPreviewer, gFontDefault, TRUE); Button_SetCheck(gHwndCheckboxRegisterPdfPreviewer, gGlobalData.installPdfPreviewer || IsPdfPreviewerInstalled()); rc.y += staticDy; gShowOptions = !gShowOptions; OnButtonOptions(); SetFocus(gHwndButtonInstUninst); }
static WCHAR *GetGhostscriptPath() { WCHAR *gsProducts[] = { L"AFPL Ghostscript", L"Aladdin Ghostscript", L"GPL Ghostscript", L"GNU Ghostscript", }; // find all installed Ghostscript versions WStrVec versions; REGSAM access = KEY_READ | KEY_WOW64_32KEY; TryAgain64Bit: for (int i = 0; i < dimof(gsProducts); i++) { HKEY hkey; ScopedMem<WCHAR> keyName(str::Join(L"Software\\", gsProducts[i])); if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyName, 0, access, &hkey) != ERROR_SUCCESS) continue; WCHAR subkey[32]; for (DWORD ix = 0; RegEnumKey(hkey, ix, subkey, dimof(subkey)) == ERROR_SUCCESS; ix++) versions.Append(str::Dup(subkey)); RegCloseKey(hkey); } if ((access & KEY_WOW64_32KEY)) { // also look for 64-bit Ghostscript versions under 64-bit Windows access = KEY_READ | KEY_WOW64_64KEY; #ifndef _WIN64 // (unless this is 32-bit Windows) if (IsRunningInWow64()) #endif goto TryAgain64Bit; } versions.SortNatural(); // return the path to the newest installation for (size_t ix = versions.Count(); ix > 0; ix--) { for (int i = 0; i < dimof(gsProducts); i++) { ScopedMem<WCHAR> keyName(str::Format(L"Software\\%s\\%s", gsProducts[i], versions.At(ix - 1))); ScopedMem<WCHAR> GS_DLL(ReadRegStr(HKEY_LOCAL_MACHINE, keyName, L"GS_DLL")); if (!GS_DLL) continue; ScopedMem<WCHAR> dir(path::GetDir(GS_DLL)); ScopedMem<WCHAR> exe(path::Join(dir, L"gswin32c.exe")); if (file::Exists(exe)) return exe.StealData(); exe.Set(path::Join(dir, L"gswin64c.exe")); if (file::Exists(exe)) return exe.StealData(); } } // if Ghostscript isn't found in the Registry, try finding it in the %PATH% DWORD size = GetEnvironmentVariable(L"PATH", NULL, 0); ScopedMem<WCHAR> envpath(AllocArray<WCHAR>(size)); if (size > 0 && envpath) { GetEnvironmentVariable(L"PATH", envpath, size); WStrVec paths; paths.Split(envpath, L";", true); for (size_t ix = 0; ix < paths.Count(); ix++) { ScopedMem<WCHAR> exe(path::Join(paths.At(ix), L"gswin32c.exe")); if (file::Exists(exe)) return exe.StealData(); exe.Set(path::Join(paths.At(ix), L"gswin64c.exe")); if (file::Exists(exe)) return exe.StealData(); } } return NULL; }