Merge remote-tracking branch 'origin/pr/114'

This commit is contained in:
Paul Betts
2014-10-29 11:54:52 -07:00
9 changed files with 237 additions and 38 deletions

View File

@@ -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

View File

@@ -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;
}

View File

@@ -4,6 +4,6 @@ class CFxHelper
{
public:
static bool IsDotNet45OrHigherInstalled();
static void HelpUserInstallDotNetFramework(bool isQuiet);
static HRESULT InstallDotNetFramework(bool isQuiet);
};

Binary file not shown.

View File

@@ -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>

View File

@@ -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;
}
}

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -134,4 +134,4 @@
<Target Name="AfterBuild">
</Target>
-->
</Project>
</Project>