2010-03-26 10 views
5

Je suis nouveau chez Silverlight et je fais des tests. Avec mon test actuel, j'essaie d'afficher en temps réel le contenu actuel du Presse-papiers. Mais il y a un comportement bizarre avec ce code:Silverlight 4 Clipboard Security Exception "l'accès n'est pas autorisé"?

namespace SilverlightTest 
{ 
public partial class MainPage : UserControl 
{ 
    private Timer _timer; 

    public MainPage() 
    { 
     InitializeComponent(); 
     var dispatcher_timer = new DispatcherTimer {Interval = new TimeSpan(0, 0, 0, 5)}; 
     dispatcher_timer.Tick += new EventHandler(timer_Callback); 
     dispatcher_timer.Start(); 
    } 

    private void timer_Callback(object state, EventArgs eventArgs) 
    { 
     current_clip_board.Content = Clipboard.GetText(); 
    } 

    private void button1_Click(object sender, RoutedEventArgs e) 
    { 
     current_clip_board.Content = Clipboard.GetText(); 
    } 
} 
} 

Le bouton de l'événement et la minuterie de l'événement sont supposés faire exactement la même action. Mais ce n'est pas le cas! Le bouton fonctionne très bien et le texte mis en presse-papiers dans l'étiquette, mais la minuterie lancer une exception:

accès Presse-papiers n'est pas autorisé

La question est: pourquoi? :)

Merci.

PS: Je serais prêt à parier sur un problème de fil: p

Répondre

4

L'accès au Presse-papiers dans une application Silverlight partielle (dans le navigateur) Silverlight (le scénario auquel vous faites référence plus haut) est limité. La propriété GetText est accessible uniquement dans les scénarios que l'environnement d'exécution Silverlight détermine ont été initiés par l'utilisateur. Votre exemple est parfait - par un clic sur un bouton par exemple. Un temporisateur d'expédition n'est cependant pas initié par l'utilisateur, donc la propriété déclenche une exception (ceci est particulièrement important dans le contexte d'une application dans le navigateur, ce qui pourrait être un gros problème de sécurité si vous pouviez créer une application Silverlight silencieuse). navigateur, en regardant les mises à jour de presse-papiers de l'utilisateur à leur insu).

Voir ce clipboard documentation pour plus de détails.

+0

Merci. Existe-t-il des moyens de contourner cette restriction? Je ne veux pas de hack mais, cela peut être une fonctionnalité indispensable pour l'application que je veux construire ... –

+0

@Niklaos: Le seul moyen de contourner cette restriction est d'avoir l'application installée comme une application hors navigateur avec une élévation confiance. – AnthonyWJones

+1

Notez également que le presse-papiers Silverlight est limité au texte uniquement. – WiredPrairie

1

Avez-vous essayé ceci:

private void timer_Callback(object state, EventArgs eventArgs) 
{ 
    Dispatcher.Invoke(new System.Threading.ThreadStart(delegate() 
    { 
     current_clip_board.Content = Clipboard.GetText(); 
    } 
} 

modifier

Après une recherche rapide, il semble que Clipboard est uniquement disponible en réponse à une action de l'utilisateur, voir here et here.

En confiance partielle (le mode par défaut pour basés sur Silverlight navigateur des applications hébergées), Silverlight également restreint l'accès à ses deux presse-papier clé API GetText et SetText. Ces API peuvent uniquement être appelées à partir d'un contexte qui est déterminé par l'exécution de Silverlight comme étant une réponse à une action déclenchée par l'utilisateur. Pour l'exemple , l'accès au Presse-papiers est valide à partir d'un gestionnaire pour un événement Clic ou KeyDown. En revanche, l'accès presse-papiers n'est pas valide à partir d'un gestionnaire pour chargé ou à partir d'un constructeur, et tentatives d'accès jeter des exceptions.

+1

Dispatcher.Invoke générer une erreur de compilation. BeginInvoke compile mais la même exception est générée par la même ligne:/Any other ideas? –

1

Si votre seule option est d'utiliser une minuterie, alors ne le faites pas du tout. Le clipboad est une ressource partagée et vous allez déclencher des erreurs "Impossible d'ouvrir le Presse-papiers" dans d'autres programmes lorsqu'ils tentent d'accéder au Presse-papiers. C'est-à-dire que l'utilisateur copie quelque chose à partir de WinWord, WinWord essaie d'ouvrir le presse-papiers, mais ne le peut pas, parce que vous l'avez verrouillé pendant que vous l'examinez.

+0

C'est bon à savoir! Je ne veux pas utiliser de minuteur (c'est assez moche) mais y a-t-il d'autres façons? Il semble que Microsoft ait oublié l'événement "ClipboardUpdated": p –

+0

Aucune idée, car je ne connais pas Silverlight. Je viens d'avoir beaucoup d'expérience à l'autre bout de ce genre de choses. Recherchez toute sorte de référence à Clipboard Viewer ou WM_DrawClipboard dans les documents API. En outre, sachez que votre appel GetText() entraînera l'envoi d'un message WM_RenderFormat à l'application qui a copié (si elle utilise "Rendu différé", ce que font la plupart des grandes applications). De plus, en garantissant à peu près tout ce que vous venez d'essayer de récupérer, l'application qui fournit vous demandera d'ouvrir à nouveau le presse-papiers. Et échouer. –

+1

Microsoft a fourni le message mis à jour du Presse-papiers aux applications natives Win32 (WM_CLIPBOARDUPDATE). Mais, pour une application Silverlight multi-plateforme, vous n'avez pas accès à ce message/fonctionnalité (en particulier dans le contexte d'une application dans le navigateur, ce qui serait un gros problème de sécurité si vous pouviez écrire du code silencieusement dans le navigateur, en regardant les mises à jour du presse-papiers de l'utilisateur à leur insu). – WiredPrairie

2

Il suffit de déclencher Clipboard.ContainsText() au lieu de Texte. La méthode ContainsText est autorisée!

0

Bonjour cela fonctionne pour moi, mais seulement dans IE Microsoft.LightSwitch.Threading.Dispatchers.Main.BeginInvoke(() => HtmlPage.Window.Eval("window.clipboardData.setData('Text','testtestest')"));

simplement utiliser la méthode getData