mirror of
https://github.com/winscp/winscp.git
synced 2026-10-24 02:28:55 +03:00
Bug 83: MSI installation package
https://winscp.net/tracker/83 Source commit: 599e90f2406250f67542a77f1594218f68a7ac67
This commit is contained in:
@@ -60,6 +60,10 @@ Currency=USD
|
||||
ImportSites=Looking for sites to import...
|
||||
AcceptButton=&Accept
|
||||
IncompleteTranslation=You are about to use an incomplete translation. It is completed by %1%% only.%n%nUntranslated parts of the user interface will be shown in their original English version.%n%nVisit WinSCP website at winscp.net to check, if newer version of the translation is available.
|
||||
MsiInstallation=WinSCP is already installed on this system using an MSI installer. Please uninstall that before running this standalone executable installer.
|
||||
|
||||
; MSI (sic)
|
||||
InnoSetupInstallation=WinSCP is already installed on this system using a standalone executable installer. Please uninstall that before running this MSI installer.
|
||||
|
||||
[CustomOptions]
|
||||
TranslationCompleteness=100
|
||||
|
||||
@@ -809,6 +809,13 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
if IsMsiProductInstalled('{029F9450-CFEF-4408-A2BB-B69ECE29EB18}', 0) and
|
||||
(not CmdLineParamExists('/OverrideMsi')) then
|
||||
begin
|
||||
MsgBox(CustomMessage('MsiInstallation'), mbError, MB_OK);
|
||||
Abort;
|
||||
end;
|
||||
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Base)'!=''">
|
||||
<_TCHARMapping>wchar_t</_TCHARMapping>
|
||||
<AllPackageLibs>vcl.lib;rtl.lib;vclx.lib;ws2_32.lib;secur32.lib;My.lib;DriveDir.lib;DragDropP.lib;tb2k.lib;tbxp.lib;bcbie.lib;Crypt32.lib;PngComponents.lib;xmlrtl.lib;vclactnband.lib;vclimg.lib;winhttp.lib;jcl.lib;vclie.lib;urlmon.lib;shlwapi.lib;powrprof.lib;soaprtl.lib;fmx.lib;dbrtl.lib;inet.lib;psapi.lib</AllPackageLibs>
|
||||
<AllPackageLibs>vcl.lib;rtl.lib;vclx.lib;ws2_32.lib;secur32.lib;My.lib;DriveDir.lib;DragDropP.lib;tb2k.lib;tbxp.lib;bcbie.lib;Crypt32.lib;PngComponents.lib;xmlrtl.lib;vclactnband.lib;vclimg.lib;winhttp.lib;jcl.lib;vclie.lib;urlmon.lib;shlwapi.lib;powrprof.lib;soaprtl.lib;fmx.lib;dbrtl.lib;inet.lib;psapi.lib;msi.lib</AllPackageLibs>
|
||||
<BCC_AllWarnings>true</BCC_AllWarnings>
|
||||
<BCC_ExtendedErrorInfo>true</BCC_ExtendedErrorInfo>
|
||||
<BCC_OptimizeForSpeed>true</BCC_OptimizeForSpeed>
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <Soap.HTTPUtil.hpp>
|
||||
#include <Web.HTTPApp.hpp>
|
||||
#include <System.IOUtils.hpp>
|
||||
#include <WinApi.h>
|
||||
//---------------------------------------------------------------------------
|
||||
#define KEY _T("SYSTEM\\CurrentControlSet\\Control\\") \
|
||||
_T("Session Manager\\Environment")
|
||||
@@ -805,11 +806,12 @@ UnicodeString __fastcall ProgramUrl(UnicodeString URL)
|
||||
FORMAT(L"%d.%d.%d.%d",
|
||||
(HIWORD(FileInfo->dwFileVersionMS), LOWORD(FileInfo->dwFileVersionMS),
|
||||
HIWORD(FileInfo->dwFileVersionLS), LOWORD(FileInfo->dwFileVersionLS)));
|
||||
int IsInstalledFlag = (IsInstalled() ? 1 : (IsInstalledMsi() ? 2 : 0));
|
||||
UnicodeString Params =
|
||||
FORMAT(L"v=%s&lang=%s&isinstalled=%d",
|
||||
(CurrentVersionStr,
|
||||
GUIConfiguration->AppliedLocaleHex,
|
||||
int(IsInstalled())));
|
||||
IsInstalledFlag));
|
||||
|
||||
if (Configuration->IsUnofficial)
|
||||
{
|
||||
@@ -1983,6 +1985,12 @@ bool __fastcall AnyOtherInstanceOfSelf()
|
||||
return Result;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
static bool DoIsPathToExe(const UnicodeString & Path)
|
||||
{
|
||||
UnicodeString ExePath = ExcludeTrailingBackslash(ExtractFilePath(Application->ExeName));
|
||||
return IsPathToSameFile(ExePath, Path);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
static bool __fastcall DoIsInstalled(HKEY RootKey)
|
||||
{
|
||||
std::unique_ptr<TRegistry> Registry(new TRegistry(KEY_READ));
|
||||
@@ -1992,21 +2000,52 @@ static bool __fastcall DoIsInstalled(HKEY RootKey)
|
||||
if (Result)
|
||||
{
|
||||
UnicodeString InstallPath = ExcludeTrailingBackslash(Registry->ReadString(L"Inno Setup: App Path"));
|
||||
UnicodeString ExePath = ExcludeTrailingBackslash(ExtractFilePath(Application->ExeName));
|
||||
Result =
|
||||
!InstallPath.IsEmpty() &&
|
||||
IsPathToSameFile(ExePath, InstallPath);
|
||||
DoIsPathToExe(InstallPath);
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
bool __fastcall IsInstalled()
|
||||
bool IsInstalled()
|
||||
{
|
||||
return
|
||||
DoIsInstalled(HKEY_LOCAL_MACHINE) ||
|
||||
DoIsInstalled(HKEY_CURRENT_USER);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
static int GIsInstalledMsi = -1;
|
||||
bool IsInstalledMsi()
|
||||
{
|
||||
if (GIsInstalledMsi < 0)
|
||||
{
|
||||
GIsInstalledMsi = 0;
|
||||
wchar_t ProductCode[MAX_GUID_CHARS + 1];
|
||||
if (MsiEnumRelatedProducts(L"{029F9450-CFEF-4408-A2BB-B69ECE29EB18}", 0, 0, ProductCode) == ERROR_SUCCESS)
|
||||
{
|
||||
UnicodeString InstallPath;
|
||||
InstallPath.SetLength(MAX_PATH);
|
||||
unsigned long Size = InstallPath.Length() + 1;
|
||||
int ErrorCode = MsiGetProductInfo(ProductCode, INSTALLPROPERTY_INSTALLLOCATION, InstallPath.c_str(), &Size);
|
||||
if (ErrorCode == ERROR_MORE_DATA)
|
||||
{
|
||||
InstallPath.SetLength(Size);
|
||||
Size++;
|
||||
ErrorCode = MsiGetProductInfo(ProductCode, INSTALLPROPERTY_INSTALLLOCATION, InstallPath.c_str(), &Size);
|
||||
}
|
||||
if (ErrorCode == ERROR_SUCCESS)
|
||||
{
|
||||
InstallPath.SetLength(Size);
|
||||
if (DoIsPathToExe(InstallPath))
|
||||
{
|
||||
GIsInstalledMsi = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return (GIsInstalledMsi > 0);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
static TStringList * __fastcall TextToTipList(const UnicodeString & Text)
|
||||
{
|
||||
std::unique_ptr<TStringList> List(new TStringList());
|
||||
|
||||
@@ -25,7 +25,8 @@ void __fastcall StopUpdateThread();
|
||||
UnicodeString __fastcall CampaignUrl(UnicodeString URL);
|
||||
void __fastcall UpdateJumpList(TStrings * SessionNames, TStrings * WorkspaceNames);
|
||||
bool __fastcall AnyOtherInstanceOfSelf();
|
||||
bool __fastcall IsInstalled();
|
||||
bool IsInstalled();
|
||||
bool IsInstalledMsi();
|
||||
UnicodeString __fastcall ProgramUrl(UnicodeString URL);
|
||||
void __fastcall AutoShowNewTip();
|
||||
bool __fastcall AnyTips();
|
||||
|
||||
@@ -192,4 +192,24 @@ public:
|
||||
#define SES_EX_HANDLEFRIENDLYURL (0x100)
|
||||
//---------------------------------------------------------------------------
|
||||
//---------------------------------------------------------------------------
|
||||
// msi.h (available, but does not compile)
|
||||
extern "C"
|
||||
{
|
||||
#define MAX_GUID_CHARS 38
|
||||
#define INSTALLPROPERTY_INSTALLLOCATION __TEXT("InstallLocation")
|
||||
UINT WINAPI MsiEnumRelatedProductsW(
|
||||
__in LPCWSTR lpUpgradeCode, // upgrade code of products to enumerate
|
||||
__reserved DWORD dwReserved, // reserved, must be 0
|
||||
__in DWORD iProductIndex, // 0-based index into registered products
|
||||
__out_ecount(MAX_GUID_CHARS+1) LPWSTR lpProductBuf); // buffer of char count: 39 (size of string GUID)
|
||||
#define MsiEnumRelatedProducts MsiEnumRelatedProductsW
|
||||
//---------------------------------------------------------------------------
|
||||
UINT WINAPI MsiGetProductInfoW(
|
||||
__in LPCWSTR szProduct, // product code
|
||||
__in LPCWSTR szAttribute, // attribute name, case-sensitive
|
||||
__out_ecount_opt(*pcchValueBuf) LPWSTR lpValueBuf, // returned value, NULL if not desired
|
||||
__inout_opt LPDWORD pcchValueBuf); // in/out buffer character count
|
||||
#define MsiGetProductInfo MsiGetProductInfoW
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
#endif // WinApiH
|
||||
|
||||
@@ -603,6 +603,7 @@ void __fastcall UpdateStaticUsage()
|
||||
bool InProgramFiles = AnsiSameText(ExeName.SubString(1, ProgramsFolder.Length()), ProgramsFolder);
|
||||
Configuration->Usage->Set(L"InProgramFiles", InProgramFiles);
|
||||
Configuration->Usage->Set(L"IsInstalled", IsInstalled());
|
||||
Configuration->Usage->Set(L"IsInstalledMsi", IsInstalledMsi());
|
||||
Configuration->Usage->Set(L"Wine", IsWine());
|
||||
Configuration->Usage->Set(L"NetFrameworkVersion", GetNetVersionStr());
|
||||
Configuration->Usage->Set(L"NetCoreVersion", GetNetCoreVersionStr());
|
||||
|
||||
Reference in New Issue
Block a user