예제 #1
0
        public string[] ReadWhitelist()
        {
            if (File.Exists(_whitelistPath))
            {
                try
                {
                    //if it does, read in all of it's lines
                    string[] lines = File.ReadAllLines(_whitelistPath);

                    return(lines);
                }
                catch (Exception e)
                {
                    Prune.HandleError(true, 1, "Error while reading the whitelist file\n" + e.Message);
                }
            }
            else
            {
                try
                {
                    //If the whitelist file does not exist, create a blank text file for future use
                    File.CreateText(_whitelistPath);
                    PruneEvents.PRUNE_EVENT_PROVIDER.EventWriteNO_WHITELIST_EVENT();

                    return(null);
                }
                catch (Exception e)
                {
                    Prune.HandleError(true, 1, "Error creating whitelist file\n" + e.Message);
                }
            }

            return(null);
        }
예제 #2
0
        //The service is stopping, so we need to dump the current cache to a file
        public void DumpCache()
        {
            //Only write contents of the cache to a file if there is something in the cache
            if (_cache.Count > 0)
            {
                //Create file name and full path
                string fileName = _rootDirectory + "\\" + WhitelistEntry + "\\" + WhitelistEntry + "_" + ProcessId + "-" + _cacheStart.ToString("yyyyMMdd_HHmmss") + "-" + DateTime.Now.ToString("yyyyMMdd_HHmmss") + ".json";

                //Create the process directory if it does not already exist
                Directory.CreateDirectory(_rootDirectory + "\\" + WhitelistEntry + "\\");

                try
                {
                    //convert list to json
                    string cacheJson = JsonConvert.SerializeObject(_cache);

                    //write json to the file
                    using (StreamWriter sw = new StreamWriter(fileName))
                    {
                        sw.Write(cacheJson);
                        sw.Flush();
                    }

                    _unloggedFiles.Add(fileName);
                }
                catch (Exception e)
                {
                    Prune.HandleError(_isService, 0, "Failed to dump cache to " + fileName + " on service shutdown" + Environment.NewLine + e.Message);
                }
            }
        }
예제 #3
0
        public ServiceConfiguration ReadConfiguration()
        {
            //Check if the config file exists
            if (!File.Exists(_configPath))
            {
                //The configuration file does not exist, so we need to create it with default values
                try
                {
                    //Create the configuration object
                    ServiceConfiguration config = new ServiceConfiguration(LogIntervalDefault, CacheIntervalDefault, MonitorIntervalDefault, WhitelistIntervalDefault, ConfigIntervalDefault);

                    //Create the json string for the configuration object
                    string configString = JsonConvert.SerializeObject(config, Formatting.Indented);

                    //Write the config json string to the config file
                    using (StreamWriter sw = new StreamWriter(_configPath, false))
                    {
                        sw.Write(configString);
                        sw.Flush();
                    }

                    return(config);
                }
                catch (Exception e)
                {
                    Prune.HandleError(true, 1, "Error while creating config file and writing default setting\n" + e.Message);
                }
            }
            else
            {
                //The config file exists, so we need to read it
                try
                {
                    //Get the text and parse the json into a ServiceConfiguration object
                    string configFileText       = File.ReadAllText(_configPath);
                    ServiceConfiguration config = JsonConvert.DeserializeObject <ServiceConfiguration>(configFileText);

                    return(config);
                }
                catch (Exception e)
                {
                    Prune.HandleError(true, 1, "Error reading configuration file\n" + e.Message);
                }
            }

            return(null);
        }
