无法在已用时的Timer事件中模拟用户

时间:2017-11-07 12:17:30

标签: c# windows service timer impersonation

在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();
            }
        }
    }

0 个答案:

没有答案