mirror of https://github.com/OpenRCT2/OpenRCT2.git
Merge pull request #3374 from IntelOrca/feature/file-associations
Register file associations on Windows
This commit is contained in:
commit
571907eabb
|
@ -58,6 +58,19 @@ static exitcode_t HandleCommandHost(CommandLineArgEnumerator * enumerator);
|
|||
static exitcode_t HandleCommandJoin(CommandLineArgEnumerator * enumerator);
|
||||
static exitcode_t HandleCommandSetRCT2(CommandLineArgEnumerator * enumerator);
|
||||
|
||||
#if defined(__WINDOWS__) && !defined(__MINGW32__)
|
||||
|
||||
static bool _removeShell = false;
|
||||
|
||||
static const CommandLineOptionDefinition RegisterShellOptions[]
|
||||
{
|
||||
{ CMDLINE_TYPE_SWITCH, &_removeShell, 'd', "remove", "remove shell integration" },
|
||||
};
|
||||
|
||||
static exitcode_t HandleCommandRegisterShell(CommandLineArgEnumerator * enumerator);
|
||||
|
||||
#endif
|
||||
|
||||
static void PrintAbout();
|
||||
static void PrintVersion();
|
||||
static void PrintLaunchInformation();
|
||||
|
@ -74,6 +87,10 @@ const CommandLineCommand CommandLine::RootCommands[]
|
|||
#endif
|
||||
DefineCommand("set-rct2", "<path>", StandardOptions, HandleCommandSetRCT2),
|
||||
|
||||
#if defined(__WINDOWS__) && !defined(__MINGW32__)
|
||||
DefineCommand("register-shell", "", RegisterShellOptions, HandleCommandRegisterShell),
|
||||
#endif
|
||||
|
||||
// Sub-commands
|
||||
DefineSubCommand("screenshot", CommandLine::ScreenshotCommands),
|
||||
DefineSubCommand("sprite", CommandLine::SpriteCommands ),
|
||||
|
@ -321,6 +338,27 @@ static exitcode_t HandleCommandSetRCT2(CommandLineArgEnumerator * enumerator)
|
|||
}
|
||||
}
|
||||
|
||||
#if defined(__WINDOWS__) && !defined(__MINGW32__)
|
||||
static exitcode_t HandleCommandRegisterShell(CommandLineArgEnumerator * enumerator)
|
||||
{
|
||||
exitcode_t result = CommandLine::HandleCommandDefault();
|
||||
if (result != EXITCODE_CONTINUE)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (!_removeShell)
|
||||
{
|
||||
platform_setup_file_associations();
|
||||
}
|
||||
else
|
||||
{
|
||||
platform_remove_file_associations();
|
||||
}
|
||||
return EXITCODE_OK;
|
||||
}
|
||||
#endif // defined(__WINDOWS__) && !defined(__MINGW32__)
|
||||
|
||||
static void PrintAbout()
|
||||
{
|
||||
PrintVersion();
|
||||
|
|
|
@ -197,6 +197,8 @@ datetime64 platform_get_datetime_now_utc();
|
|||
|
||||
int windows_get_registry_install_info(rct2_install_info *installInfo, char *source, char *font, uint8 charset);
|
||||
HWND windows_get_window_handle();
|
||||
void platform_setup_file_associations();
|
||||
void platform_remove_file_associations();
|
||||
#endif // __WINDOWS__
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1035,4 +1035,147 @@ utf8* platform_get_username() {
|
|||
return username;
|
||||
}
|
||||
|
||||
#ifndef __MINGW32__
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// File association setup
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define SOFTWARE_CLASSES L"Software\\Classes"
|
||||
|
||||
static void get_progIdName(wchar_t *dst, const utf8 *extension)
|
||||
{
|
||||
utf8 progIdName[128];
|
||||
safe_strcpy(progIdName, OPENRCT2_NAME, sizeof(progIdName));
|
||||
safe_strcat(progIdName, extension, sizeof(progIdName));
|
||||
|
||||
wchar_t *progIdNameW = utf8_to_widechar(progIdName);
|
||||
lstrcpyW(dst, progIdNameW);
|
||||
free(progIdNameW);
|
||||
}
|
||||
|
||||
static bool windows_setup_file_association(
|
||||
const utf8 * extension,
|
||||
const utf8 * fileTypeText,
|
||||
const utf8 * commandText,
|
||||
const utf8 * commandArgs,
|
||||
const uint32 iconIndex
|
||||
) {
|
||||
wchar_t exePathW[MAX_PATH];
|
||||
wchar_t dllPathW[MAX_PATH];
|
||||
|
||||
GetModuleFileNameW(NULL, exePathW, sizeof(exePathW));
|
||||
GetModuleFileNameW(_dllModule, dllPathW, sizeof(dllPathW));
|
||||
|
||||
wchar_t *extensionW = utf8_to_widechar(extension);
|
||||
wchar_t *fileTypeTextW = utf8_to_widechar(fileTypeText);
|
||||
wchar_t *commandTextW = utf8_to_widechar(commandText);
|
||||
wchar_t *commandArgsW = utf8_to_widechar(commandArgs);
|
||||
|
||||
wchar_t progIdNameW[128];
|
||||
get_progIdName(progIdNameW, extension);
|
||||
|
||||
bool result = false;
|
||||
|
||||
// [HKEY_CURRENT_USER\Software\Classes]
|
||||
HKEY hRootKey = NULL;
|
||||
if (RegOpenKeyW(HKEY_CURRENT_USER, SOFTWARE_CLASSES, &hRootKey) != ERROR_SUCCESS) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
// [hRootKey\.ext]
|
||||
if (RegSetValueW(hRootKey, extensionW, REG_SZ, progIdNameW, 0) != ERROR_SUCCESS) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
HKEY hKey = NULL;
|
||||
if (RegCreateKeyW(hRootKey, progIdNameW, &hKey) != ERROR_SUCCESS) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
// [hRootKey\OpenRCT2.ext]
|
||||
if (RegSetValueW(hKey, NULL, REG_SZ, fileTypeTextW, 0) != ERROR_SUCCESS) {
|
||||
goto fail;
|
||||
}
|
||||
// [hRootKey\OpenRCT2.ext\DefaultIcon]
|
||||
wchar_t szIconW[MAX_PATH];
|
||||
wsprintfW(szIconW, L"\"%s\",%d", dllPathW, iconIndex);
|
||||
if (RegSetValueW(hKey, L"DefaultIcon", REG_SZ, szIconW, 0) != ERROR_SUCCESS) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
// [hRootKey\OpenRCT2.sv6\shell]
|
||||
if (RegSetValueW(hKey, L"shell", REG_SZ, L"open", 0) != ERROR_SUCCESS) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
// [hRootKey\OpenRCT2.sv6\shell\open]
|
||||
if (RegSetValueW(hKey, L"shell\\open", REG_SZ, commandTextW, 0) != ERROR_SUCCESS) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
// [hRootKey\OpenRCT2.sv6\shell\open\command]
|
||||
wchar_t szCommandW[MAX_PATH];
|
||||
wsprintfW(szCommandW, L"\"%s\" %s", exePathW, commandArgsW);
|
||||
if (RegSetValueW(hKey, L"shell\\open\\command", REG_SZ, szCommandW, 0) != ERROR_SUCCESS) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
result = true;
|
||||
fail:
|
||||
free(extensionW);
|
||||
free(fileTypeTextW);
|
||||
free(commandTextW);
|
||||
free(commandArgsW);
|
||||
RegCloseKey(hKey);
|
||||
RegCloseKey(hRootKey);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void windows_remove_file_association(const utf8 * extension)
|
||||
{
|
||||
// [HKEY_CURRENT_USER\Software\Classes]
|
||||
HKEY hRootKey;
|
||||
if (RegOpenKeyW(HKEY_CURRENT_USER, SOFTWARE_CLASSES, &hRootKey) == ERROR_SUCCESS) {
|
||||
// [hRootKey\.ext]
|
||||
RegDeleteTreeA(hRootKey, extension);
|
||||
|
||||
// [hRootKey\OpenRCT2.ext]
|
||||
wchar_t progIdName[128];
|
||||
get_progIdName(progIdName, extension);
|
||||
RegDeleteTreeW(hRootKey, progIdName);
|
||||
|
||||
RegCloseKey(hRootKey);
|
||||
}
|
||||
}
|
||||
|
||||
void platform_setup_file_associations()
|
||||
{
|
||||
// Setup file extensions
|
||||
windows_setup_file_association(".sc4", "RCT1 Scenario (.sc4)", "Play", "\"%1\"", 0);
|
||||
windows_setup_file_association(".sc6", "RCT2 Scenario (.sc6)", "Play", "\"%1\"", 0);
|
||||
windows_setup_file_association(".sv4", "RCT1 Saved Game (.sc4)", "Play", "\"%1\"", 0);
|
||||
windows_setup_file_association(".sv6", "RCT2 Saved Game (.sv6)", "Play", "\"%1\"", 0);
|
||||
windows_setup_file_association(".td4", "RCT1 Track Design (.td4)", "Install", "\"%1\"", 0);
|
||||
windows_setup_file_association(".td6", "RCT2 Track Design (.td6)", "Install", "\"%1\"", 0);
|
||||
|
||||
// Refresh explorer
|
||||
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);
|
||||
}
|
||||
|
||||
void platform_remove_file_associations()
|
||||
{
|
||||
// Remove file extensions
|
||||
windows_remove_file_association(".sc4");
|
||||
windows_remove_file_association(".sc6");
|
||||
windows_remove_file_association(".sv4");
|
||||
windows_remove_file_association(".sv6");
|
||||
windows_remove_file_association(".td4");
|
||||
windows_remove_file_association(".td6");
|
||||
|
||||
// Refresh explorer
|
||||
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#endif
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue