用户启动的操作实现

时间:2010-08-17 19:32:11

标签: c# .net vb.net security

在Flash 10中,有些方法要求从用户启动的操作(如按钮单击,键盘上/下键等)触发它们。

是否可以在.NET中实现此行为?例如,如果我们有这个子例程:

void SomeMethod() {
   // Here some stuff
}

如何检查方法是否是从鼠标单击事件处理程序中调用的?

如果有人知道我的意思,我们也可以把这些方法想象成“魔兽世界”中受保护的功能。

编辑:看起来这种行为是在Silverlight中实现的 - 我们只能通过鼠标点击或其他用户启动的操作弹出文件对话框(打开,保存),否则将抛出SecurityException。 I我希望实现这个bevaviour,但在我的情况下,它不是文件对话框,而是我们自己的方法。

2 个答案:

答案 0 :(得分:2)

为什么不将它作为参数提供?

void SomeMethod(bool userInitiated) {
   // Here some stuff
}

鉴于你已经在调用它,有时来自事件处理程序,有时候不是,你已经掌握了这些信息。

编辑:另一种方法是使用一个线程静态字段,在进入事件处理程序时设置,然后在退出时重置(在finally块中)。任何想要测试他们是否“响应用户操作”的代码都可以测试该字段。

如果这还不够好,那么我怀疑答案就是“不”。

编辑:你可以进入调用堆栈(请参阅StackTrace类),但这相对较慢并且可能由于内联而错过堆栈帧。还有Code Access Security 可能只是为了帮助你 - 但我对此表示怀疑。

答案 1 :(得分:0)

您似乎正在编写某种插件API。您希望提供一种方法来执行用户可能不想要的操作,例如更改剪贴板内容,并且您希望确保插件只能响应用户操作来调用该方法。

我能想到的唯一方法是API需要不断了解它当前是否正在处理用户启动的操作。据推测,程序中会有一些代码调用插件提供的代码,例如

if (plugin.HasHandlerForMouseClick)
    plugin.HandleMouseClick();

此时您需要记住这是用户启动的操作。一旦方法返回,那就是用户启动的操作的结束:

if (plugin.HasHandlerForMouseClick)
{
    _userInitiated = true;
    try
    {
        plugin.HandleMouseClick();
    }
    finally
    {
        _userInitiated = false;
    }
}

然后,在您的“不安全”方法中,例如要设置剪贴板的那个,你必须检查这个标志:

public void SetClipboard(object newValue)
{
    if (!_userInitiated)
        return;    // or throw AccessDeniedException?

    // set clipboard here
}

正如Jon暗示的那样,该字段应该被声明为线程静态的。这意味着每个线程都有一个单独的字段副本:

[ThreadStatic]
private static bool _userInitiated = false;