예제 #4
0
        //Initialize the counters for the current process
        public void InitializeInstance()
        {
            if (ProcessFinished)
            {
                return;
            }

            //Set up the performance counters
            SetPerfCounters();

            //set the start and end times
            if (DateTime.Equals(DateTime.MinValue, _logStart))
            {
                _logStart = DateTime.Now;
            }
            if (DateTime.Equals(DateTime.MinValue, _cacheStart))
            {
                _cacheStart = DateTime.Now;
            }

            //Different interval finishes are needed if this is run from the command line or the service
            if (_isService)
            {
                //From the service, we need to set the log and cache interval end times
                _logFinish   = Prune.CalculateIntervalFinishTime(_logStart, _logInterval);
                _cacheFinish = Prune.CalculateIntervalFinishTime(_cacheStart, _writeCacheInterval);
            }
            else
            {
                //From the command line, we don't use the logFinish and cacheFinish is simply the current time plus the length to monitor
                _cacheFinish = DateTime.Now.AddSeconds(_writeCacheInterval);
            }

            //create the current file suffix for use later in the cache files
            _fileSuffix = "-" + _cacheStart.ToString("yyyyMMdd_HHmmss") + "-" + _cacheFinish.ToString("yyyyMMdd_HHmmss") + ".json";
        }
예제 #5
0
        //Record the next data point from each counter and add it to the cache list
        public bool GetData()
        {
            if (ProcessFinished)
            {
                return(false);
            }

            //If the current cache interval is over
            if (_isService && DateTime.Compare(_cacheFinish, DateTime.Now) < 0)
            {
                //adjust the cache times to the next interval
                _cacheStart  = _cacheFinish;
                _cacheFinish = _cacheStart.AddSeconds(_writeCacheInterval);

                //write the current cache to a file before adding new information to the cache
                WriteCacheToFile();
            }

            if (_cpuPc == null || _privBytesPc == null || _workingSetPc == null)
            {
                //The perf counters are null, so we need to try to reassign them. They may have been nulled because another instance with the same name closed and broke things
                //If the process really did exit, then they will remain null after this call
                SetPerfCounters();
            }

            //add the data inside of a DataPoint object
            //The Cpu value is divided by the total cpu threshold to convert it to a percent out of 100, where 100% is total utilization of all processor cores
            //Only do this if all of the Perf Counters are initialized properly
            if (_cpuPc != null && _privBytesPc != null && _workingSetPc != null)
            {
                try {
                    if (_cpuPc.InstanceName.CompareTo(Prune.GetInstanceNameForProcessId(this.ProcessId)) != 0)
                    {
                        //The PID we are monitoring exists but does not match our the instance name used by the perf counters
                        //	Therefore, we must reset them so they are correct. Nulling them will skip this data gathering but allow
                        //	us to reset them on the next data call
                        NullPerformanceCounters();
                    }
                } catch (Exception) {
                    //This happens if the current pid we are monitoring no longer exists, so we tell this instance to close and null the perf counters on all
                    //	other processes that share the same name to prevent instance name confusion and errors
                    FinishMonitoring();
                    return(false);
                }

                double cpuAdjusted;
                double privValue;
                double workingValue;

                //Get the data from the performance counters in a try catch in case one of the counters has closed
                try
                {
                    cpuAdjusted  = (_cpuPc.NextValue() / _totalCpuThreshold) * 100;
                    privValue    = _privBytesPc.NextValue();
                    workingValue = _workingSetPc.NextValue();
                }
                catch (Exception) {
                    if (_isService)
                    {
                        PruneEvents.PRUNE_EVENT_PROVIDER.EventWriteCANNOT_GATHER_EVENT(WhitelistEntry + "_" + ProcessId);
                    }

                    FinishMonitoring();
                    return(false);
                }

                //reset localEtwCounters
                Prune.Counters localEtwCounters = null;

                //Get the ETW data, which includes Disk I/O and Network I/O
                try
                {
                    localEtwCounters = Prune.GetEtwDataForProcess(ProcessId);
                }
                catch (Exception e)
                {
                    Prune.HandleError(_isService, 0, "Error getting ETW Data:" + Environment.NewLine + e.Message);
                }

                //If nothing is retrieved, create a new Counter object with all values set to 0
                if (localEtwCounters == null)
                {
                    localEtwCounters = new Prune.Counters();
                }

                //Add the data point to the cache
                DataPoint tempDataPoint = new DataPoint(cpuAdjusted, Convert.ToInt64(privValue), Convert.ToInt64(workingValue), localEtwCounters.DiskReadBytes, localEtwCounters.DiskWriteBytes,
                                                        localEtwCounters.DiskReadOperations, localEtwCounters.DiskWriteOperations, localEtwCounters.UdpSent, localEtwCounters.UdpReceived,
                                                        localEtwCounters.TcpSent, localEtwCounters.TcpReceived, localEtwCounters.ConnectionsSent, localEtwCounters.ConnectionsSentCount, localEtwCounters.ConnectionsReceived,
                                                        localEtwCounters.ConnectionsReceivedCount, DateTime.Now);
                _cache.Add(tempDataPoint);

                return(true);
            }
            else
            {
                FinishMonitoring();
                return(false);
            }
        }
