在Windows服务中,我面临着冒充用户的问题。 模拟发现位于System.Timers.Timer Elapsed事件中。 计时器每3秒钟滴答一次。当imersonation失败并且我得到"无法冒充用户"我通过重新启动计时器进行重试,然后继续并继续模拟。
运行此服务3到4天后,模拟再次失败,重试不起作用,应用程序停留在已用事件中。
Timer是否可能用完了线程?(Threadpool)
如何防止模拟失败或如何处理?
假冒代码:
[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", CharSet = CharSet.Auto)]
public extern static bool CloseHandle(IntPtr handle);
private static IntPtr tokenHandle = new IntPtr(0);
private static WindowsImpersonationContext impersonatedUser;
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public extern static bool DuplicateToken(IntPtr ExistingTokenHandle,
int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle);
// If you incorporate this code into a DLL, be sure to demand that it
// runs with FullTrust.
[PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
public void Impersonate(string domainName, string userName, string password)
{
//try
{
// Use the unmanaged LogonUser function to get the user token for
// the specified user, domain, and password.
const int LOGON32_PROVIDER_DEFAULT = 0;
// Passing this parameter causes LogonUser to create a primary token.
const int LOGON32_LOGON_INTERACTIVE = 2;
tokenHandle = IntPtr.Zero;
// ---- Step - 1
// Call LogonUser to obtain a handle to an access token.
bool returnValue = LogonUser(userName,domainName,password,LOGON32_LOGON_INTERACTIVE,LOGON32_PROVIDER_DEFAULT,ref tokenHandle);
// tokenHandle - new security token
if (false == returnValue)
{
int ret = Marshal.GetLastWin32Error();
throw new System.ComponentModel.Win32Exception(ret);
}
// ---- Step - 2
WindowsIdentity newId = new WindowsIdentity(tokenHandle);
// ---- Step - 3
impersonatedUser = newId.Impersonate();
}
}
// Stops impersonation
public void Undo()
{
impersonatedUser.Undo();
// Free the tokens.
if (tokenHandle != IntPtr.Zero)
CloseHandle(tokenHandle);
}
计时器代码:
void polling_Elapsed(object sender, ElapsedEventArgs e)
{
try
{
StopPolling();
//doing some stuff some impersonation
StartPolling();
}
catch (Exception ex)
{
retries++;
if (retries < 10)
{
StartPolling();
}
}
}