Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Any way to circumvent "Dialogs must be user-initiated" exception?

My app has a 'open file' button. Before launching the OpenFileDialog, it asks whether the user wants to save the current file, and if they do, it launches a SaveFileDialog. It then launches the OpenFileDialog. Pretty standard stuff.

My problem is that silverlight then sees the OpenFileDialog.ShowDialog() method as not user-initiated, and I get a SecurityException.

Is there any known reasonable way to avoid this exception? Surely this is a pretty standard scenario?

The app is within a browser.

Any ideas welcome

EDIT:

Sorry, not allowed to release actual code :( The logic is pretty simple though: In psuedocode the 'OpenFile" button press event calls a method something like:

*Launch a new SL message asking whether to save first.

*On message window yes/no clicked: -If No, Go to Load -If Yes, Launch SaveFileDialog.ShowDialog(), go to Load

*Load: Launch An Open File Dialog

EDIT 2: Mini programme...

XML content for the main page:

<Grid x:Name="LayoutRoot" Background="White">
    <Button Content="Open" Click="Button_Click"/>
</Grid>

Code:

using System.Windows;
using System.Windows.Controls;

namespace SilverlightApplication15
{
public partial class MainPage : UserControl
{
    AskWindow aw = new AskWindow();

    public MainPage()
    {
        InitializeComponent();
        aw.Closed += new System.EventHandler(aw_Closed);
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        aw.Show();
    }

    private void aw_Closed(object sender, System.EventArgs e)
    {
        if (aw.DialogResult == true)
        {
            SaveFileDialog svd = new SaveFileDialog();
            svd.ShowDialog();
        }


        OpenFileDialog ofd = new OpenFileDialog();
        ofd.ShowDialog();//Causes security exception
    }
}

public class AskWindow : ChildWindow
{
    public AskWindow()
    {
        Button b = new System.Windows.Controls.Button();
        b.Click += new System.Windows.RoutedEventHandler(b_Click);
        b.Content = "Yes, save it";
        this.Content = b;
    }

    private void b_Click(object sender, System.Windows.RoutedEventArgs e)
    {
        this.DialogResult = true;
    }
}
}
like image 799
user495625 Avatar asked Nov 04 '11 10:11

user495625


1 Answers

A short answer to your question is "NO", cause the second Dialog isn´t user-initiated anymore for the silverlight runtime. The same is true if you display a MessageBox before opening a Dialog.

Here´s some information from MSDN about security restrictions on Dialogs

For security purposes, if a Silverlight application is a sandboxed application, file and print dialog boxes must be user-initiated. This means you must show them from a user-initiated action, such as the click event handler for a button. If you attempt to show a dialog box from non-user initiated code, a SecurityException will occur. In addition, there is a limit on the time allowed between when the user initiates the dialog and when the dialog is shown. If the time limit between these actions is exceeded, an exception will occur. When you are using the Visual Studio debugger with a dialog box, a SecurityException will be thrown if you set a breakpoint between dialog box creation and showing the dialog box. Because of the user-initiated restrictions, this is the expected behavior. If you set a breakpoint after the call to ShowDialog, no exception will be thrown.

If you attempt to show the dialog box from KeyDown event handlers and other synchronous calls to application code, such as LayoutUpdated or SizeChanged event handlers, an exception will be thrown. However, an exception will not be thrown when the application is hosted in Internet Explorer, running in protected mode.

The Silverlight plug-in has limited support for dialog boxes when the plug-in is in full-screen mode. In most cases, displaying the dialog box in full-screen mode will cause the plug-in to revert to embedded mode. However, to avoid issues on some browsers, you should exit full-screen mode before using these classes. In Silverlight applications that run outside the browser, you can display a prompt to the user to enable dialog boxes in full-screen mode. Also, the user initiation restrictions are relaxed for trusted applications. For more information, see Trusted Applications.

The time limit, could be easily tested with following code:

private void OpenDialog(object sender, RoutedEventArgs e) {
  MessageBox.Show("test");

  OpenFileDialog fileDialog = new OpenFileDialog();
  var result = fileDialog.ShowDialog();
}

When you really hit fast the "Enter"-Key when the MessageBox gets displayed, the OpenFileDialog gets displayed afterwards, raising no security exception. But if you leave the MessageBox open for a small amount of time, after closing the MessageBox a SecurityException is raised.

I think the time limit is the problem showing two Dialogs one after another, cause the time limit will exceed showing the first one.

like image 192
Jehof Avatar answered Oct 04 '22 02:10

Jehof