예제 #6
0
        public void LogDataFromFiles(List <string> list, bool loggingFromOldFiles)
        {
            //the number of data points processed
            uint dataPointCount = 0;

            //variables to hold calculations
            double averageCpu = 0;
            double maxCpu     = double.MinValue;
            double minCpu     = double.MaxValue;

            long averagePriv = 0;
            long maxPriv     = long.MinValue;
            long minPriv     = long.MaxValue;

            long averageWorking = 0;
            long maxWorking     = long.MinValue;
            long minWorking     = long.MaxValue;

            long averageTcpOut = 0;
            long maxTcpOut     = long.MinValue;
            long minTcpOut     = long.MaxValue;

            long averageTcpIn = 0;
            long maxTcpIn     = long.MinValue;
            long minTcpIn     = long.MaxValue;

            long averageUdpOut = 0;
            long maxUdpOut     = long.MinValue;
            long minUdpOut     = long.MaxValue;

            long averageUdpIn = 0;
            long maxUdpIn     = long.MinValue;
            long minUdpIn     = long.MaxValue;

            long averageDiskReadBytes = 0;
            long maxDiskReadBytes     = long.MinValue;
            long minDiskReadBytes     = long.MaxValue;

            long averageDiskWriteBytes = 0;
            long maxDiskWriteBytes     = long.MinValue;
            long minDiskWriteBytes     = long.MaxValue;

            double averageDiskReadOps = 0;
            long   maxDiskReadOps     = long.MinValue;
            long   minDiskReadOps     = long.MaxValue;

            double averageDiskWriteOps = 0;
            long   maxDiskWriteOps     = long.MinValue;
            long   minDiskWriteOps     = long.MaxValue;

            Dictionary <string, TcpConnectionData> connectionData = new Dictionary <string, TcpConnectionData>();

            if (list == null || list.Count == 0)
            {
                return;
            }

            //loop through all unlogged files
            foreach (string fileName in list)
            {
                List <DataPoint> fileList = new List <DataPoint>();

                try
                {
                    //parse file into an object
                    string fileText = File.ReadAllText(fileName);

                    //Doing this the hard way because the default deserialization methods produce null value errors for some reason
                    //Deserailize the array
                    dynamic o = JsonConvert.DeserializeObject(fileText);

                    //Loop through each array element
                    foreach (Newtonsoft.Json.Linq.JObject obj in (Newtonsoft.Json.Linq.JArray)o)
                    {
                        //Create a new DataPoint from each property of the object, each of which must be converted to the correct type with ToObject<>()
                        fileList.Add(new DataPoint(obj["CpuVal"].ToObject <double>(), obj["PrivBytesVal"].ToObject <long>(), obj["WorkingBytesVal"].ToObject <long>(),
                                                   obj["DiskBytesReadVal"].ToObject <long>(), obj["DiskBytesWriteVal"].ToObject <long>(), obj["DiskOpsReadVal"].ToObject <long>(),
                                                   obj["DiskOpsWriteVal"].ToObject <long>(), obj["UdpSent"].ToObject <long>(),
                                                   obj["UdpRecv"].ToObject <long>(), obj["TcpSent"].ToObject <long>(), obj["TcpRecv"].ToObject <long>(), obj["ConnectionsSent"].ToObject <Dictionary <string, long> >(),
                                                   obj["ConnectionsSentCount"].ToObject <Dictionary <string, long> >(), obj["ConnectionsReceived"].ToObject <Dictionary <string, long> >(),
                                                   obj["ConnectionsReceivedCount"].ToObject <Dictionary <string, long> >(), obj["LogTime"].ToObject <DateTime>())
                                     );
                    }
                }
                catch (Exception e)
                {
                    Prune.HandleError(_isService, 0, "Failed to read file " + fileName + " and deserialize it" + Environment.NewLine + e.Message);
                    return;
                }

                if (fileList == null || fileList.Count == 0)
                {
                    continue;
                }

                //loop through the array doing the math as normal
                //increment dataPointCount in the dataPoint loop
                foreach (DataPoint data in fileList)
                {
                    dataPointCount++;

                    double cpu            = data.CpuVal;
                    long   priv           = data.PrivBytesVal;
                    long   work           = data.WorkingBytesVal;
                    long   tcpIn          = data.TcpRecv;
                    long   tcpOut         = data.TcpSent;
                    long   udpIn          = data.UdpRecv;
                    long   udpOut         = data.UdpSent;
                    long   diskReadBytes  = data.DiskBytesReadVal;
                    long   diskWriteBytes = data.DiskBytesWriteVal;
                    long   diskReadOps    = data.DiskOpsReadVal;
                    long   diskWriteOps   = data.DiskOpsWriteVal;

                    averageCpu            += cpu;
                    averagePriv           += priv;
                    averageWorking        += work;
                    averageTcpIn          += tcpIn;
                    averageTcpOut         += tcpOut;
                    averageUdpIn          += udpIn;
                    averageUdpOut         += udpOut;
                    averageDiskReadBytes  += diskReadBytes;
                    averageDiskWriteBytes += diskWriteBytes;
                    averageDiskReadOps    += diskReadOps;
                    averageDiskWriteOps   += diskWriteOps;

                    if (cpu > maxCpu)
                    {
                        maxCpu = cpu;
                    }
                    if (cpu < minCpu)
                    {
                        minCpu = cpu;
                    }

                    if (priv > maxPriv)
                    {
                        maxPriv = priv;
                    }
                    if (priv < minPriv)
                    {
                        minPriv = priv;
                    }

                    if (work > maxWorking)
                    {
                        maxWorking = work;
                    }
                    if (work < minWorking)
                    {
                        minWorking = work;
                    }

                    if (tcpIn > maxTcpIn)
                    {
                        maxTcpIn = tcpIn;
                    }
                    if (tcpIn < minTcpIn)
                    {
                        minTcpIn = tcpIn;
                    }

                    if (tcpOut > maxTcpOut)
                    {
                        maxTcpOut = tcpOut;
                    }
                    if (tcpOut < minTcpOut)
                    {
                        minTcpOut = tcpOut;
                    }

                    if (udpIn > maxUdpIn)
                    {
                        maxUdpIn = udpIn;
                    }
                    if (udpIn < minUdpIn)
                    {
                        minUdpIn = udpIn;
                    }

                    if (udpOut > maxUdpOut)
                    {
                        maxUdpOut = udpOut;
                    }
                    if (udpOut < minUdpOut)
                    {
                        minUdpOut = udpOut;
                    }

                    if (diskReadBytes > maxDiskReadBytes)
                    {
                        maxDiskReadBytes = diskReadBytes;
                    }
                    if (diskReadBytes < minDiskReadBytes)
                    {
                        minDiskReadBytes = diskReadBytes;
                    }

                    if (diskWriteBytes > maxDiskWriteBytes)
                    {
                        maxDiskWriteBytes = diskWriteBytes;
                    }
                    if (diskWriteBytes < minDiskWriteBytes)
                    {
                        minDiskWriteBytes = diskWriteBytes;
                    }

                    if (diskReadOps > maxDiskReadOps)
                    {
                        maxDiskReadOps = diskReadOps;
                    }
                    if (diskReadOps < minDiskReadOps)
                    {
                        minDiskReadOps = diskReadOps;
                    }

                    if (diskWriteOps > maxDiskWriteOps)
                    {
                        maxDiskWriteOps = diskWriteOps;
                    }
                    if (diskWriteOps < minDiskWriteOps)
                    {
                        minDiskWriteOps = diskWriteOps;
                    }

                    //Add connection sent bytes to our DataPoint object
                    foreach (string key in data.ConnectionsSent.Keys)
                    {
                        //First make sure the key is present in dictionary
                        if (!connectionData.ContainsKey(key))
                        {
                            connectionData.Add(key, new TcpConnectionData(key));
                        }

                        //add the data
                        connectionData[key].AddOutData(data.ConnectionsSent[key]);
                    }

                    //Add connection sent count to our DataPoint object
                    foreach (string key in data.ConnectionsSentCount.Keys)
                    {
                        if (!connectionData.ContainsKey(key))
                        {
                            connectionData.Add(key, new TcpConnectionData(key));
                        }

                        connectionData[key].AddOutCount(data.ConnectionsSentCount[key]);
                    }

                    //Add connection received bytes to our DataPoint object
                    foreach (string key in data.ConnectionsReceived.Keys)
                    {
                        if (!connectionData.ContainsKey(key))
                        {
                            connectionData.Add(key, new TcpConnectionData(key));
                        }

                        connectionData[key].AddInData(data.ConnectionsReceived[key]);
                    }

                    //Add connection received count to our DataPoint object
                    foreach (string key in data.ConnectionsReceivedCount.Keys)
                    {
                        if (!connectionData.ContainsKey(key))
                        {
                            connectionData.Add(key, new TcpConnectionData(key));
                        }

                        connectionData[key].AddInCount(data.ConnectionsReceivedCount[key]);
                    }
                }

                string[] fileNameSplit   = fileName.Split('\\');
                string   loggedDirectory = _rootDirectory + "\\" + WhitelistEntry + "\\logged\\";
                string   path2           = loggedDirectory + fileNameSplit[fileNameSplit.Length - 1];

                try
                {
                    //Move the file, that has been completely processed, into the logged subfolder
                    Directory.CreateDirectory(loggedDirectory);

                    if (File.Exists(path2))
                    {
                        File.Delete(path2);
                    }

                    //Move the file to the logged directory
                    File.Move(fileName, path2);
                }
                catch (Exception e)
                {
                    Prune.HandleError(_isService, 0, "Failed to move file " + fileName + " to " + loggedDirectory + fileNameSplit[fileNameSplit.Length - 1] + " after logging" + Environment.NewLine + e.Message);
                }
            }

            if (dataPointCount == 0)
            {
                return;
            }

            //Get a few total for the I/O related measures
            long totalTcpIn          = averageTcpIn;
            long totalTcpOut         = averageTcpOut;
            long totalUdpIn          = averageUdpIn;
            long totalUdpOut         = averageUdpOut;
            long totalDiskReadBytes  = averageDiskReadBytes;
            long totalDiskWriteBytes = averageDiskWriteBytes;
            long totalDiskReadOps    = (long)averageDiskReadOps;
            long totalDiskWriteOps   = (long)averageDiskWriteOps;

            //divide the sums to get averages
            averageCpu            /= dataPointCount;
            averagePriv           /= dataPointCount;
            averageWorking        /= dataPointCount;
            averageTcpIn          /= dataPointCount;
            averageTcpOut         /= dataPointCount;
            averageUdpIn          /= dataPointCount;
            averageUdpOut         /= dataPointCount;
            averageDiskReadBytes  /= dataPointCount;
            averageDiskReadOps    /= dataPointCount;
            averageDiskWriteBytes /= dataPointCount;
            averageDiskWriteOps   /= dataPointCount;

            try
            {
                //Create array of strings used for TCP connection information
                string[] Connections;

                if (connectionData.Count != 0)
                {
                    Connections = new string[connectionData.Count];
                }
                else
                {
                    Connections = new string[0];
                    //Connections[0] = "No Connections";
                }

                int counter = 0;
                foreach (TcpConnectionData data in connectionData.Values)
                {
                    data.CalculateStats();
                    Connections[counter] = data.ToString();
                    counter++;
                }

                string processors     = string.Join("\0", Prune.Processors);
                string disks          = string.Join("\0", Prune.Disks);
                string tcpConnections = string.Join("\0", Connections);

                try
                {
                    //call the event
                    bool returnVal = PruneEvents.PRUNE_EVENT_PROVIDER.EventWritePROCESS_REPORT_EVENT(WhitelistEntry + "_" + ProcessId,
                                                                                                     dataPointCount, Convert.ToUInt32(Prune.Processors.Length), Convert.ToUInt32(Prune.Disks.Length), processors, disks,
                                                                                                     Prune.ComputerManufacturer, Prune.ComputerModel, Prune.ComputerProcessorNum, Prune.RamSize, minCpu, maxCpu,
                                                                                                     averageCpu, minWorking, maxWorking, averageWorking, minPriv, maxPriv, averagePriv, totalDiskReadBytes,
                                                                                                     minDiskReadBytes, maxDiskReadBytes, averageDiskReadBytes, totalDiskWriteBytes, minDiskWriteBytes,
                                                                                                     maxDiskWriteBytes, averageDiskWriteBytes, totalDiskReadOps, minDiskReadOps, maxDiskReadOps, averageDiskReadOps,
                                                                                                     totalDiskWriteOps, minDiskWriteOps, maxDiskWriteOps, averageDiskWriteOps, totalTcpIn, minTcpIn, maxTcpIn,
                                                                                                     averageTcpIn, totalTcpOut, minTcpOut, maxTcpOut, averageTcpOut, totalUdpIn, minUdpIn, maxUdpIn, averageUdpIn,
                                                                                                     totalUdpOut, minUdpOut, maxUdpOut, averageUdpOut, Convert.ToUInt32(Connections.Length), tcpConnections);
                } catch (Exception e) {
                    Prune.HandleError(_isService, 0, "Error printing data report event" + Environment.NewLine + e.Message);
                }
            }
            catch (Exception e)
            {
                Prune.HandleError(_isService, 0, "Error outputting statistics to log" + Environment.NewLine + e.Message);
            }

            //If all of the performance counters are null, then we can stop monitoring this process
            if (_cpuPc == null && _privBytesPc == null && _workingSetPc == null)
            {
                ProcessFinished = true;
            }

            //If this is not logging files left over from a previous running of the tool, then advance the log interval times
            if (!loggingFromOldFiles)
            {
                _logStart  = _logFinish;
                _logFinish = _logStart.AddSeconds(_logInterval);
            }
        }
