Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将代码作为参数传递给函数;使用语句";_C#_Impersonation_Using Statement - Fatal编程技术网

C# 将代码作为参数传递给函数;使用语句";

C# 将代码作为参数传递给函数;使用语句";,c#,impersonation,using-statement,C#,Impersonation,Using Statement,这段代码对我来说很好: [DllImport("advapi32.dll", SetLastError = true)] public static extern bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken); [DllImport("kernel32

这段代码对我来说很好:

    [DllImport("advapi32.dll", SetLastError = true)]
    public static extern bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

    [DllImport("kernel32.dll")]
    public static extern bool CloseHandle(IntPtr token);

enum LogonType
    {
        Interactive = 2,
        Network = 3,
        Batch = 4,
        Service = 5,
        Unlock = 7,
        NetworkClearText = 8,
        NewCredentials = 9
    }
    enum LogonProvider
    {
        Default = 0,
        WinNT35 = 1,
        WinNT40 = 2,
        WinNT50 = 3
    }

private void Button1_Click()
    { 
        IntPtr token = IntPtr.Zero;
        LogonUser("Administrator",
                  "192.168.1.244",
                  "PassWord",
                  (int)LogonType.NewCredentials,
                  (int)LogonProvider.WinNT50,
                  ref token);
        using (WindowsImpersonationContext context = WindowsIdentity.Impersonate(token))
        {
    CloseHandle(token);
    /*
    Code_of_Do_Something
    */
    }
}
但是…这意味着每次我需要进行模拟(在远程机器=服务器上执行操作)时,我必须重复“Button1\u Click()”中的最后一个代码。 所以我的问题是:有没有可能像这样做

为此,您可以使用委托。最简单的方法是使用or
Func
。如果不需要返回值,请使用
操作

private void RunImpersonated(Action act)
{
    IntPtr token = IntPtr.Zero;
    LogonUser("Administrator",
              "192.168.1.244",
              "PassWord",
              (int)LogonType.NewCredentials,
              (int)LogonProvider.WinNT50,
              ref token);
    try
    {
        using (WindowsImpersonationContext context = WindowsIdentity.Impersonate(token))
        {
            // Call action
            act();
        }
    }
    finally
    {
        CloseHandle(token);
    }
}
请注意,泛型类型参数有很多变体,允许您也以强类型方式向
Action
Func
委托提供参数。例如,如果需要into参数,请使用
Action
,而不仅仅是
Action

还要注意,我创建了一个finally块,无论是否发生异常,它都会关闭句柄

为了调用函数,可以使用lambda表达式:

private void button1_Click(object sender, EventArgs e)
{
    RunImpersonated(() => {
        DirectoryInfo dir = new DirectoryInfo( @"\\192.168.1.244\repository");
        foreach (DirectoryInfo di in dir.GetDirectories()) 
        { 
            lable_folders_count.Text = Convert.ToString(dir.GetFileSystemInfos().Length); 
        }
    });
}

是的,可以将代码作为参数传递。但让我们在不使用lambdas的情况下解决您的问题:

private void Button1_Click()
{
    using(GetImpersonationContext())
    {
        /* code here */
    } 
}
private WindowsImpersonationContext GetImpersonationContext()
{
    IntPtr token = IntPtr.Zero;
    LogonUser("Administrator",
              "192.168.1.244",
              "PassWord",
              (int)LogonType.NewCredentials,
              (int)LogonProvider.WinNT50,
              ref token);

    WindowsImpersonationContext context = WindowsIdentity.Impersonate(token);
    CloseHandle(token);
    return context;
}

使用代理?您还可以返回上下文值(WindowsIdentity.Impersonate)并自行处理该操作。
CloseHandle
是否应该紧跟代码?事实上,它不应该在自己的
finally
块中,这样它就会一直被执行吗?同意。您有什么证据可以在那里调用
CloseHandle
?如果
WindowsIdentity.Impersonate()
失败,则您根本不会调用它。我可以知道如何将此代码放入操作中吗
code
DirectoryInfo dir=new DirectoryInfo(@“\\192.168.1.244\存储库);foreach(DirectoryInfo di in dir.GetDirectories()){lable_folders_count.Text=Convert.ToString(dir.getfilesystemminfos().Length);}
code
@CrownFord:我更新了帖子并加入了一个示例。希望能有所帮助。我收到了以下错误:“方法必须有一个返回类型”关于:RunImpersonated(()@CrownFord:错误显示在哪里?在public void RunImpersonated(Action act)或者您在哪里调用RunImpersonated?请从这里查看屏幕截图:它工作正常,thanx…只需从
);
表单
WindowsIdentity.Impersonate(令牌);