public new void Kill()
 {
     using (var hProcess = SafeProcessHandle.OpenProcess(SafeProcessHandle.ProcessAccessFlags.Terminate, false, Id))
     {
         if (hProcess.IsInvalid)
         {
             var error = Marshal.GetLastWin32Error();
             _debugLogger.Error("AsyncImpersonationProcess ({0}): Cannot kill proces; OpenProcess failed. ErrorCode: {1} ({2})", StartInfo.FileName, error, new Win32Exception(error).Message);
             return;
         }
         if (!TerminateProcess(hProcess, EXITCODE_OK))
         {
             var error = Marshal.GetLastWin32Error();
             _debugLogger.Error("AsyncImpersonationProcess ({0}): Cannot kill proces; TerminateProcess failed. ErrorCode: {1} ({2})", StartInfo.FileName, error, new Win32Exception(error).Message);
         }
     }
 }
示例#2
0
        /// <summary>
        /// Инициализация информации о модулях
        /// </summary>
        /// <param name="mainModuleName">главный модуль симулятора (fs9.exe)</param>
        /// <returns>true - simulator was found</returns>
        public InitializationState Initialize(string mainModuleName)
        {
            const string systemName = "MemoryPatcher";

            // Без этого процессор грузится на 50%, пока симулятор не загружен
            if (DateTime.Now < _lastTimeTryToInitialize + new TimeSpan(0, 0, 0, 2))
            {
                if (_lastInitStatus != null)
                {
                    return(_lastInitStatus);
                }
                return(new InitializationState
                {
                    System = systemName,
                    ErrorCode = (int)InitializationStatus.AttemptToInitializeTooOften,
                    ErrorMessage = "Attempted to initialize too often",
                    IsOk = false
                });
            }
            _lastTimeTryToInitialize = DateTime.Now;
            try
            {
                lock (_modules)
                {
                    _modules.Clear();
                    var runningProcesses         = Process.GetProcesses();
                    var processesWithCorrectName = runningProcesses.Where(x => x.ProcessName.ToLower() == mainModuleName.ToLower());
                    if (processesWithCorrectName.Count() == 0)
                    {
                        _lastInitStatus = new InitializationState
                        {
                            System       = systemName,
                            ErrorCode    = (int)InitializationStatus.ModuleToPatchWasNotFound,
                            ErrorMessage = "Module '" + mainModuleName + "' was not found in process list",
                            IsOk         = false
                        };
                        return(_lastInitStatus);
                    }
                    if (processesWithCorrectName.Count() > 1)
                    {
                        _lastInitStatus = new InitializationState
                        {
                            System       = systemName,
                            ErrorCode    = (int)InitializationStatus.MultipleModulesFound,
                            ErrorMessage = "Multiple modules with name '" + mainModuleName + "' were found, don't know how to select correct one",
                            IsOk         = false
                        };
                        return(_lastInitStatus);
                    }
                    var process = processesWithCorrectName.First();
                    _mainModuleProcessId = process.Id;
                    _processHandle       = SafeProcessHandle.OpenProcess(ProcessAccessFlags.VmOperation | ProcessAccessFlags.QueryInformation | ProcessAccessFlags.VmRead | ProcessAccessFlags.VmWrite, false, _mainModuleProcessId);
                    for (var i = 0; i < process.Modules.Count; i++)
                    {
                        var info = new ModuleInfo
                        {
                            BaseAddress = process.Modules[i].BaseAddress,
                            Size        = (uint)process.Modules[i].ModuleMemorySize,
                            Name        = process.Modules[i].ModuleName
                        };
                        if (!_modules.ContainsKey(info.Name))
                        {
                            _modules.Add(info.Name, info);
                        }
                    }
                    process.Close();

                    _lastInitStatus = new InitializationState
                    {
                        System       = systemName,
                        ErrorCode    = (int)InitializationStatus.Ok,
                        ErrorMessage = "",
                        IsOk         = true
                    };
                    return(_lastInitStatus);
                }
            }
            catch (Exception ex)
            {
                _lastInitStatus = new InitializationState
                {
                    System       = systemName,
                    ErrorCode    = (int)InitializationStatus.Exception,
                    ErrorMessage = "An exception occuted: " + ex.Message,
                    IsOk         = false
                };
                return(_lastInitStatus);
            }
        }
示例#3
0
        private void TimerCallback(object state)
        {
            try
            {
                // Get process handles.
                var process = Process.GetCurrentProcess();
                var pid     = process.Id;
                var handle1 = process.Handle;

                if (!_initialEmptyComplete)
                {
                    // The first time through, empty the working set and return.
                    _initialEmptyComplete = true;
                    NativeMethods.EmptyWorkingSet(handle1);
                    return;
                }

                // Get memory usage.
                var safeHandle = SafeProcessHandle.OpenProcess(pid, ProcessAccessFlags.QueryInformation);
                var handle2    = safeHandle.DangerousGetHandle();
                var counters   = new PROCESS_MEMORY_COUNTERS();
                NativeMethods.GetProcessMemoryInfo(handle2, out counters, (uint)Marshal.SizeOf(counters));

                var workingSetSize = counters.WorkingSetSize / 1024 / 1024;
                if (workingSetSize < _mediumThreshold)
                {
                    // We're below the medium threshold, nothing to do.
                    return;
                }

                if (workingSetSize < _highThreshold)
                {
                    // We're above the medium threshold and below the high threshold. Get the
                    // time since the last empty and bail if it was less than 10 minutes ago.
                    var timeSinceLastEmpty = TimeSpan.FromTicks(
                        Stopwatch.GetTimestamp() - _lastEmptyTimestamp);

                    if (timeSinceLastEmpty < TimeSpan.FromMinutes(10))
                    {
                        return;
                    }
                }

                // Empty the working set.
                NativeMethods.EmptyWorkingSet(handle1);
                _lastEmptyTimestamp = Stopwatch.GetTimestamp();

                // Get updated memory usage.
                NativeMethods.GetProcessMemoryInfo(handle2, out counters, (uint)Marshal.SizeOf(counters));

                // Record the operation in the log.
                var newWorkingSetSize = counters.WorkingSetSize / 1024 / 1024;
                var highUsageDetected = workingSetSize > _highThreshold;

                Logger.Info(
                    "{0} memory threshold ({1}MB) exceeded - working set reduced from: {2} to: {3}",
                    highUsageDetected ? "High" : "Medium",
                    highUsageDetected ? _highThreshold : _mediumThreshold,
                    workingSetSize,
                    newWorkingSetSize);
            }
            catch (Exception e)
            {
                Logger.Error("Error monitoring working set size", e);
            }
            finally
            {
                Thread.MemoryBarrier();
                if (!_disposed)
                {
                    _timer.Change(TimeSpan.FromSeconds(30), TimeSpan.FromMilliseconds(-1));
                }
            }
        }