예제 #7
0
        //Go through the currently cached data and write it to a file
        public void WriteCacheToFile()
        {
            //Only write contents of the cache to a file if there is something in the cache
            if (_cache.Count > 0)
            {
                //create the full path and file name
                string directory = _rootDirectory + "\\" + WhitelistEntry;

                //If this is being used form the command line tool, the file should go straight into
                //      The logged sub-directory of the process directory
                if (!_isService)
                {
                    directory = directory + "\\logged";
                }

                string fileName = directory + "\\" + WhitelistEntry + "_" + ProcessId + _fileSuffix;

                if (!_isService)
                {
                    Console.WriteLine("\nWriting to file: " + fileName);
                }

                if (!Directory.Exists(directory))
                {
                    Directory.CreateDirectory(directory);
                }

                try
                {
                    //convert the cache list to json format and write
                    string cacheJson = JsonConvert.SerializeObject(_cache, new JsonSerializerSettings()
                    {
                        NullValueHandling = NullValueHandling.Ignore
                    });

                    using (StreamWriter sw = new StreamWriter(fileName, false))
                    {
                        sw.Write(cacheJson);
                        sw.Flush();
                    }
                }
                catch (Exception e)
                {
                    Prune.HandleError(_isService, 0, "Error writing cache to file" + Environment.NewLine + e.Message);
                }

                //Only add the file to the unlogged file list if it was generated by the service
                //Additional code also only needed for service, as the command line tool ends after writing first file
                if (_isService)
                {
                    //add this file to the list of unlogged files
                    lock (_unloggedFiles)
                    {
                        _unloggedFiles.Add(fileName);
                    }

                    //recreate the file suffix for the next file
                    _fileSuffix = "-" + _cacheStart.ToString("yyyyMMdd_HHmmss") + "-" +
                                  _cacheFinish.ToString("yyyyMMdd_HHmmss") + ".json";

                    //clear the cache list for future use
                    _cache.Clear();
                }
            }

            //Only log from files if this is running from the service
            if (_isService)
            {
                //after the cache has been cleared, check to see if the logging interval has passed
                //  And verify that there is a file that needs logging
                if (DateTime.Compare(_logFinish, DateTime.MinValue) > 0 &&
                    DateTime.Compare(_logFinish, DateTime.Now) < 0 && _unloggedFiles.Count > 0)
                {
                    //if it has, launch a thread to process the information from the files and log the results
                    try
                    {
                        _loggingThread = new Thread(LogDataFromCacheFiles);
                        _loggingThread.Start();
                    }
                    catch (Exception e)
                    {
                        Prune.HandleError(_isService, 0, "Failed to start thread to log usage statistics" + Environment.NewLine + e.Message);
                    }
                }
            }
        }
