8

I have a Silverlight 5.1.10411.0 Out-of-Browser application that is NOT trusted and I am trying to close the application using the App.Current.MainWindow.Close method. According to the documentation I can only use this mechanism if one of these conditions is true:

  • It is a trusted application (not true for my application)
  • Before the Application.Startup event has completed (not true for my application)
  • In response to a user-initiated action, for example, in a button Click event handler (This is what I am trying to get to work)

In my attempts to get this to work I have kept things extremely simple and am calling the method directly in a code behind button click event handler as shown below but it has no effect.

void closeButton_Click(object sender, RoutedEventArgs e)
{
    var mainWindow = Application.Current.MainWindow;
    mainWindow.Close();
}

When I attach the debugger and set "Break when an exception is Thrown" I can see the exception

SecurityException: Access to the property or method call is not allowed unless the application has elevated permissions, or the code was called through a user initiated action.

Any ideas why my code is not being considered a user initiated action?

I have tried attaching the event handler in both XAML and in the code-behind (not at the same time)

 <Button x:Name="closeButton" Content="Close" Click="closeButton_Click" />

or

 closeButton.Click += closeButton_Click;

without success. I have read the User-Initiated Events documentation very carefully and cannot see why my code is not considered user initiated. I have tried this in both debug and release mode as well as when no debugger is attached without success. If I change "Require elevated trust when running outside the browser" to be true, the close call works as expected.

I have redefined my application requirements to work around this issue but I would really like to understand what I am doing wrong ;-)

Update: SonOfPirate's answer indicate that the documentation for this method is not accurate but I'm not convinced. Using the reflection tool dotPeek the method that is throwing the exception is

private void CheckForPermissions()
{
  if (!Application.Current.HasElevatedPermissions && !XcpImports.IsUserInitiatedAction() && Application.Current.ApplicationStarted)
    throw new SecurityException(Resx.GetString("Window_AccessNotAllowed"));
}

I find this a bit confusing to read so I've mocked the code and written unit tests for it as shown by this gist and as you can see from the results I should be able to call close from an untrusted application, provided it is user initiated. Window Close Security Test Results

The security exception message

Access to the property or method call is not allowed unless the application has elevated permissions, or the code was called through a user initiated action.

also indicates that it should be possible so I am back to the question - why is this code not considered user initiated?

Community
  • 1
  • 1
Martin Hollingsworth
  • 7,249
  • 7
  • 49
  • 51

2 Answers2

3

The mistake is in the very first paragraph when you state that you "can only use this mechanism if one of these conditions is true:" Re-read the MS documentation a little closer and you will see that they do not say "one" of these conditions. Here is the exact text from the MS reference page for the Close method:

You can call this method only in the following cases:

  • In response to a user-initiated action, for example, in a button Click event handler.
  • Before the Application.Startup event has completed (that is, in an IApplicationService.StartService method, an IApplicationLifetimeAware.Starting method, or a Startup event handler).
  • In a trusted application.

As you have seen, you need to enable elevated trust.

UPDATE

I concede that the wording used by Microsoft is a bit misleading with either of the first two cases required in combination with the third. Perhaps it would be clearer if worded more accurately as:

You can call this method only in a trusted application in either of the following cases:

  • In response to a user-initiated action, for example, in a button Click event handler.
  • Before the Application.Startup event has completed (that is, in an IApplicationService.StartService method, an IApplicationLifetimeAware.Starting method, or a Startup event handler).
SonOfPirate
  • 5,642
  • 3
  • 41
  • 97
  • I had already considered that the cases all need to be true rather than either of them but that would mean you could only call the method "Before the Application.Startup event has completed". This is not the case and you can definitely call the method in a trusted application after the Startup event. If you use a reflection tool to look at the Window.Close method you can see the call to `this.CheckForPermissions();` and the implementation only throws the exception if it is not trusted and it is not user initiated and the application has started. – Martin Hollingsworth Jul 05 '12 at 02:25
  • I think you are probably right although I would use stronger language than "a bit misleading", at the very least I would drop the _bit_ :-) – Martin Hollingsworth Jul 05 '12 at 06:10
  • The behaviour I'm observing matches your modified version of the documentation (i.e. this can only be called from a trusted application), but the reflected version of the CheckForPermissons code and the exception message indicate that this should not be the case - i.e you should be able to call this from an untrusted application if it is user initiated. I've updated the question with the details of this. I'm going to try this on a machine with the normal silverlight runtime rather than the developer runtime next. – Martin Hollingsworth Jul 06 '12 at 01:04
  • Interesting. I agree that the CheckForPermissions method definitely allows untrusted apps but I have never been able to get this to work without elevated permissions. – SonOfPirate Jul 06 '12 at 13:21
0

How to elevate permission for webBrowser control in silverlight:

1- http://msdn.microsoft.com/en-us/library/gg192793%28v=vs.96%29.aspx Topic: To enable in-browser trusted applications

2- http://www.johnpapa.net/digitally-signing-a-xap-silverlight/ Topic: Digitally Signing a XAP Silverlight

3- http://chainding.wordpress.com/2012/09/19/silverlight-5-trusted-applications/ Topic: Adding the required registry setting Signing your XAP file Deploying the certificate

And make sure the signed certificate is deployed in Trusted publisher of local machine and current user.

msbeigi
  • 189
  • 1
  • 5