Skip to content
This repository has been archived by the owner on Jul 5, 2024. It is now read-only.

Commit

Permalink
Better setup error dialogs; Show error when installing on Win7 and lo…
Browse files Browse the repository at this point in the history
…wer.
  • Loading branch information
caesay committed Feb 18, 2022
1 parent 2ec46e7 commit 2c01e19
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 14 deletions.
57 changes: 43 additions & 14 deletions src/Setup/Setup.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <windows.h>
#include <versionhelpers.h>
#include <string>
#include <functional>
#include <tchar.h>
Expand All @@ -21,12 +22,10 @@ wstring getTempExePath()
BYTE* getByteResource(int idx, DWORD* cBuf)
{
auto f = FindResource(NULL, MAKEINTRESOURCE(idx), L"DATA");
if (!f)
throw std::exception(string("Unable to find resource " + to_string(idx)).c_str());
if (!f) throw wstring(L"Unable to find resource " + to_wstring(idx));

auto r = LoadResource(NULL, f);
if (!r)
throw std::exception(string("Unable to load resource " + to_string(idx)).c_str());
if (!r) throw wstring(L"Unable to load resource " + to_wstring(idx));

*cBuf = SizeofResource(NULL, f);
return (BYTE*)LockResource(r);
Expand All @@ -40,6 +39,17 @@ wstring getCurrentExecutablePath()
return wstring(ourFile);
}

wstring getNameFromPath(wstring path)
{
auto idx = path.find_last_of('\\');

// if we can't find last \ or the name is too short, default to 'Setup'
if (idx == wstring::npos || path.length() < idx + 3)
return L"Setup";

return path.substr(idx + 1);
}

// https://stackoverflow.com/a/874160/184746
bool hasEnding(std::wstring const& fullString, std::wstring const& ending)
{
Expand Down Expand Up @@ -77,7 +87,7 @@ void unzipSingleFile(BYTE* zipBuf, DWORD cZipBuf, wstring fileLocation, std::fun

CloseZip(zipFile);

if (!unzipSuccess) throw std::exception("Unable to extract embedded package");
if (!unzipSuccess) throw wstring(L"Unable to extract embedded package (predicate not found).");
}

// https://stackoverflow.com/a/17387176/184746
Expand All @@ -88,12 +98,12 @@ void throwLastWin32Error()
return;
}

LPSTR messageBuffer = nullptr;
size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);
LPWSTR messageBuffer = nullptr;
size_t size = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&messageBuffer, 0, NULL);

std::string message(messageBuffer, size);
throw std::exception(message.c_str());
std::wstring message(messageBuffer, size);
throw message;
}

void wexec(const wchar_t* cmd)
Expand Down Expand Up @@ -121,12 +131,25 @@ void wexec(const wchar_t* cmd)
CloseHandle(pi.hThread);

if (dwExitCode != 0) {
throw std::exception(string("Process exited with error code: " + to_string(dwExitCode)).c_str());
throw wstring(L"Process exited with error code: " + to_wstring(dwExitCode));
}
}

int showErrorDialog(wstring msg)
{
wstring myPath = getCurrentExecutablePath();
wstring myName = getNameFromPath(myPath);
wstring errorTitle = myName + L" Error";
MessageBox(0, msg.c_str(), errorTitle.c_str(), MB_OK | MB_ICONERROR);
return -1;
}

int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ PWSTR pCmdLine, _In_ int nCmdShow)
{
if (!IsWindows7SP1OrGreater()) {
return showErrorDialog(L"This application requires Windows 7 SP1 or later and cannot be installed on this computer.");
}

wstring myPath = getCurrentExecutablePath();
wstring updaterPath = getTempExePath();

Expand All @@ -145,15 +168,21 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
wstring cmd = L"\"" + updaterPath + L"\" --setup \"" + myPath + L"\" " + pCmdLine;
wexec(cmd.c_str());
}
catch (wstring wsx) {
return showErrorDialog(L"An error occurred while running setup: " + wsx + L". Please contact the application author.");
}
catch (std::exception ex) {
// nasty shit to convert from ascii to wide-char. this will fail if there are multi-byte characters.
// hopefully we remember to throw 'wstring' everywhere instead of 'exception' and it doesn't matter.
string msg = ex.what();
// just use the _A function because std does not have a wexception
MessageBoxA(0, string("An error occurred while running setup: " + msg + ". Please contact the application author.").c_str(), "Setup Error", MB_OK | MB_ICONERROR);
wstring wsTmp(msg.begin(), msg.end());
return showErrorDialog(L"An error occurred while running setup: " + wsTmp + L". Please contact the application author.");
}
catch (...) {
MessageBox(0, L"An unknown error occurred while running setup. Please contact the application author.", L"Setup Error", MB_OK | MB_ICONERROR);
return showErrorDialog(L"An unknown error occurred while running setup. Please contact the application author.");
}

// clean-up after ourselves
DeleteFile(updaterPath.c_str());
return 0;
}
9 changes: 9 additions & 0 deletions src/Setup/Setup.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<Manifest>
<AdditionalManifestFiles>compatibility.manifest</AdditionalManifestFiles>
</Manifest>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
Expand All @@ -79,6 +82,9 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<Manifest>
<AdditionalManifestFiles>compatibility.manifest</AdditionalManifestFiles>
</Manifest>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="Setup.cpp" />
Expand All @@ -87,6 +93,9 @@
<ItemGroup>
<ClInclude Include="unzip.h" />
</ItemGroup>
<ItemGroup>
<Text Include="compatibility.manifest" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
Expand Down
5 changes: 5 additions & 0 deletions src/Setup/Setup.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,9 @@
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Text Include="compatibility.manifest">
<Filter>Resource Files</Filter>
</Text>
</ItemGroup>
</Project>
41 changes: 41 additions & 0 deletions src/Setup/compatibility.manifest
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

<!-- Indicate our support for newer versions so windows stops lying to us -->
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- Windows 10 and Windows 11 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
<!-- Windows 8.1 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<!-- Windows 8 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
<!-- Windows 7 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!-- Windows Vista -->
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
</application>
</compatibility>

<!-- Enable themes for Windows common controls and dialogs (Windows XP and later) -->
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>

<!-- Disable legacy dpi / bitmap scaling -->
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">True</dpiAware>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
</windowsSettings>
</application>

</assembly>

0 comments on commit 2c01e19

Please sign in to comment.