Rohan Pas
Rohan Pas

Reputation: 177

How to detect if a new process is running on timer c#

How would I find out if a new process is running (not specific, just any new one), and add it to listView with its icon from timer.

Currently I have this, and all it does is reset the listview regardless if a new process is there or not. I want it to not reset the listview, and instead add the new one into the listview. As well, remove processes that are no longer there.

public UserControl5()
        {
            InitializeComponent();
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct SHFILEINFO
        {
            public IntPtr hIcon;
            public IntPtr iIcon;
            public uint dwAttributes;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
            public string szDisplayName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
            public string szTypeName;
        };

        class Win32
        {
            public const uint SHGFI_ICON = 0x100;
            public const uint SHGFI_LARGEICON = 0x0;    // 'Large icon
            public const uint SHGFI_SMALLICON = 0x1;    // 'Small icon

            [DllImport("shell32.dll")]
            public static extern IntPtr SHGetFileInfo(string pszPath,
                                        uint dwFileAttributes,
                                        ref SHFILEINFO psfi,
                                        uint cbSizeFileInfo,
                                        uint uFlags);
        }

        private int nIndex = 0;
        private void UserControl5_Load(object sender, EventArgs e)
        {
            timer1.Enabled = true;


        }
private void timer1_Tick(object sender, EventArgs e)
        {
            listView1.Items.Clear();
            listView1.View = View.Details;
            listView1.Columns.Clear();
            listView1.Columns.Add("Processes");
            listView1.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);

            IntPtr hImgSmall;    //the handle to the system image list
            IntPtr hImgLarge;    //the handle to the system image list
            string fName;        // 'the file name to get icon from
            SHFILEINFO shinfo = new SHFILEINFO();

            listView1.SmallImageList = imageList1;
            listView1.LargeImageList = imageList1;


            Process[] processlist = Process.GetProcesses();

            foreach (Process process in processlist)
            {
                try
                {
                    String fileName = process.MainModule.FileName;
                    String processName = process.ProcessName;
                    hImgSmall = Win32.SHGetFileInfo(fileName, 0, ref shinfo,
                                                  (uint)Marshal.SizeOf(shinfo),
                                                   Win32.SHGFI_ICON |
                                                   Win32.SHGFI_SMALLICON);

                    //Use this to get the large Icon
                    //hImgLarge = SHGetFileInfo(fName, 0,
                    //ref shinfo, (uint)Marshal.SizeOf(shinfo),
                    //Win32.SHGFI_ICON | Win32.SHGFI_LARGEICON);
                    //The icon is returned in the hIcon member of the shinfo
                    //struct
                    System.Drawing.Icon myIcon = System.Drawing.Icon.FromHandle(shinfo.hIcon);

                    imageList1.Images.Add(myIcon);

                    //Add file name and icon to listview



                    listView1.Items.Add(Path.GetFileName(System.IO.Path.GetFileNameWithoutExtension(fileName)), nIndex++);
                    //nIndex++


                }
                catch
                {

                }
            }
            }

private void listView1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (listView1.SelectedIndices.Count <= 0)
            {
                return;
            }
            int intselectedindex = listView1.SelectedIndices[0];
            if (intselectedindex >= 0)
            {
                textBox1.Text = listView1.Items[intselectedindex].Text;
            }
        }

Upvotes: 1

Views: 666

Answers (1)

Reza Aghaei
Reza Aghaei

Reputation: 125197

Option 1 - As an option you can use a timer and fetch processes information using Process.GetProcesses() or using a WMI query on Win32_Process. Then compare existing list of processes with new list based on their ProcessId. Then you can find processes and removed processes.

Option 2 - As another option you can use ManagementEventWatcher to monitor Win32_ProcessStartTrace to detect start of new proceses and Win32_ProcessStopTrace to detect stopping processes.

You can subscribe EventArrived event of ManagementEventWatcher which monitors an object. In this event, you can find informations like ProcessID and ProcessName about process.

When using the watcher and the event, keep in mind:

  • The EventArrived will raise in a different thread than UI thread and if you need to manipulate UI, you need to use Invoke.
  • You should stop the watcher and dispose it in OnFormClosed.
  • You should add a reference to System.Management.dll.
  • You should add using System.Management;
  • You need to run your program as administrator.

Example

ManagementEventWatcher startWatcher;
ManagementEventWatcher stopWatcher;
protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);
    startWatcher = new ManagementEventWatcher("Select * From Win32_ProcessStartTrace");
    startWatcher.EventArrived += new EventArrivedEventHandler(startWatcher_EventArrived);
    stopWatcher = new ManagementEventWatcher("Select * From Win32_ProcessStopTrace");
    stopWatcher.EventArrived += new EventArrivedEventHandler(stopWatcher_EventArrived);
    startWatcher.Start();
    stopWatcher.Start();
}
void startWatcher_EventArrived(object sender, EventArrivedEventArgs e)
{
    MessageBox.Show(string.Format("{0} started", (string)e.NewEvent["ProcessName"]));
}
void stopWatcher_EventArrived(object sender, EventArrivedEventArgs e)
{
    MessageBox.Show(string.Format("{0} stopped", (string)e.NewEvent["ProcessName"]));
}
protected override void OnFormClosed(FormClosedEventArgs e)
{
    startWatcher.Stop();
    stopWatcher.Stop();
    startWatcher.Dispose();
    stopWatcher.Dispose();
    base.OnFormClosed(e);
}

Upvotes: 1

Related Questions