예제 #8
0
        private void SetPerfCounters()
        {
            PerfCounterSem.WaitOne();

            //An additional check to prevent processes marked as finished from continuing
            if (ProcessFinished)
            {
                PerfCounterSem.Release();
                return;
            }

            string instanceName;

            //Get the instance name that corresponds to the process id
            try
            {
                instanceName = Prune.GetInstanceNameForProcessId(ProcessId);
            }
            catch (Exception e)
            {
                Prune.HandleError(_isService, 0, "Error getting instance name. Setting it to null. This error likely does not affect PRUNE's Functionality. " + Environment.NewLine + e.Message);
                instanceName = null;
            }

            //if the string is not null or empty, set up Perf Counters
            if (!String.IsNullOrWhiteSpace(instanceName))
            {
                try
                {
                    //Create the % processor time counter and start it
                    //the first next value call is required to begin gathering information on the process
                    _cpuPc = new PerformanceCounter("Process", "% Processor Time", instanceName, true);
                    _cpuPc.NextValue();
                }
                catch (Exception e)
                {
                    Prune.HandleError(_isService, 0, "Failed to initialize % Processor Time performance counter" + Environment.NewLine + e.Message);
                    PerfCounterSem.Release();
                    return;
                }

                try
                {
                    //create the private bytes counter and start it
                    _privBytesPc = new PerformanceCounter("Process", "Private Bytes", instanceName, true);
                    _privBytesPc.NextValue();
                }
                catch (Exception e)
                {
                    Prune.HandleError(_isService, 0, "Failed to initialize Private Bytes performance counter" + Environment.NewLine + e.Message);
                    PerfCounterSem.Release();
                    return;
                }

                try
                {
                    //create the working set counter and start it
                    _workingSetPc = new PerformanceCounter("Process", "Working Set - Private", instanceName, true);
                    _workingSetPc.NextValue();
                }
                catch (Exception e)
                {
                    Prune.HandleError(_isService, 0, "Failed to initialize Private Working Set performance counter" + Environment.NewLine + e.Message);
                    PerfCounterSem.Release();
                    return;
                }

                //give the counters a quarter of a second to ensure they start to gather data
                Thread.Sleep(250);
            }
            else
            {
                //The procName was null or empty
                FinishMonitoring();
            }

            PerfCounterSem.Release();
        }
