2010-03-26 63 views
5

我是Silverlight新手,我正在做一些测试。通过我目前的测试,我尝试实时显示当前的剪贴板内容。但是这个代码有一个奇怪的行为:Silverlight 4剪贴板安全异常“访问不被允许”?

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(); 
    } 
} 
} 

按钮事件和计时器事件是假设做完全相同的行为。 但它不!该按钮正常工作和剪贴板文本设置成标签,但计时器抛出异常:

剪贴板不允许访问

的问题是:为什么? :)

谢谢。

PS:我会赌一个线程的问题:对

回答

4

在部分信任(浏览器内)Silverlight应用程序(上面可能提​​到的场景)中,剪贴板访问受到限制。 GetText属性只能在Silverlight运行时确定由用户启动的情况下访问。你的例子是完美的 - 例如通过点击按钮。然而,派发计时器不是用户启动的,因此该属性会抛出一个异常(这在浏览器内应用程序的上下文中尤为重要,如果您可以创建一个仅在第三方应用程序中静默运行的Silverlight应用程序,这可能是一个巨大的安全漏洞。浏览器,在不知情的情况下观看用户的剪贴板更新)。

有关更多详细信息,请参阅此clipboard documentation

+0

谢谢。有没有办法绕过这个限制?我不想要黑客,但是,这可能是我想要构建的应用程序不可缺少的功能... – 2010-03-26 20:26:11

+0

@Niklaos:解决此限制的唯一方法是将应用程序安装为浏览器应用程序相信。 – AnthonyWJones 2010-03-26 21:40:14

+1

另请注意,Silverlight剪贴板仅限于文本。 – WiredPrairie 2010-03-27 15:01:21

1

你有没有尝试过这样的:

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

编辑

快速搜索后,似乎Clipboard仅适用响应于用户动作,参见herehere

在部分信任(对于 浏览器承载基于Silverlight的应用 默认模式),Silverlight的也 限制了它的两个 关键的API gettext和的setText剪贴板访问。这些 API只能在由 Silverlight运行时确定的 上下文中调用,以响应用户发起的操作的 。例如,对于 示例,剪贴板访问从Click或 KeyDown事件的处理程序内有效 。相比之下,剪贴板 访问对于加载或来自构造函数的 处理程序无效,并且 访问尝试会引发异常。

+1

Dispatcher.Invoke产生编译错误。 BeginInvoke编译,但同一行生成相同的异常:/任何其他想法? – 2010-03-26 19:06:16

1

如果您唯一的选择是使用计时器,那么请不要这样做。 clipboad是一个共享资源,当您尝试访问剪贴板时,您将在其他程序中引发“无法打开剪贴板”错误。即用户从WinWord中复制某些内容,WinWord会尝试打开剪贴板,但不能,因为您在检查时已将其锁定。

+0

很高兴知道!我不想使用计时器(这很难看),但还有其他一些方法吗?这似乎是微软忘了“ClipboardUpdated”事件:p – 2010-03-26 20:46:01

+0

不知道,因为我不知道Silverlight。在这类事情的另一端,我有很多经验。在API文档中查找对Clipboard Viewer或WM_DrawClipboard的任何类型的引用。另外,要明白你的GetText()调用会导致WM_RenderFormat消息被发送到复制的应用程序(如果他们使用大多数应用程序所做的“延迟渲染”),那么你将以这种方式添加到你的麻烦中同样,通过非常保证无论你试图抓取什么,都会导致提供应用程序想要再次打开剪贴板。并失败。 – 2010-03-26 20:58:51

+1

Microsoft确实向本机Win32应用程序提供了剪贴板更新的消息(WM_CLIPBOARDUPDATE)。 但是,对于跨平台的Silverlight应用程序,您无法访问此消息/功能(特别是在浏览器内应用程序的情况下,如果您可以编写刚刚坐的代码,这会是一个很大的安全问题在浏览器中默默无闻地看着用户的剪贴板更新)。 – WiredPrairie 2010-03-27 15:12:16

2

只需触发Clipboard.ContainsText()而不是Text。 ContainsText方法是允许的!

0

你好这对我的作品,但只有在IE Microsoft.LightSwitch.Threading.Dispatchers.Main.BeginInvoke(() => HtmlPage.Window.Eval("window.clipboardData.setData('Text','testtestest')"));

只使用GetData方法