[英]passing code to a function as parameter within “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.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_Click()”内的最后一个代码(在远程机器上做某事=服务器)。 所以我的问题是:是否可以做这样的插图?:
您可以使用委托来实现此目的。 最简单的方法是使用Action
或Func
。 如果您不需要返回值,请使用Action
:
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<int>
而不仅仅是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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.