[RAPPS] Added /S switch for silent installs (#8241)

MSI, Inno and NSIS installers are automatically detected (also if they are nested by ExeInZip). Others can specify command line switches in the rapps-db package.
This commit is contained in:
Whindmar Saksit
2025-08-29 15:18:55 +02:00
committed by GitHub
parent 47d6b3ae12
commit 8ce870d87b
36 changed files with 301 additions and 65 deletions
+33 -3
View File
@@ -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)
+2 -1
View File
@@ -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;
}
+1 -1
View File
@@ -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);
+16 -9
View File
@@ -4,7 +4,6 @@
#include <atlpath.h>
#include <atlsimpcoll.h>
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);
+5 -1
View File
@@ -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<CAppInfo *> &AppsList, BOOL bIsModal);
DownloadListOfApplications(const CAtlList<CAppInfo *> &AppsList, UINT Flags = 0);
+7
View File
@@ -1,6 +1,7 @@
#pragma once
#include <atlstr.h>
#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);
+2 -2
View File
@@ -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]";
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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"
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+64 -19
View File
@@ -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<const CAvailableApplicationInfo&>(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<CDownloadManager> 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<DownloadInfo> 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<LPWSTR>(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<CAppInfo *> &AppsList, BOOL bIsModal)
DownloadListOfApplications(const CAtlList<CAppInfo *> &AppsList, UINT Flags)
{
if (AppsList.IsEmpty())
return FALSE;
CComPtr<CDownloadManager> 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<CAppInfo *> &AppsList, BOOL bIsModal)
BOOL
DownloadApplication(CAppInfo *pAppInfo)
{
const bool bModal = false;
if (!pAppInfo)
return FALSE;
CAtlList<CAppInfo*> list;
list.AddTail(pAppInfo);
return DownloadListOfApplications(list, bModal);
return DownloadListOfApplications(list);
}
VOID
DownloadApplicationsDB(LPCWSTR lpUrl, BOOL IsOfficial)
{
const bool bModal = true;
CComPtr<CDownloadManager> pDM;
if (!CDownloadManager::CreateInstance(bModal, pDM))
if (!CDownloadManager::CreateInstance(DAF_MODAL, pDM))
return;
DownloadInfo DatabaseDLInfo;
+120
View File
@@ -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;
}
}
}
+25 -3
View File
@@ -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