日期:2014-05-20  浏览次数:21633 次

程序频繁访问共享,导致本地lsass进程占用超高的cpu资源,最终系统崩溃
我在使用win32的api,LogUser方法来模拟用户登录,访问远程共享文件,由于每两秒访问4次(4个线程),从不同文件夹下copy文件,如果运行七八个小时,发现lsass进程几乎占光了cpu的资源,我感觉是这个方法运用不当造成的,但是找不到原因所在,下面是模拟用户登录的方法:
C# code

public PImpersonate(string DomainName, string strUserName, string strPassword)
        {
            _DomainName = DomainName;
            _strUserName = strUserName;
            _strPassword = strPassword;
            isconnect = false;
        }
        public void Login()
        {
            if (!isconnect)
            {
                try
                {
                    bool result = LogonUser(_strUserName, _DomainName,
                                            _strPassword,
                                            LogonSessionType.NewCredentials,
                                            LogonProvider.Default,
                                            out token);
                    if (result)
                    {
                        result = DuplicateToken(token, 2, ref dupToken);
                        WindowsIdentity id = new WindowsIdentity(dupToken);
                        impersonatedUser = id.Impersonate();
                        isconnect = true;
                    }
                    else
                    {
                        isconnect = false;
                    }
                }
                catch
                {
                    isconnect = false;
                }
            }
        }

        public void Logout()
        {
            try
            {
                if (impersonatedUser != null)
                {
                    impersonatedUser.Undo();
                    isconnect = false;
                }
                // Free the token
                if (token != IntPtr.Zero)
                {
                    CloseHandle(token);
                }
            }
            catch
            {
            }
        }

        [DllImport("advapi32.dll", SetLastError = true)]
        static extern bool LogonUser(
          string principal,
          string authority,
          string password,
          LogonSessionType logonType,
          LogonProvider logonProvider,
          out IntPtr token);

        [DllImport("advapi32.dll", CharSet = CharSet.Auto,
        SetLastError = true)]
        public extern static bool DuplicateToken(IntPtr
        existingTokenHandle,
        int SECURITY_IMPERSONATION_LEVEL, ref IntPtr
        duplicateTokenHandle);

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern bool CloseHandle(IntPtr handle);
        enum LogonSessionType : uint
        {
            Interactive = 2,
            Network,
            Batch,
            Service,
            NetworkCleartext = 8,
            NewCredentials
        }
        enum LogonProvider : uint
        {
            Default = 0, // default for platform (use this!)
            WinNT35,     // sends smoke signals to authority
            WinNT40,     // uses NTLM
            WinNT50      // negotiates Kerb or NTLM
        }



访问共享的代码是:
C# code

             while (true)
                {
                                                         
                    //与共享建立连接
                    PImpersonate connectremote = new PImpersonate(remoteip, remoteuser, remotepassword);
                    connectremote.Login();

                    FileInfo[] filelist = null;
                    try
                    {
                        filelist = new DirectoryInfo("\\\\" + remoteip + "\\" + sharefolder).GetFiles("*." + sourcefileformat);

                        foreach (FileInfo file in filelist)
                        {
                            DateTime dtnow = DateTime.Now;
                            TimeSpan t = dtnow - file.LastWriteTime;
                            if (t.TotalSeconds > 2)
                            {
                                try
                                {
                                    file.CopyTo(localpath + "\\" + file.Name, true);
                                }
                                catch (Exception ex)
                                {
                                    Log.writelog("##copy share file exception.\r\n\t"+ex.ToString()+"File is from " + "\\\\" + remoteip + "\\" + sharefolder + "\\" + file.Name + , logpath);
                                    Thread.Sleep(100);
                                    continue;
                                }
                                Thread.Sleep(10);
                                try
                                {
                                    file.Delete();
                                    Log.writelog("Copy finish.File frome " + "\\\\" + remoteip + "\\" + sharefolder + "\\" + file.Name + ",and save to " + localpath + "\\" + file.Name, logpath);
                                }
                                catch(Exception ex)
                                {
                                    Thread.Sleep(100);
                                    File.Delete(localpath + "\\" + file.Name);
                                    Log.writelog("##Delete share file exception.\r\n\t" + ex.ToString() + "File is from " + "\\\\" + remoteip + "\\" + sharefolder + "\\" + file.Name,logpath);
                                    continue;
                                }
                            }
                            Thread.Sleep(200);
                        }
                    }
                    catch(Exception ex)
                    {
                        connectremote.Logout();
                        Log.writelog("## Here..copy....file visit exception...***"+ex.ToString(), logpath);
                        Thread.Sleep(20000);
                        continue;
                    }                    }
                    //成功,断开连接
                    connectremote.Logout();
                    Thread.Sleep(2000);
                    #endregion
                }