Skip to content

Clean up url handler registration #2366

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 19, 2018
Merged

Conversation

HebaruSan
Copy link
Member

Background

When it starts up, the CKAN GUI adds support for ckan://identifier URLs on Windows and Linux.

On Windows, it does this by adding this registry key:

image

CKAN might need to escalate privileges to make these changes. It detects this after the fact by catching an UnauthorizedAccessException when it attempts to set the registry key. If this exception is thrown, ckan.exe re-launches itself as administrator with the registerUrl command line flag, which prompts the user whether to allow the increased privileges and then sets the registry key.

Problem

The user might see this error when launching CKAN:

8468 [1] ERROR CKAN.URLHandlers (null) - There was an error while registering the URL handler for ckan:// - Cannot delete a subkey tree because the subkey does not exist.
8485 [1] ERROR CKAN.URLHandlers (null) -    at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
   at Microsoft.Win32.RegistryKey.DeleteSubKeyTree(String subkey, Boolean throwOnMissingSubKey)
   at CKAN.URLHandlers.RegisterURLHandler_Win32()
   at CKAN.URLHandlers.RegisterURLHandler(Configuration config, IUser user)

If this is fixed, other errors can appear:

12186 [1] ERROR CKAN.URLHandlers (null) - There was an error while registering the URL handler for ckan:// - Cannot write to the registry key.
12200 [1] ERROR CKAN.URLHandlers (null) -    at System.ThrowHelper.ThrowUnauthorizedAccessException(ExceptionResource resource)
   at Microsoft.Win32.RegistryKey.EnsureWriteable()
   at Microsoft.Win32.RegistryKey.DeleteSubKeyTree(String subkey, Boolean throwOnMissingSubKey)
   at CKAN.URLHandlers.RegisterURLHandler_Win32()
   at CKAN.URLHandlers.RegisterURLHandler(Configuration config, IUser user)

Causes

The DeleteSubKeyTree call doesn't throw UnauthorizedAccessException when it can't do its job as we would hope. So this call should have its exceptions caught and ignored just like the lines above it.

But if UnauthorizedAccessException is thrown, it's re-thrown after it is caught and handled:

CKAN/GUI/URLHandlers.cs

Lines 51 to 67 in 9ee3584

if (user.RaiseYesNoDialog(@"CKAN requires permission to add a handler for ckan:// URLs.
Do you want to allow CKAN to do this? If you click no you won't see this message again."))
{
// we need elevation to write to the registry
ProcessStartInfo startInfo = new ProcessStartInfo(System.Reflection.Assembly.GetEntryAssembly().Location);
startInfo.Verb = "runas"; // trigger a UAC prompt (if UAC is enabled)
startInfo.Arguments = "gui " + UrlRegistrationArgument;
Process.Start(startInfo);
}
else
{
config.URLHandlerNoNag = true;
config.Save();
}
throw;
}

This is redundant, because no other code is going to be able to do anything more to help the situation than has already been done, and if the privilege-escalated sub-process is able to set the key, then the user has no reason to care about this exception.

Changes

Now DeleteSubKeyTree is called within the try block above its current location, and we don't re-throw any UnauthorizedAccessExceptions. This prevents the error message from bothering the user.

Fixes #2362.

@HebaruSan HebaruSan added Bug Something is not working as intended Windows Issues specific for Windows labels Mar 17, 2018
@politas
Copy link
Member

politas commented Mar 18, 2018

So, does this leave the GUI running with elevated privileges? If so, that could be part of why so many people end up running CKAN as administrator (It "worked fine" the first time they ran it!)

@HebaruSan
Copy link
Member Author

No, the special registerUrl parameter makes it only do the URL registration stuff. The GUI itself is only initialized if that argument is absent:

CKAN/GUI/Program.cs

Lines 27 to 37 in a6619fe

if (args.Contains(URLHandlers.UrlRegistrationArgument))
{
//Passing in null will cause a NullRefrenceException if it tries to show the dialog
//asking for elevation permission, but we want that to happen. Doing that keeps us
//from getting in to a infinite loop of trying to register.
URLHandlers.RegisterURLHandler(null, null);
}
else
{
new Main(args, user, showConsole);
}

@politas
Copy link
Member

politas commented Mar 18, 2018

Ah, thanks, I figured that would be in there somewhere.

@politas politas merged commit 0fddc34 into KSP-CKAN:master Mar 19, 2018
politas added a commit that referenced this pull request Mar 19, 2018
@politas politas removed the Bug Something is not working as intended label Mar 19, 2018
@HebaruSan HebaruSan deleted the fix/url-errors branch March 19, 2018 04:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Windows Issues specific for Windows
Projects
None yet
Development

Successfully merging this pull request may close these issues.

CKAN.URLHandlers error every time when opening CKAN on Windows
2 participants