예제 #9
0
        private void SetPerfCounters()
        {
            PerfCounterSem.WaitOne();

            //An additional check to prevent processes marked as finished from continuing
            if (ProcessFinished)
            {
                NullPerformanceCounters();
                PerfCounterSem.Release();
                return;
            }

            string instanceName;

            //get the name of the process from the PID
            string procNameTemp = Prune.GetProcessNameFromProcessId(ProcessId);

            //Get a list of all processes with that name
            _processesWithName = Prune.GetProcessesFromProcessName(procNameTemp);

            //Get the instance name that corresponds to the process id
            try
            {
                instanceName = Prune.GetInstanceNameForProcessId(ProcessId);
            }
            catch (Exception e)
            {
                Prune.HandleError(_isService, 0, "Error getting instance name. Setting it to null. This error likely does not affect PRUNE's Functionality. " + Environment.NewLine + e.Message);
                instanceName = null;
            }

            //if the string is not null or empty, set up Perf Counters
            if (!String.IsNullOrWhiteSpace(instanceName))
            {
                //For each process, set up an event handler for when a process exits
                //This is because if a process exits, the instance names of other processes with the same name may change
                //We need to use the instance name if we get the PID, so recalculate the correct instance name
                if (_isService)
                {
                    try {
                        foreach (Process proc in _processesWithName)
                        {
                            proc.EnableRaisingEvents = true;
                            proc.Exited += (sender, e) => { SetPerfCounters(); };
                        }
                    } catch (Exception) {
                        if (_isService)
                        {
                            PruneEvents.PRUNE_EVENT_PROVIDER.EventWriteEXIT_EVENT_ERROR_EVENT(WhitelistEntry + "_" +
                                                                                              ProcessId);
                        }
                    }
                }

                try
                {
                    //Create the % processor time counter and start it
                    //the first next value call is required to begin gathering information on the process
                    _cpuPc = new PerformanceCounter("Process", "% Processor Time", instanceName, true);
                    _cpuPc.NextValue();
                }
                catch (Exception e)
                {
                    Prune.HandleError(_isService, 0, "Failed to initialize % Processor Time performance counter" + Environment.NewLine + e.Message);
                    PerfCounterSem.Release();
                    return;
                }

                try
                {
                    //create the private bytes counter and start it
                    _privBytesPc = new PerformanceCounter("Process", "Private Bytes", instanceName, true);
                    _privBytesPc.NextValue();
                }
                catch (Exception e)
                {
                    Prune.HandleError(_isService, 0, "Failed to initialize Private Bytes performance counter" + Environment.NewLine + e.Message);
                    PerfCounterSem.Release();
                    return;
                }

                try
                {
                    //create the working set counter and start it
                    _workingSetPc = new PerformanceCounter("Process", "Working Set - Private", instanceName, true);
                    _workingSetPc.NextValue();
                }
                catch (Exception e)
                {
                    Prune.HandleError(_isService, 0, "Failed to initialize Private Working Set performance counter" + Environment.NewLine + e.Message);
                    PerfCounterSem.Release();
                    return;
                }

                //give the counters a quarter of a second to ensure they start to gather data
                Thread.Sleep(250);
            }
            else
            {
                //The procName was null or empty, so set them all to null
                FinishMonitoring();
            }

            PerfCounterSem.Release();
        }