2011-11-04 16 views
11

Mi aplicación tiene un botón de "abrir archivo". Antes de abrir OpenFileDialog, pregunta si el usuario desea guardar el archivo actual y, si lo hace, inicia SaveFileDialog. A continuación, inicia el OpenFileDialog. Bastante estándar.¿Alguna forma de eludir la excepción "Los cuadros de diálogo deben ser iniciados por el usuario"?

Mi problema es que Silverlight ve el método OpenFileDialog.ShowDialog() como no iniciado por el usuario, y recibo una SecurityException.

¿Se conoce alguna forma razonable de evitar esta excepción? Sin duda, este es un escenario bastante estándar?

La aplicación está dentro de un navegador.

Cualquier idea bienvenida

EDIT:

Lo sentimos, no se les permite liberar código real :(La lógica es bastante simple sin embargo: En el psuedocode 'OpenFile caso pulse el botón" llama a un método algo como:

* Lanzar un nuevo mensaje SL preguntando si desea guardar primero

* en la ventana de mensaje si/no hace clic en:. -Si no, vaya a cargar -Si Sí, Lanzamiento SaveFileDialog.Sho wDialog(), vaya a cargar

* Capacidad de carga: iniciar un archivo de diálogo Abrir

EDIT 2: Mini programa ...

contenido XML para la página principal:

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

Código:

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; 
    } 
} 
} 
+1

Puedes publicar el código que tienes. – ChrisF

+0

¿Ha intentado escribir el método de extensión para ShowDialog() como ShowDialog (pregunta de cadena) que primero mostraría MsgBox y luego posiblemente llamaría a ShowDiaglog básico()? – neurotix

+0

@neurotix: Acabo de probarlo; mismo resultado me temo :( – user495625

Respuesta

3

Puede ser un escenario estándar para una aplicación de escritorio pero no está creando una aplicación de escritorio. Está creando un componente que se ejecuta en un entorno seguro y que viene con algunas restricciones bastante estrictas por buenas razones.

No hay una forma inteligente de manejar este escenario. Podría proporcionar una función de "documento" cercana que abrirá un cuadro de confirmación advirtiendo que la continuación perderá trabajo.

En un intento de abrir otro "documento" mientras la corriente no está guardada, todo lo que puede hacer es mostrar un mensaje indicándole al usuario sus elecciones, cierre el "documento" actual y abandone sus cambios o elija guardar. El usuario tendrá que realizar manualmente estas acciones y luego volver a elegir para abrir un "documento".

Es posible que pueda mejorar un poco las cosas si su aplicación admite varios documentos "abiertos", al menos no se le cobrará al usuario por abrir un "documento".

+0

Hola, gracias por tu respuesta. ¿Podría hacerte la misma pregunta que le pregunté a Jehof, arriba? ¿Por qué se trata openfiledialog de manera diferente a un cuadro de mensaje? p.ej. lo siguiente no causa una excepción, y aún 'spams' al usuario: for (int i = 0; i <1000000; i ++) {MessageBox.Show ("SPAM!"); } – user495625

+0

se considera menos dañino al usuario al dar acceso a la aplicación SL a los usuarios reales del disco HD mediante los diálogos SaveAs o OpenFile donde primero se puede usar para escribir virus en el disco y segundo para robar información sensible del usuario. –

4

Una respuesta corta a y nuestra pregunta es "NO", porque el segundo cuadro de diálogo ya no es iniciado por el usuario para el tiempo de ejecución de Silverlight. Lo mismo es cierto si muestra un cuadro de mensaje antes de abrir un cuadro de diálogo.

tope aquí tienes alguna información de MSDN sobre las restricciones de seguridad en Diálogos

Por motivos de seguridad, si una aplicación de Silverlight es un recinto de seguridad de aplicaciones, archivos e impresión de cajas de un cuadro de diálogo debe ser iniciada por el usuario. Esto significa que debe mostrarlos desde una acción iniciada por el usuario, como el controlador de evento click para un botón. Si intenta mostrar un cuadro de diálogo desde un código no iniciado por el usuario, se producirá una SecurityException. Además, hay un límite en el tiempo permitido entre cuando el usuario inicia el diálogo y cuando se muestra el diálogo. Si se excede el límite de tiempo entre estas acciones, se producirá una excepción. Cuando está utilizando el depurador de Visual Studio con un cuadro de diálogo, se lanzará una SecurityException si establece un punto de interrupción entre la creación del cuadro de diálogo y mostrando el cuadro de diálogo. Debido a las restricciones iniciadas por el usuario, este es el comportamiento esperado. Si establece un punto de interrupción después de la llamada a ShowDialog, no se lanzará ninguna excepción.

Si intenta mostrar el cuadro de diálogo de los controladores de eventos KeyDown y otras llamadas sincrónicas al código de la aplicación, como los controladores de eventos LayoutUpdated o SizeChanged, se lanzará una excepción. Sin embargo, no se lanzará una excepción cuando la aplicación esté alojada en Internet Explorer, ejecutándose en modo protegido.

El complemento Silverlight tiene soporte limitado para los cuadros de diálogo cuando el complemento está en modo de pantalla completa. En la mayoría de los casos, mostrar el cuadro de diálogo en modo de pantalla completa hará que el complemento vuelva al modo incrustado. Sin embargo, para evitar problemas en algunos navegadores, debe salir del modo de pantalla completa antes de utilizar estas clases. En las aplicaciones de Silverlight que se ejecutan fuera del navegador, puede mostrar una solicitud al usuario para habilitar cuadros de diálogo en modo de pantalla completa. Además, las restricciones de iniciación del usuario se relajan para las aplicaciones confiables. Para obtener más información, vea Aplicaciones de confianza.

El límite de tiempo, se podrían probar fácilmente con el código siguiente:

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

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

Cuando realmente golpea rápidamente en el "Enter" -Tecla cuando se visualiza el cuadro de mensaje, el OpenFileDialog Obtiene aparecerá más adelante, levantando sin excepcion de seguridad. Pero si deja el MessageBox abierto durante un período de tiempo pequeño, después de cerrar el MessageBox, se genera una SecurityException.

Creo que el límite de tiempo es el problema que muestra dos cuadros de diálogo uno tras otro, porque el límite de tiempo excederá mostrando el primero.

+0

Hola gracias por tu respuesta. Una pregunta sin embargo: ¿Por qué se trata openfiledialog de manera diferente a un cuadro de mensaje? p. lo siguiente no causa una excepción, y aún 'spams' al usuario para (int i = 0; i <1000000; i ++) { MessageBox.Show ("SPAM!"); } – user495625

+0

@ user495625: Un MessageBox muestra solo texto, mientras que OpenFileDialog/SaveFileDialog se usa para acceder a los archivos y recursos locales y, por lo tanto, tiene un mayor riesgo de seguridad. – Jehof

0

Debería mostrar SaveFileDialog en el mouse Click controlador inmediatamente. En su caso, sería en private void b_Click.

Poner algunos obstáculos entre el clic del mouse y SaveFileDialog no funcionará.

Cuestiones relacionadas