mirror of
https://github.com/velopack/velopack.git
synced 2025-10-25 15:19:22 +00:00
Merge remote-tracking branch 'origin/pr/114'
This commit is contained in:
@@ -18,7 +18,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Update", "src\Update\Update
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SyncGitHubReleases", "src\SyncGitHubReleases\SyncGitHubReleases.csproj", "{EB521191-1EBF-4D06-8541-ED192E2EE378}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "misc", "misc", "{ED657D2C-F8A0-4012-A64F-7367D41BE4D2}"
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SolutionLevel", "SolutionLevel", "{ED657D2C-F8A0-4012-A64F-7367D41BE4D2}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
src\SolutionAssemblyInfo.cs = src\SolutionAssemblyInfo.cs
|
||||
src\Squirrel.nuspec = src\Squirrel.nuspec
|
||||
|
||||
@@ -10,45 +10,237 @@ bool CFxHelper::IsDotNet45OrHigherInstalled()
|
||||
{
|
||||
ATL::CRegKey key;
|
||||
|
||||
return false;
|
||||
|
||||
if (key.Open(HKEY_LOCAL_MACHINE, ndpPath, KEY_READ) != ERROR_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DWORD dwReleaseInfo = 0;
|
||||
if (key.QueryDWORDValue(L"Release", dwReleaseInfo) != ERROR_SUCCESS ||
|
||||
dwReleaseInfo < fx45ReleaseVersion) {
|
||||
dwReleaseInfo < fx45ReleaseVersion) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void CFxHelper::HelpUserInstallDotNetFramework(bool isQuiet)
|
||||
class ATL_NO_VTABLE CDownloadProgressCallback :
|
||||
public CComObjectRoot,
|
||||
public IBindStatusCallback
|
||||
{
|
||||
if (isQuiet) return;
|
||||
|
||||
CTaskDialog dlg;
|
||||
TASKDIALOG_BUTTON buttons [] = {
|
||||
{ 1, L"Install", },
|
||||
{ 2, L"Cancel", },
|
||||
};
|
||||
|
||||
dlg.SetButtons(buttons, 2);
|
||||
dlg.SetMainInstructionText(L"Install .NET 4.5");
|
||||
dlg.SetContentText(L"This application requires the .NET Framework 4.5. Click the Install button to get started.");
|
||||
dlg.SetMainIcon(TD_INFORMATION_ICON);
|
||||
|
||||
dlg.SetExpandedInformationText(
|
||||
L"This application requires .NET Framework 4.5 or above. Click\n"
|
||||
L"the 'Install' button in order to navigate to a website which\n"
|
||||
L"will help you to install the latest version of .NET");
|
||||
|
||||
int nButton;
|
||||
if (SUCCEEDED(dlg.DoModal(::GetActiveWindow(), &nButton)) && nButton == 1) {
|
||||
CString url;
|
||||
url.LoadString(IDS_FXDOWNLOADURL);
|
||||
|
||||
ShellExecute(NULL, NULL, url, NULL, NULL, SW_SHOW);
|
||||
public:
|
||||
CDownloadProgressCallback()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_NOT_AGGREGATABLE(CDownloadProgressCallback)
|
||||
|
||||
BEGIN_COM_MAP(CDownloadProgressCallback)
|
||||
COM_INTERFACE_ENTRY(IBindStatusCallback)
|
||||
END_COM_MAP()
|
||||
|
||||
DECLARE_PROTECT_FINAL_CONSTRUCT()
|
||||
|
||||
HRESULT FinalConstruct()
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void FinalRelease()
|
||||
{
|
||||
}
|
||||
|
||||
void SetProgressDialog(IProgressDialog* pd)
|
||||
{
|
||||
m_spProgressDialog = pd;
|
||||
}
|
||||
|
||||
STDMETHOD(OnStartBinding)(DWORD /*dwReserved*/, IBinding *pBinding)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHOD(GetPriority)(LONG *pnPriority)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHOD(OnLowResource)(DWORD /*reserved*/)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHOD(OnProgress)(ULONG ulProgress, ULONG ulProgressMax, ULONG /*ulStatusCode*/, LPCWSTR /*szStatusText*/)
|
||||
{
|
||||
if (m_spProgressDialog != nullptr) {
|
||||
if (m_spProgressDialog->HasUserCancelled()) {
|
||||
return E_ABORT;
|
||||
}
|
||||
|
||||
m_spProgressDialog->SetProgress(ulProgress, ulProgressMax);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHOD(OnStopBinding)(HRESULT /*hresult*/, LPCWSTR /*szError*/)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHOD(GetBindInfo)(DWORD *pgrfBINDF, BINDINFO *pbindInfo)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHOD(OnDataAvailable)(DWORD grfBSCF, DWORD dwSize, FORMATETC * /*pformatetc*/, STGMEDIUM *pstgmed)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHOD(OnObjectAvailable)(REFIID /*riid*/, IUnknown * /*punk*/)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
private:
|
||||
CComPtr<IProgressDialog> m_spProgressDialog;
|
||||
};
|
||||
|
||||
HRESULT CFxHelper::InstallDotNetFramework(bool isQuiet)
|
||||
{
|
||||
if (!isQuiet) {
|
||||
CTaskDialog dlg;
|
||||
TASKDIALOG_BUTTON buttons [] = {
|
||||
{ 1, L"Install", },
|
||||
{ 2, L"Cancel", },
|
||||
};
|
||||
|
||||
dlg.SetButtons(buttons, 2);
|
||||
dlg.SetMainInstructionText(L"Install .NET 4.5");
|
||||
dlg.SetContentText(L"This application requires the .NET Framework 4.5. Click the Install button to get started.");
|
||||
dlg.SetMainIcon(TD_INFORMATION_ICON);
|
||||
|
||||
dlg.SetExpandedInformationText(
|
||||
L"This application requires .NET Framework 4.5 or above. Clicking "
|
||||
L"the Install button will download the latest version of this operating "
|
||||
L"system component from Microsoft and install it on your PC.");
|
||||
|
||||
int nButton;
|
||||
if (FAILED(dlg.DoModal(::GetActiveWindow(), &nButton)) || nButton != 1) {
|
||||
return S_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT hr = E_FAIL;
|
||||
WCHAR szFinalTempFileName[_MAX_PATH] = L"";
|
||||
CComPtr<IBindStatusCallback> bscb;
|
||||
CComPtr<IProgressDialog> pd;
|
||||
SHELLEXECUTEINFO execInfo = {sizeof(execInfo),};
|
||||
|
||||
CString url;
|
||||
url.LoadString(IDS_FXDOWNLOADURL);
|
||||
|
||||
WCHAR szTempPath[_MAX_PATH];
|
||||
DWORD dwTempPathResult = GetTempPath(_MAX_PATH, szTempPath);
|
||||
|
||||
if (dwTempPathResult == 0) {
|
||||
hr = AtlHresultFromLastError();
|
||||
goto out;
|
||||
} else if (dwTempPathResult > _MAX_PATH) {
|
||||
hr = DISP_E_BUFFERTOOSMALL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
WCHAR szTempFileName[_MAX_PATH];
|
||||
if (!GetTempFileName(szTempPath, L"NDP", 0, szTempFileName)) {
|
||||
hr = AtlHresultFromLastError();
|
||||
goto out;
|
||||
}
|
||||
|
||||
szTempFileName[_countof(szTempFileName) - 1] = L'\0';
|
||||
if (wcscpy_s(szFinalTempFileName, _countof(szFinalTempFileName), szTempFileName) != 0) {
|
||||
hr = E_FAIL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
WCHAR* pLastDot = wcsrchr(szFinalTempFileName, L'.');
|
||||
if (pLastDot == nullptr) {
|
||||
if (wcscat_s(szFinalTempFileName, _countof(szFinalTempFileName), L".exe") != 0) {
|
||||
hr = E_FAIL;
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
if (wcscpy_s(szFinalTempFileName, _countof(szFinalTempFileName) - (pLastDot - szFinalTempFileName), L".exe") != 0) {
|
||||
hr = E_FAIL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (!MoveFile(szTempFileName, szFinalTempFileName)) {
|
||||
hr = AtlHresultFromLastError();
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!isQuiet) {
|
||||
pd.CoCreateInstance(CLSID_ProgressDialog);
|
||||
|
||||
if (pd != nullptr) {
|
||||
pd->SetTitle(L"Downloading");
|
||||
pd->SetLine(1, L"Downloading the .NET Framework installer", FALSE, nullptr);
|
||||
pd->StartProgressDialog(nullptr, nullptr, 0, nullptr);
|
||||
|
||||
CComObject<CDownloadProgressCallback>* bscbObj = nullptr;
|
||||
if (SUCCEEDED(CComObject<CDownloadProgressCallback>::CreateInstance(&bscbObj))) {
|
||||
bscbObj->SetProgressDialog(pd);
|
||||
bscb = bscbObj;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hr = URLDownloadToFile(nullptr, url, szFinalTempFileName, 0, bscb);
|
||||
if (pd != nullptr) {
|
||||
pd->StopProgressDialog();
|
||||
}
|
||||
if (hr != S_OK) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
execInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
|
||||
execInfo.lpVerb = L"open";
|
||||
execInfo.lpFile = szFinalTempFileName;
|
||||
|
||||
if (isQuiet) {
|
||||
execInfo.lpParameters = L"/q /norestart";
|
||||
} else {
|
||||
execInfo.lpParameters = L"/passive /norestart /showrmui";
|
||||
}
|
||||
|
||||
execInfo.nShow = SW_SHOW;
|
||||
if (!ShellExecuteEx(&execInfo)) {
|
||||
hr = AtlHresultFromLastError();
|
||||
goto out;
|
||||
}
|
||||
|
||||
WaitForSingleObject(execInfo.hProcess, INFINITE);
|
||||
|
||||
DWORD exitCode;
|
||||
if (!GetExitCodeProcess(execInfo.hProcess, &exitCode)) {
|
||||
hr = AtlHresultFromLastError();
|
||||
goto out;
|
||||
}
|
||||
|
||||
hr = exitCode != 0 ? E_FAIL : S_OK;
|
||||
|
||||
out:
|
||||
if (execInfo.hProcess != NULL && execInfo.hProcess != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(execInfo.hProcess);
|
||||
}
|
||||
|
||||
if (*szFinalTempFileName != L'\0') {
|
||||
DeleteFile(szFinalTempFileName);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,6 @@ class CFxHelper
|
||||
{
|
||||
public:
|
||||
static bool IsDotNet45OrHigherInstalled();
|
||||
static void HelpUserInstallDotNetFramework(bool isQuiet);
|
||||
static HRESULT InstallDotNetFramework(bool isQuiet);
|
||||
};
|
||||
|
||||
|
||||
Binary file not shown.
@@ -83,6 +83,7 @@
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;urlmon.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<Manifest>
|
||||
<AdditionalManifestFiles>compat.manifest</AdditionalManifestFiles>
|
||||
@@ -107,6 +108,7 @@
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<UACExecutionLevel>AsInvoker</UACExecutionLevel>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;urlmon.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<Manifest>
|
||||
<AdditionalManifestFiles>compat.manifest</AdditionalManifestFiles>
|
||||
@@ -131,6 +133,7 @@
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<UACExecutionLevel>AsInvoker</UACExecutionLevel>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;urlmon.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<Manifest>
|
||||
<AdditionalManifestFiles>compat.manifest</AdditionalManifestFiles>
|
||||
|
||||
@@ -17,7 +17,6 @@ void CUpdateRunner::DisplayErrorMessage(CString& errorMessage, wchar_t* logFile)
|
||||
dlg.SetMainInstructionText(L"Installation has failed");
|
||||
dlg.SetContentText(errorMessage);
|
||||
dlg.SetMainIcon(TD_ERROR_ICON);
|
||||
dlg.EnableButton(1, logFile != NULL);
|
||||
|
||||
int nButton;
|
||||
|
||||
@@ -115,7 +114,8 @@ int CUpdateRunner::ExtractUpdaterAndRun(wchar_t* lpCommandLine)
|
||||
}
|
||||
|
||||
if (dwExitCode != 0) {
|
||||
DisplayErrorMessage(CString(L"There was an error while installing the application. "
|
||||
DisplayErrorMessage(CString(
|
||||
L"There was an error while installing the application. "
|
||||
L"Check the setup log for more information and contact the author."), logFile);
|
||||
}
|
||||
|
||||
@@ -130,4 +130,4 @@ int CUpdateRunner::ExtractUpdaterAndRun(wchar_t* lpCommandLine)
|
||||
failedExtract:
|
||||
DisplayErrorMessage(CString(L"Failed to extract installer"), NULL);
|
||||
return (int) dwExitCode;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
// Windows Header Files:
|
||||
#include <windows.h>
|
||||
#include <shellapi.h>
|
||||
#include <shlobj.h>
|
||||
#include <urlmon.h>
|
||||
|
||||
// C RunTime Header Files
|
||||
#include <stdlib.h>
|
||||
@@ -33,4 +35,4 @@
|
||||
#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
|
||||
#else
|
||||
#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -24,8 +24,10 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
|
||||
bool isQuiet = (cmdLine.Find(L"/quiet") >= 0);
|
||||
|
||||
if (!CFxHelper::IsDotNet45OrHigherInstalled()) {
|
||||
CFxHelper::HelpUserInstallDotNetFramework(isQuiet);
|
||||
goto out;
|
||||
hr = CFxHelper::InstallDotNetFramework(isQuiet);
|
||||
if (hr != S_OK) {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
exitCode = CUpdateRunner::ExtractUpdaterAndRun(lpCmdLine);
|
||||
@@ -34,4 +36,4 @@ out:
|
||||
_Module.Term();
|
||||
::CoUninitialize();
|
||||
return exitCode;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,4 +134,4 @@
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
Reference in New Issue
Block a user