diff --git a/base/applications/rapps/appinfo.cpp b/base/applications/rapps/appinfo.cpp index 9587afb87b2..4aea019ecf2 100644 --- a/base/applications/rapps/appinfo.cpp +++ b/base/applications/rapps/appinfo.cpp @@ -375,18 +375,48 @@ CAvailableApplicationInfo::GetDisplayInfo(CStringW &License, CStringW &Size, CSt UrlDownload = m_szUrlDownload; } +static InstallerType +GetInstallerTypeFromString(const CStringW &Installer) +{ + if (Installer.CompareNoCase(L"Inno") == 0) + return INSTALLER_INNO; + if (Installer.CompareNoCase(L"NSIS") == 0) + return INSTALLER_NSIS; + return INSTALLER_UNKNOWN; +} + InstallerType -CAvailableApplicationInfo::GetInstallerType() const +CAvailableApplicationInfo::GetInstallerType(bool NestedType) const { CStringW str; m_Parser->GetString(DB_INSTALLER, str); if (str.CompareNoCase(DB_INSTALLER_GENERATE) == 0) + { return INSTALLER_GENERATE; - if (str.CompareNoCase(DB_INSTALLER_EXEINZIP) == 0) + } + else if (str.CompareNoCase(DB_INSTALLER_EXEINZIP) == 0) + { + if (NestedType) + { + CStringW nested; + m_Parser->GetSectionString(DB_EXEINZIPSECTION, DB_INSTALLER, nested); + InstallerType it = GetInstallerTypeFromString(nested); + if (it != INSTALLER_UNKNOWN) + return it; + } return INSTALLER_EXEINZIP; + } return INSTALLER_UNKNOWN; } +InstallerType +CAvailableApplicationInfo::GetInstallerInfo(CStringW &SilentParameters) const +{ + InstallerType it = GetInstallerType(true); + m_Parser->GetString(DB_SILENTARGS, SilentParameters); + return it; +} + BOOL CAvailableApplicationInfo::UninstallApplication(UninstallCommandFlags Flags) { @@ -584,7 +614,7 @@ CInstalledApplicationInfo::GetDisplayInfo(CStringW &License, CStringW &Size, CSt } InstallerType -CInstalledApplicationInfo::GetInstallerType() const +CInstalledApplicationInfo::GetInstallerType(bool NestedType) const { CRegKey reg; if (reg.Open(m_hKey, GENERATE_ARPSUBKEY, KEY_READ) == ERROR_SUCCESS) diff --git a/base/applications/rapps/geninst.cpp b/base/applications/rapps/geninst.cpp index d643a084f06..f89d6d67b71 100644 --- a/base/applications/rapps/geninst.cpp +++ b/base/applications/rapps/geninst.cpp @@ -678,9 +678,10 @@ CreateUI(BOOL Silent, LPTHREAD_START_ROUTINE ThreadProc) } BOOL -ExtractAndRunGeneratedInstaller(const CAvailableApplicationInfo &AppInfo, LPCWSTR Archive) +ExtractAndRunGeneratedInstaller(const CAvailableApplicationInfo &AppInfo, LPCWSTR Archive, bool Silent) { InstallInfo Info(AppInfo.szDisplayName, *AppInfo.GetConfigParser(), Archive); + Info.Silent = Silent; g_pInfo = &Info; return CreateUI(Info.Silent, ExtractAndInstallThread) ? !Info.Error : FALSE; } diff --git a/base/applications/rapps/gui.cpp b/base/applications/rapps/gui.cpp index 8470ba092d1..7ceab662da5 100644 --- a/base/applications/rapps/gui.cpp +++ b/base/applications/rapps/gui.cpp @@ -579,7 +579,7 @@ CMainWindow::OnCommand(WPARAM wParam, LPARAM lParam) { if (!m_Selected.IsEmpty()) { - if (DownloadListOfApplications(m_Selected, FALSE)) + if (DownloadListOfApplications(m_Selected)) { m_Selected.RemoveAll(); UpdateApplicationsList(SelectedEnumType); diff --git a/base/applications/rapps/include/appinfo.h b/base/applications/rapps/include/appinfo.h index 171d8edce9c..7f8dd72a720 100644 --- a/base/applications/rapps/include/appinfo.h +++ b/base/applications/rapps/include/appinfo.h @@ -4,7 +4,6 @@ #include #include - enum LicenseType { LICENSE_NONE, @@ -72,9 +71,9 @@ IsInstalledEnum(INT x) enum UninstallCommandFlags { - UCF_NONE = 0x00, - UCF_MODIFY = 0x01, - UCF_SILENT = 0x02, + UCF_NONE = 0x00, + UCF_SILENT = 0x01, + UCF_MODIFY = 0x02, UCF_SAMEPROCESS = 0x04, }; DEFINE_ENUM_FLAG_OPERATORS(UninstallCommandFlags); @@ -82,8 +81,11 @@ DEFINE_ENUM_FLAG_OPERATORS(UninstallCommandFlags); enum InstallerType { INSTALLER_UNKNOWN, + INSTALLER_EXEINZIP, // setup.exe we extract from a .zip file INSTALLER_GENERATE, // .zip file automatically converted to installer by rapps - INSTALLER_EXEINZIP, + INSTALLER_MSI, + INSTALLER_INNO, + INSTALLER_NSIS, }; #define DB_VERSION L"Version" @@ -95,6 +97,7 @@ enum InstallerType #define DB_INSTALLER_EXEINZIP L"ExeInZip" #define DB_SCOPE L"Scope" // User or Machine #define DB_SAVEAS L"SaveAs" +#define DB_SILENTARGS L"SilentParameters" #define DB_GENINSTSECTION L"Generate" #define GENERATE_ARPSUBKEY L"RApps" // Our uninstall data is stored here @@ -134,7 +137,9 @@ class CAppInfo virtual VOID GetDisplayInfo(CStringW &License, CStringW &Size, CStringW &UrlSite, CStringW &UrlDownload) = 0; virtual InstallerType - GetInstallerType() const { return INSTALLER_UNKNOWN; } + GetInstallerType(bool NestedType = false) const { return INSTALLER_UNKNOWN; } + virtual InstallerType + GetInstallerInfo(CStringW &SilentParameters) const { return GetInstallerType(); } virtual BOOL UninstallApplication(UninstallCommandFlags Flags) = 0; }; @@ -185,7 +190,9 @@ class CAvailableApplicationInfo : public CAppInfo virtual VOID GetDisplayInfo(CStringW &License, CStringW &Size, CStringW &UrlSite, CStringW &UrlDownload) override; virtual InstallerType - GetInstallerType() const override; + GetInstallerType(bool NestedType = false) const override; + virtual InstallerType + GetInstallerInfo(CStringW &SilentParameters) const override; virtual BOOL UninstallApplication(UninstallCommandFlags Flags) override; }; @@ -231,7 +238,7 @@ class CInstalledApplicationInfo : public CAppInfo virtual VOID GetDisplayInfo(CStringW &License, CStringW &Size, CStringW &UrlSite, CStringW &UrlDownload) override; virtual InstallerType - GetInstallerType() const override; + GetInstallerType(bool NestedType = false) const override; virtual BOOL UninstallApplication(UninstallCommandFlags Flags) override; }; @@ -239,6 +246,6 @@ class CInstalledApplicationInfo : public CAppInfo BOOL UninstallGenerated(CInstalledApplicationInfo &AppInfo, UninstallCommandFlags Flags); BOOL -ExtractAndRunGeneratedInstaller(const CAvailableApplicationInfo &AppInfo, LPCWSTR Archive); +ExtractAndRunGeneratedInstaller(const CAvailableApplicationInfo &AppInfo, LPCWSTR Archive, bool Silent); HRESULT ExtractArchiveForExecution(PCWSTR pszArchive, const CStringW &PackageName, CStringW &TempDir, CStringW &App); diff --git a/base/applications/rapps/include/dialogs.h b/base/applications/rapps/include/dialogs.h index 93b8720f497..bbdc909545d 100644 --- a/base/applications/rapps/include/dialogs.h +++ b/base/applications/rapps/include/dialogs.h @@ -9,9 +9,13 @@ VOID CreateSettingsDlg(HWND hwnd); // Download dialogs +enum DOWNLOADAPPFLAGS { + DAF_SILENT = 0x01, + DAF_MODAL = 0x02, +}; VOID DownloadApplicationsDB(LPCWSTR lpUrl, BOOL IsOfficial); BOOL DownloadApplication(CAppInfo *pAppInfo); BOOL -DownloadListOfApplications(const CAtlList &AppsList, BOOL bIsModal); +DownloadListOfApplications(const CAtlList &AppsList, UINT Flags = 0); diff --git a/base/applications/rapps/include/misc.h b/base/applications/rapps/include/misc.h index b6861e7de7c..4eb47f1a020 100644 --- a/base/applications/rapps/include/misc.h +++ b/base/applications/rapps/include/misc.h @@ -1,6 +1,7 @@ #pragma once #include +#include "appinfo.h" #ifdef _M_IX86 #define CurrentArchitecture L"x86" @@ -159,3 +160,9 @@ struct CScopedMutex bool Acquired() const { return m_hMutex != NULL; } }; + +InstallerType +GuessInstallerType(LPCWSTR Installer, UINT &ExtraInfo); + +BOOL +GetSilentInstallParameters(InstallerType InstallerType, UINT ExtraInfo, LPCWSTR Installer, CStringW &Parameters); diff --git a/base/applications/rapps/include/unattended.h b/base/applications/rapps/include/unattended.h index dd6ea07b595..b496c289712 100644 --- a/base/applications/rapps/include/unattended.h +++ b/base/applications/rapps/include/unattended.h @@ -13,9 +13,9 @@ const WCHAR UsageString[] = L"RAPPS \ [/" CMD_KEY_HELP L"] \ -[/" CMD_KEY_INSTALL L" packagename] \ +[/" CMD_KEY_INSTALL L" [/S] packagename] \ [/" CMD_KEY_UNINSTALL L" packagename|displayname] \ -[/" CMD_KEY_SETUP L" filename] \ +[/" CMD_KEY_SETUP L" [/S] filename] \ [/" CMD_KEY_FIND L" string] \ [/" CMD_KEY_INFO L" packagename]"; diff --git a/base/applications/rapps/lang/bg-BG.rc b/base/applications/rapps/lang/bg-BG.rc index 5d8f27e4dba..2d214cb014f 100644 --- a/base/applications/rapps/lang/bg-BG.rc +++ b/base/applications/rapps/lang/bg-BG.rc @@ -84,7 +84,7 @@ BEGIN END IDD_DOWNLOAD_DIALOG DIALOGEX 0, 0, 220, 220 -STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION | WS_VISIBLE +STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "Сваляне %ls…" FONT 8, "MS Shell Dlg" BEGIN diff --git a/base/applications/rapps/lang/cs-CZ.rc b/base/applications/rapps/lang/cs-CZ.rc index 8d336327cfe..8f46bb365d3 100644 --- a/base/applications/rapps/lang/cs-CZ.rc +++ b/base/applications/rapps/lang/cs-CZ.rc @@ -85,7 +85,7 @@ BEGIN END IDD_DOWNLOAD_DIALOG DIALOGEX 0, 0, 220, 220 -STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION | WS_VISIBLE +STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "Stahování %ls…" FONT 8, "MS Shell Dlg" BEGIN diff --git a/base/applications/rapps/lang/de-DE.rc b/base/applications/rapps/lang/de-DE.rc index 53d4a111147..05273c79e8e 100644 --- a/base/applications/rapps/lang/de-DE.rc +++ b/base/applications/rapps/lang/de-DE.rc @@ -87,7 +87,7 @@ BEGIN END IDD_DOWNLOAD_DIALOG DIALOGEX 0, 0, 220, 220 -STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION | WS_VISIBLE +STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "Download von %ls…" FONT 8, "MS Shell Dlg" BEGIN diff --git a/base/applications/rapps/lang/en-US.rc b/base/applications/rapps/lang/en-US.rc index 499aeb5142d..2ce25a39fad 100644 --- a/base/applications/rapps/lang/en-US.rc +++ b/base/applications/rapps/lang/en-US.rc @@ -87,7 +87,7 @@ BEGIN END IDD_DOWNLOAD_DIALOG DIALOGEX 0, 0, 220, 220 -STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION | WS_VISIBLE +STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "Downloading %ls…" FONT 8, "MS Shell Dlg" BEGIN diff --git a/base/applications/rapps/lang/es-ES.rc b/base/applications/rapps/lang/es-ES.rc index 67f2a930802..54706c57305 100644 --- a/base/applications/rapps/lang/es-ES.rc +++ b/base/applications/rapps/lang/es-ES.rc @@ -86,7 +86,7 @@ BEGIN END IDD_DOWNLOAD_DIALOG DIALOGEX 0, 0, 220, 220 -STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION | WS_VISIBLE +STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "Descargando %ls…" FONT 8, "MS Shell Dlg" BEGIN diff --git a/base/applications/rapps/lang/et-EE.rc b/base/applications/rapps/lang/et-EE.rc index 9ab9214ea41..55032673bd0 100644 --- a/base/applications/rapps/lang/et-EE.rc +++ b/base/applications/rapps/lang/et-EE.rc @@ -84,7 +84,7 @@ BEGIN END IDD_DOWNLOAD_DIALOG DIALOGEX 0, 0, 220, 220 -STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION | WS_VISIBLE +STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "%ls allalaadimine…" FONT 8, "MS Shell Dlg" BEGIN diff --git a/base/applications/rapps/lang/fr-FR.rc b/base/applications/rapps/lang/fr-FR.rc index ddad6d4c90a..61d446595f3 100644 --- a/base/applications/rapps/lang/fr-FR.rc +++ b/base/applications/rapps/lang/fr-FR.rc @@ -87,7 +87,7 @@ BEGIN END IDD_DOWNLOAD_DIALOG DIALOGEX 0, 0, 220, 220 -STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION | WS_VISIBLE +STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "Téléchargement %ls…" FONT 8, "MS Shell Dlg" BEGIN diff --git a/base/applications/rapps/lang/he-IL.rc b/base/applications/rapps/lang/he-IL.rc index 90837d9fc01..a9c5beab1cc 100644 --- a/base/applications/rapps/lang/he-IL.rc +++ b/base/applications/rapps/lang/he-IL.rc @@ -88,7 +88,7 @@ BEGIN END IDD_DOWNLOAD_DIALOG DIALOGEX 0, 0, 220, 220 -STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION | WS_VISIBLE +STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION EXSTYLE WS_EX_LAYOUTRTL CAPTION "הורדה %ls…" FONT 8, "MS Shell Dlg" diff --git a/base/applications/rapps/lang/hu-HU.rc b/base/applications/rapps/lang/hu-HU.rc index 21f7b9b71ee..71f9ee09fe4 100644 --- a/base/applications/rapps/lang/hu-HU.rc +++ b/base/applications/rapps/lang/hu-HU.rc @@ -84,7 +84,7 @@ BEGIN END IDD_DOWNLOAD_DIALOG DIALOGEX 0, 0, 220, 220 -STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION | WS_VISIBLE +STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "%ls letöltése…" FONT 8, "MS Shell Dlg" BEGIN diff --git a/base/applications/rapps/lang/id-ID.rc b/base/applications/rapps/lang/id-ID.rc index 1dde61b4136..aea7a0154ef 100644 --- a/base/applications/rapps/lang/id-ID.rc +++ b/base/applications/rapps/lang/id-ID.rc @@ -84,7 +84,7 @@ BEGIN END IDD_DOWNLOAD_DIALOG DIALOGEX 0, 0, 220, 220 -STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION | WS_VISIBLE +STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "Mengunduh %ls…" FONT 8, "MS Shell Dlg" BEGIN diff --git a/base/applications/rapps/lang/it-IT.rc b/base/applications/rapps/lang/it-IT.rc index 1075574ba4c..e3b0199410f 100644 --- a/base/applications/rapps/lang/it-IT.rc +++ b/base/applications/rapps/lang/it-IT.rc @@ -86,7 +86,7 @@ BEGIN END IDD_DOWNLOAD_DIALOG DIALOGEX 0, 0, 220, 220 -STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION | WS_VISIBLE +STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "Scaricamento in corso %ls…" FONT 8, "MS Shell Dlg" BEGIN diff --git a/base/applications/rapps/lang/ja-JP.rc b/base/applications/rapps/lang/ja-JP.rc index a094a4074eb..bff0ba930d8 100644 --- a/base/applications/rapps/lang/ja-JP.rc +++ b/base/applications/rapps/lang/ja-JP.rc @@ -86,7 +86,7 @@ BEGIN END IDD_DOWNLOAD_DIALOG DIALOGEX 0, 0, 220, 220 -STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION | WS_VISIBLE +STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "%ls をダウンロード中..." FONT 9, "MS UI Gothic" BEGIN diff --git a/base/applications/rapps/lang/no-NO.rc b/base/applications/rapps/lang/no-NO.rc index b271227c78a..af86ca612fe 100644 --- a/base/applications/rapps/lang/no-NO.rc +++ b/base/applications/rapps/lang/no-NO.rc @@ -84,7 +84,7 @@ BEGIN END IDD_DOWNLOAD_DIALOG DIALOGEX 0, 0, 220, 220 -STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION | WS_VISIBLE +STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "Lastet ned %ls…" FONT 8, "MS Shell Dlg" BEGIN diff --git a/base/applications/rapps/lang/pl-PL.rc b/base/applications/rapps/lang/pl-PL.rc index 1aa2fcc6135..100ec0223bd 100644 --- a/base/applications/rapps/lang/pl-PL.rc +++ b/base/applications/rapps/lang/pl-PL.rc @@ -86,7 +86,7 @@ BEGIN END IDD_DOWNLOAD_DIALOG DIALOGEX 0, 0, 220, 220 -STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION | WS_VISIBLE +STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "Pobieranie %ls…" FONT 8, "MS Shell Dlg" BEGIN diff --git a/base/applications/rapps/lang/pt-BR.rc b/base/applications/rapps/lang/pt-BR.rc index 807615a63ca..bb26ae1ac84 100644 --- a/base/applications/rapps/lang/pt-BR.rc +++ b/base/applications/rapps/lang/pt-BR.rc @@ -84,7 +84,7 @@ BEGIN END IDD_DOWNLOAD_DIALOG DIALOGEX 0, 0, 220, 220 -STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION | WS_VISIBLE +STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "Download %ls…" FONT 8, "MS Shell Dlg" BEGIN diff --git a/base/applications/rapps/lang/pt-PT.rc b/base/applications/rapps/lang/pt-PT.rc index dfdd2850137..d75033d4368 100644 --- a/base/applications/rapps/lang/pt-PT.rc +++ b/base/applications/rapps/lang/pt-PT.rc @@ -84,7 +84,7 @@ BEGIN END IDD_DOWNLOAD_DIALOG DIALOGEX 0, 0, 220, 220 -STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION | WS_VISIBLE +STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "A carregar %ls…" FONT 8, "MS Shell Dlg" BEGIN diff --git a/base/applications/rapps/lang/ro-RO.rc b/base/applications/rapps/lang/ro-RO.rc index ba9421f37fe..ac3ba3e2043 100644 --- a/base/applications/rapps/lang/ro-RO.rc +++ b/base/applications/rapps/lang/ro-RO.rc @@ -86,7 +86,7 @@ BEGIN END IDD_DOWNLOAD_DIALOG DIALOGEX 0, 0, 220, 220 -STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION | WS_VISIBLE +STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "În curs de descărcare %ls…" FONT 8, "MS Shell Dlg" BEGIN diff --git a/base/applications/rapps/lang/ru-RU.rc b/base/applications/rapps/lang/ru-RU.rc index 6b119334886..b6bc6032e7a 100644 --- a/base/applications/rapps/lang/ru-RU.rc +++ b/base/applications/rapps/lang/ru-RU.rc @@ -89,7 +89,7 @@ BEGIN END IDD_DOWNLOAD_DIALOG DIALOGEX 0, 0, 220, 220 -STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION | WS_VISIBLE +STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "Загрузка %ls…" FONT 8, "MS Shell Dlg" BEGIN diff --git a/base/applications/rapps/lang/sk-SK.rc b/base/applications/rapps/lang/sk-SK.rc index 44932a0b4e3..a0367e27a1b 100644 --- a/base/applications/rapps/lang/sk-SK.rc +++ b/base/applications/rapps/lang/sk-SK.rc @@ -85,7 +85,7 @@ BEGIN END IDD_DOWNLOAD_DIALOG DIALOGEX 0, 0, 220, 220 -STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION | WS_VISIBLE +STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "Sťahujem %ls…" FONT 8, "MS Shell Dlg" BEGIN diff --git a/base/applications/rapps/lang/sq-AL.rc b/base/applications/rapps/lang/sq-AL.rc index 77feaa24eda..34f7009f7b5 100644 --- a/base/applications/rapps/lang/sq-AL.rc +++ b/base/applications/rapps/lang/sq-AL.rc @@ -84,7 +84,7 @@ BEGIN END IDD_DOWNLOAD_DIALOG DIALOGEX 0, 0, 220, 220 -STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION | WS_VISIBLE +STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "Shkarko %ls…" FONT 8, "MS Shell Dlg" BEGIN diff --git a/base/applications/rapps/lang/sv-SE.rc b/base/applications/rapps/lang/sv-SE.rc index c14b19adb51..5233cb3ddf6 100644 --- a/base/applications/rapps/lang/sv-SE.rc +++ b/base/applications/rapps/lang/sv-SE.rc @@ -84,7 +84,7 @@ BEGIN END IDD_DOWNLOAD_DIALOG DIALOGEX 0, 0, 220, 220 -STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION | WS_VISIBLE +STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "Ladda ner %ls…" FONT 8, "MS Shell Dlg" BEGIN diff --git a/base/applications/rapps/lang/tr-TR.rc b/base/applications/rapps/lang/tr-TR.rc index c33ab128536..44e3b69161b 100644 --- a/base/applications/rapps/lang/tr-TR.rc +++ b/base/applications/rapps/lang/tr-TR.rc @@ -86,7 +86,7 @@ BEGIN END IDD_DOWNLOAD_DIALOG DIALOGEX 0, 0, 220, 220 -STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION | WS_VISIBLE +STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "İndiriliyor %ls…" FONT 8, "MS Shell Dlg" BEGIN diff --git a/base/applications/rapps/lang/uk-UA.rc b/base/applications/rapps/lang/uk-UA.rc index 35cb17f24f2..5a5a8eb1775 100644 --- a/base/applications/rapps/lang/uk-UA.rc +++ b/base/applications/rapps/lang/uk-UA.rc @@ -87,7 +87,7 @@ BEGIN END IDD_DOWNLOAD_DIALOG DIALOGEX 0, 0, 220, 220 -STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION | WS_VISIBLE +STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "Завантаження %ls…" FONT 8, "MS Shell Dlg" BEGIN diff --git a/base/applications/rapps/lang/zh-CN.rc b/base/applications/rapps/lang/zh-CN.rc index 7eed7260cbf..ef6f55c720e 100644 --- a/base/applications/rapps/lang/zh-CN.rc +++ b/base/applications/rapps/lang/zh-CN.rc @@ -88,7 +88,7 @@ BEGIN END IDD_DOWNLOAD_DIALOG DIALOGEX 0, 0, 220, 220 -STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION | WS_VISIBLE +STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "正在下载 %ls…" FONT 9, "宋体" BEGIN diff --git a/base/applications/rapps/lang/zh-HK.rc b/base/applications/rapps/lang/zh-HK.rc index 2340b0963c6..7a59c3bed5d 100644 --- a/base/applications/rapps/lang/zh-HK.rc +++ b/base/applications/rapps/lang/zh-HK.rc @@ -85,7 +85,7 @@ BEGIN END IDD_DOWNLOAD_DIALOG DIALOGEX 0, 0, 220, 220 -STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION | WS_VISIBLE +STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "正在下載 %ls…" FONT 9, "新細明體" BEGIN diff --git a/base/applications/rapps/lang/zh-TW.rc b/base/applications/rapps/lang/zh-TW.rc index a3befd8880d..e22964561e4 100644 --- a/base/applications/rapps/lang/zh-TW.rc +++ b/base/applications/rapps/lang/zh-TW.rc @@ -85,7 +85,7 @@ BEGIN END IDD_DOWNLOAD_DIALOG DIALOGEX 0, 0, 220, 220 -STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION | WS_VISIBLE +STYLE DS_SHELLFONT | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "正在下載 %ls…" FONT 9, "新細明體" BEGIN diff --git a/base/applications/rapps/loaddlg.cpp b/base/applications/rapps/loaddlg.cpp index 66d4fcca1d8..6021b672a5c 100644 --- a/base/applications/rapps/loaddlg.cpp +++ b/base/applications/rapps/loaddlg.cpp @@ -137,13 +137,16 @@ struct DownloadInfo DownloadInfo() : DLType(DLTYPE_APPLICATION), IType(INSTALLER_UNKNOWN), SizeInBytes(0) { } - DownloadInfo(const CAppInfo &AppInfo) : DLType(DLTYPE_APPLICATION) + DownloadInfo(const CAppInfo &AppInfo, UINT DAF = 0) : DLType(DLTYPE_APPLICATION), Flags(DAF) { AppInfo.GetDownloadInfo(szUrl, szSHA1, SizeInBytes); szName = AppInfo.szDisplayName; IType = AppInfo.GetInstallerType(); szPackageName = AppInfo.szIdentifier; + if (Flags & DAF_SILENT) + IExecType = AppInfo.GetInstallerInfo(szSilentInstallArgs); + CConfigParser *cfg = static_cast(AppInfo).GetConfigParser(); if (cfg) cfg->GetString(DB_SAVEAS, szFileName); @@ -156,11 +159,14 @@ struct DownloadInfo DownloadType DLType; InstallerType IType; + InstallerType IExecType = INSTALLER_UNKNOWN; + UINT Flags = 0; CStringW szUrl; CStringW szName; CStringW szSHA1; CStringW szPackageName; CStringW szFileName; + CStringW szSilentInstallArgs; ULONG SizeInBytes; }; @@ -476,9 +482,9 @@ public: CDownloadManager() : m_hDlg(NULL), m_Threads(0), m_Index(0), m_bCancelled(FALSE) {} static CDownloadManager* - CreateInstanceHelper(BOOL Modal) + CreateInstanceHelper(UINT Flags) { - if (!Modal) + if (!(Flags & DAF_MODAL)) { CDownloadManager* pExisting = CDownloadManager::FindInstance(); if (pExisting) @@ -490,7 +496,8 @@ public: CComPtr obj; if (FAILED(ShellObjectCreator(obj))) return NULL; - obj->m_bModal = Modal; + obj->m_fDaf = Flags; + obj->m_bModal = !!(Flags & DAF_MODAL); return obj.Detach(); } @@ -507,7 +514,7 @@ public: static CDownloadManager* FindInstance() { - if (g_hDownloadWnd) + if (g_hDownloadWnd && IsWindowVisible(g_hDownloadWnd)) return (CDownloadManager*)SendMessageW(g_hDownloadWnd, WM_GETINSTANCE, 0, 0); return NULL; } @@ -518,6 +525,12 @@ public: return !IsWindow(m_hDlg) || SendMessageW(m_hDlg, WM_ISCANCELLED, 0, 0); } + BOOL + IsSilentDialog() + { + return m_fDaf & DAF_SILENT; + } + void StartWorkerThread(); void Add(const DownloadInfo &Info); void Show(); @@ -538,6 +551,7 @@ protected: UINT m_Index; BOOL m_bCancelled; BOOL m_bModal; + UINT m_fDaf = 0; WCHAR m_szCaptionFmt[100]; ATL::CSimpleArray m_List; CDowloadingAppsListView m_ListView; @@ -573,10 +587,17 @@ CDownloadManager::Add(const DownloadInfo &Info) void CDownloadManager::Show() { - if (m_bModal) + HWND hDlg = NULL; + const BOOL bSilent = IsSilentDialog(), bModal = m_bModal; + if (bModal && !bSilent) DialogBoxParamW(hInst, MAKEINTRESOURCEW(IDD_DOWNLOAD_DIALOG), hMainWnd, DlgProc, (LPARAM)this); else if (!m_hDlg || !IsWindow(m_hDlg)) - CreateDialogParamW(hInst, MAKEINTRESOURCEW(IDD_DOWNLOAD_DIALOG), hMainWnd, DlgProc, (LPARAM)this); + hDlg = CreateDialogParamW(hInst, MAKEINTRESOURCEW(IDD_DOWNLOAD_DIALOG), hMainWnd, DlgProc, (LPARAM)this); + + // A DialogBox dialog cannot be invisible, it is forced visible after WM_INITDIALOG returns. + // We therefore use a modeless dialog when we are both modal and silent. + for (MSG msg; bModal && bSilent && hDlg && GetMessageW(&msg, NULL, 0, 0);) + DispatchMessage(&msg); } INT_PTR CALLBACK @@ -641,7 +662,7 @@ CDownloadManager::RealDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam return FALSE; m_ListView.LoadList(m_List); - ShowWindow(hDlg, SW_SHOW); + ShowWindow(hDlg, IsSilentDialog() ? SW_HIDE : SW_SHOW); StartWorkerThread(); return TRUE; } @@ -658,7 +679,7 @@ CDownloadManager::RealDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam m_bCancelled = TRUE; if (m_ProgressBar) m_ProgressBar.UnsubclassWindow(TRUE); - return m_bModal ? ::EndDialog(hDlg, 0) : ::DestroyWindow(hDlg); + return m_bModal && !IsSilentDialog() ? ::EndDialog(hDlg, 0) : ::DestroyWindow(hDlg); case WM_DESTROY: if (g_hDownloadWnd == hDlg) @@ -666,6 +687,8 @@ CDownloadManager::RealDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam g_Busy--; if (hMainWnd) PostMessage(hMainWnd, WM_NOTIFY_OPERATIONCOMPLETED, 0, 0); + if (m_bModal && IsSilentDialog()) + PostQuitMessage(0); Release(); break; @@ -1058,6 +1081,7 @@ run: // run it if (Info.DLType == DLTYPE_APPLICATION) { + BOOL bSilentInstall = Info.Flags & DAF_SILENT; CStringW app, params, tempdir; SHELLEXECUTEINFOW shExInfo = { sizeof(shExInfo), SEE_MASK_NOCLOSEPROCESS, hDlg }; shExInfo.lpVerb = L"open"; @@ -1067,9 +1091,8 @@ run: if (Info.IType == INSTALLER_GENERATE) { - params = L"/" + CStringW(CMD_KEY_GENINST) + L" \"" + - Info.szPackageName + L"\" \"" + - CStringW(shExInfo.lpFile) + L"\""; + params = L"/" CMD_KEY_GENINST + CStringW(bSilentInstall ? L" /S" : L"") + + L" \"" + Info.szPackageName + L"\" \"" + shExInfo.lpFile + L"\""; shExInfo.lpParameters = params; shExInfo.lpFile = app.GetBuffer(MAX_PATH); GetModuleFileNameW(NULL, const_cast(shExInfo.lpFile), MAX_PATH); @@ -1086,6 +1109,30 @@ run: shExInfo.lpFile = app; } + if (bSilentInstall) + { + if (!Info.szSilentInstallArgs.IsEmpty()) + { + // The package wants to force specific parameters + shExInfo.lpParameters = Info.szSilentInstallArgs.GetString(); + } + else + { + UINT extrainfo = 0; + InstallerType it = Info.IExecType; + + if (it == INSTALLER_UNKNOWN || it == INSTALLER_EXEINZIP) + it = GuessInstallerType(shExInfo.lpFile, extrainfo); + + if (GetSilentInstallParameters(it, extrainfo, shExInfo.lpFile, params)) + { + shExInfo.lpParameters = params; + if (it == INSTALLER_MSI) + shExInfo.lpFile = L"msiexec.exe"; // params contains the .msi path + } + } + } + /* FIXME: Do we want to log installer status? */ WriteLogMessage(EVENTLOG_SUCCESS, MSG_SUCCESS_INSTALL, Info.szName); @@ -1142,19 +1189,19 @@ end: } BOOL -DownloadListOfApplications(const CAtlList &AppsList, BOOL bIsModal) +DownloadListOfApplications(const CAtlList &AppsList, UINT Flags) { if (AppsList.IsEmpty()) return FALSE; CComPtr pDM; - if (!CDownloadManager::CreateInstance(bIsModal, pDM)) + if (!CDownloadManager::CreateInstance(Flags, pDM)) return FALSE; for (POSITION it = AppsList.GetHeadPosition(); it;) { const CAppInfo *Info = AppsList.GetNext(it); - pDM->Add(DownloadInfo(*Info)); + pDM->Add(DownloadInfo(*Info, Flags)); } pDM->Show(); return TRUE; @@ -1163,21 +1210,19 @@ DownloadListOfApplications(const CAtlList &AppsList, BOOL bIsModal) BOOL DownloadApplication(CAppInfo *pAppInfo) { - const bool bModal = false; if (!pAppInfo) return FALSE; CAtlList list; list.AddTail(pAppInfo); - return DownloadListOfApplications(list, bModal); + return DownloadListOfApplications(list); } VOID DownloadApplicationsDB(LPCWSTR lpUrl, BOOL IsOfficial) { - const bool bModal = true; CComPtr pDM; - if (!CDownloadManager::CreateInstance(bModal, pDM)) + if (!CDownloadManager::CreateInstance(DAF_MODAL, pDM)) return; DownloadInfo DatabaseDLInfo; diff --git a/base/applications/rapps/misc.cpp b/base/applications/rapps/misc.cpp index 0965cc945d0..0b28ec09985 100644 --- a/base/applications/rapps/misc.cpp +++ b/base/applications/rapps/misc.cpp @@ -583,3 +583,123 @@ GetProgramFilesPath(CStringW &Path, BOOL PerUser, HWND hwnd) } return hr; } + +static BOOL +ReadAt(HANDLE Handle, UINT Offset, LPVOID Buffer, UINT Size) +{ + OVERLAPPED ol = {}; + ol.Offset = Offset; + DWORD cb; + return ReadFile(Handle, Buffer, Size, &cb, &ol) && cb == Size; +} + +InstallerType +GuessInstallerType(LPCWSTR Installer, UINT &ExtraInfo) +{ + ExtraInfo = 0; + InstallerType it = INSTALLER_UNKNOWN; + + HANDLE hFile = CreateFileW(Installer, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL); + if (hFile == INVALID_HANDLE_VALUE) + return it; + + BYTE buf[0x30 + 12]; + if (!ReadAt(hFile, 0, buf, sizeof(buf))) + goto done; + + if (buf[0] == 0xD0 && buf[1] == 0xCF && buf[2] == 0x11 && buf[3] == 0xE0) + { + if (!StrCmpIW(L".msi", PathFindExtensionW(Installer))) + { + it = INSTALLER_MSI; + goto done; + } + } + + if (buf[0] != 'M' || buf[1] != 'Z') + goto done; + + // <= Inno 5.1.4 + { + UINT sig[3]; + C_ASSERT(sizeof(buf) >= 0x30 + sizeof(sig)); + CopyMemory(sig, buf + 0x30, sizeof(sig)); + if (sig[0] == 0x6F6E6E49 && sig[1] == ~sig[2]) + { + it = INSTALLER_INNO; + ExtraInfo = 1; + goto done; + } + } + + // NSIS 1.6+ + { + UINT nsis[1+1+3+1+1], nsisskip = 512; + for (UINT nsisoffset = nsisskip * 20; nsisoffset < 1024 * 1024 * 50; nsisoffset += nsisskip) + { + if (ReadAt(hFile, nsisoffset, nsis, sizeof(nsis)) && nsis[1] == 0xDEADBEEF) + { + if (nsis[2] == 0x6C6C754E && nsis[3] == 0x74666F73 && nsis[4] == 0x74736E49) + { + it = INSTALLER_NSIS; + goto done; + } + } + } + } + + if (HMODULE hMod = LoadLibraryEx(Installer, NULL, LOAD_LIBRARY_AS_DATAFILE)) + { + // Inno + enum { INNORCSETUPLDR = 11111 }; + HGLOBAL hGlob; + HRSRC hRsrc = FindResourceW(hMod, MAKEINTRESOURCE(INNORCSETUPLDR), RT_RCDATA); + if (hRsrc && (hGlob = LoadResource(hMod, hRsrc)) != NULL) + { + if (BYTE *p = (BYTE*)LockResource(hGlob)) + { + if (p[0] == 'r' && p[1] == 'D' && p[2] == 'l' && p[3] == 'P' && p[4] == 't' && p[5] == 'S') + it = INSTALLER_INNO; + UnlockResource((void*)p); + } + } + FreeLibrary(hMod); + } +done: + CloseHandle(hFile); + return it; +} + +BOOL +GetSilentInstallParameters(InstallerType InstallerType, UINT ExtraInfo, LPCWSTR Installer, CStringW &Parameters) +{ + switch (InstallerType) + { + case INSTALLER_MSI: + { + Parameters.Format(L"/i \"%s\" /qn", Installer); + return TRUE; + } + + case INSTALLER_INNO: + { + LPCWSTR pszInnoParams = L"/SILENT /VERYSILENT /SP-"; + if (ExtraInfo) + Parameters.Format(L"%s", pszInnoParams); + else + Parameters.Format(L"%s /SUPPRESSMSGBOXES", pszInnoParams); // https://jrsoftware.org/files/is5.5-whatsnew.htm + return TRUE; + } + + case INSTALLER_NSIS: + { + Parameters = L"/S"; + return TRUE; + } + + default: + { + return FALSE; + } + } +} diff --git a/base/applications/rapps/unattended.cpp b/base/applications/rapps/unattended.cpp index fd115385638..0efd9b12c7b 100644 --- a/base/applications/rapps/unattended.cpp +++ b/base/applications/rapps/unattended.cpp @@ -62,6 +62,13 @@ SearchForAppWithDisplayName(CAppDB &db, AppsCategories Type, LPCWSTR Name) static BOOL HandleInstallCommand(CAppDB *db, LPWSTR szCommand, int argcLeft, LPWSTR *argvLeft) { + UINT flags = DAF_MODAL; + if (argcLeft >= 1 && !StrCmpIW(L"/S", argvLeft[0])) + { + flags |= DAF_SILENT; + argvLeft = &argvLeft[1], --argcLeft; + } + if (argcLeft < 1) { InitRappsConsole(); @@ -80,12 +87,19 @@ HandleInstallCommand(CAppDB *db, LPWSTR szCommand, int argcLeft, LPWSTR *argvLef } } - return DownloadListOfApplications(Applications, TRUE); + return DownloadListOfApplications(Applications, flags); } static BOOL HandleSetupCommand(CAppDB *db, LPWSTR szCommand, int argcLeft, LPWSTR *argvLeft) { + UINT flags = DAF_MODAL; + if (argcLeft >= 1 && !StrCmpIW(L"/S", argvLeft[0])) + { + flags |= DAF_SILENT; + argvLeft = &argvLeft[1], --argcLeft; + } + if (argcLeft != 1) { InitRappsConsole(); @@ -118,7 +132,7 @@ HandleSetupCommand(CAppDB *db, LPWSTR szCommand, int argcLeft, LPWSTR *argvLeft) } SetupCloseInfFile(InfHandle); - return DownloadListOfApplications(Applications, TRUE); + return DownloadListOfApplications(Applications, flags); } static BOOL @@ -200,6 +214,14 @@ HandleUninstallCommand(CAppDB &db, UINT argcLeft, LPWSTR *argvLeft) static BOOL HandleGenerateInstallerCommand(CAppDB &db, UINT argcLeft, LPWSTR *argvLeft) { + bool bSilent = false; + if (argcLeft && !StrCmpIW(argvLeft[0], L"/S")) + { + bSilent = true; + --argcLeft; + ++argvLeft; + } + if (argcLeft != 2) return FALSE; @@ -207,7 +229,7 @@ HandleGenerateInstallerCommand(CAppDB &db, UINT argcLeft, LPWSTR *argvLeft) if (!pAI) return FALSE; - return ExtractAndRunGeneratedInstaller(*pAI, argvLeft[1]); + return ExtractAndRunGeneratedInstaller(*pAI, argvLeft[1], bSilent); } static BOOL