Passing the function code as a parameter to "using statement"

This code works fine with me:

[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 */ } } 

BUT ... This means that I have to repeat the last code that is inside "Button1_Click ()" every time I need to impersonate (do something on the remote computer = server). So my question is: is it possible to do something like this illustration ?: enter image description here

+6
source share
2 answers

You can use delegates for this purpose. The easiest way is to use Action or Func . If you do not need a return value, use 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); } } 

Note that there are many variations of generic type parameters that allow you to also provide parameters to Action or Func delegates in a strongly typed way. If you need the in parameter, use an Action<int> instead of an Action .

Also note that I created a finally block that closes the descriptor if an exception is thrown.

To call a function, you can use the lambda expression:

 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); } }); } 
+3
source

Yes, you can pass the code as a parameter. But solve your problem without using lambda:

 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; } 
+1
source

All Articles