-5

I am looking for a way to get all the excel processes initiated by my winform application. Is it even possible? If I can get list of all running processes using

 Process[] processes = Process.GetProcesses();

Shouldn't there be a way to get processes started by a certain applciation?

Mostafiz
  • 7,243
  • 3
  • 28
  • 42
SamuraiJack
  • 5,131
  • 15
  • 89
  • 195
  • Why don't you just keep a list yourself as you start each process? How are you starting the Excel processes? Without more specifics, this question is far too broad. Please fix it by including a good [mcve] that shows clearly what you're doing, what you've tried, and explaining precisely what specific difficulty you've run into. – Peter Duniho Aug 23 '16 at 04:53
  • If you are starting the process with your own coded application, then you should maintain a list of those processes when you create them. Show some code where you are creating Excel process to get a good answer. – Sarvesh Mishra Aug 23 '16 at 04:58
  • @PeterDuniho what if the application was not created by me? And I have been asked to find a quick fix. – SamuraiJack Aug 23 '16 at 05:00
  • @SarveshMishra it is a complicated application and i have been asked to find a quick fix. I am trying to kill all excel processes started by this application. – SamuraiJack Aug 23 '16 at 05:02
  • 1
    _"what if the application was not created by me?"_ -- does your question not read _"get all the excel processes initiated by **my** winform application"_? If this is a program not written by you, your question is even more confusing. – Peter Duniho Aug 23 '16 at 05:03
  • Fact is, depending on how the Excel processes are actually started, what you want to do may not be possible at all. If it is however, you will want to look at these posts: http://stackoverflow.com/questions/394816/how-to-get-parent-process-in-net-in-managed-way and http://stackoverflow.com/questions/1125958/how-do-i-discover-how-my-process-was-started. Frankly, you should have looked at them before you posted your question. – Peter Duniho Aug 23 '16 at 05:06
  • @PeterDuniho it also says "your" application in main question. Doesnt mean mean "your application" or "or my application" literally. Somebody wrote this application and now i am working on it further. I think this question pretty simple to understand. How can one get a list of all excel processes started by your application. – SamuraiJack Aug 23 '16 at 05:06
  • @Arbaaz keeping a reference of initiated process will not complicate it any further. If you don't know where in code it is being created then it would become really difficult to obtain all the processes started. – Sarvesh Mishra Aug 23 '16 at 05:08
  • @PeterDuniho I am not looking to find parent process. What I am looking for is... I have a winform application .. which opens excel processes.. quite a few times it does not close them. I am looking for a quick fix to close all those excel processes when i click on a button "close all excel", that were started by this application – SamuraiJack Aug 23 '16 at 05:09
  • @Arbaaz get all the Excel processes, check their parent. If parent is your own app, kill the Excel process. – Sarvesh Mishra Aug 23 '16 at 05:13
  • _"I am not looking to find parent process"_ -- sure you are. You claim your process is the parent process. So, if you find the parent process of candidate Excel processes and that happens to be your process, that's an Excel process you want to kill. Whether this will work in your case, who knows? You have provided practically _no_ information to base any sort of answer on. But you might as well try, since you don't seem inclined to improve the question. – Peter Duniho Aug 23 '16 at 05:16
  • @SarveshMishra that is exactly my question Sarvesh, how you do it? – SamuraiJack Aug 23 '16 at 05:16
  • @PeterDuniho Yes,I looking for a way to find child processes or processes whose parent is my application. I would have improved my question if I could. Right now just try to understand my question this way. I have a winform application. When I click on a button, I want to kill all excel processes started by this application. – SamuraiJack Aug 23 '16 at 05:19
  • @PeterDuniho I have found solution. I have posted it as answer. This is what I wanted to achieve. – SamuraiJack Aug 23 '16 at 09:32

3 Answers3

1

First add this namespaces to your application

using Excel = Microsoft.Office.Interop.Excel;
using System.Runtime.InteropServices;
using System.Diagnostics;

then in your application reference user32 dll

class ExcelClass
{
    [DllImport("user32.dll")]
    static extern int GetWindowThreadProcessId(int hWnd, out int lpdwProcessId);

    Process GetId(Excel.Application excelApp)
    {
        int id;
        GetWindowThreadProcessId(excelApp.Hwnd, out id);
        return Process.GetProcessById(id);
    }
}
Mostafiz
  • 7,243
  • 3
  • 28
  • 42
  • from what I understand, I will have to pass the object of `Excel.Application` and it will return list of process started by that object, right? is there a way to find excel processes started by my application, all Excel.Application objects in the application? I mean without having to pass Excel.Application object. – SamuraiJack Aug 23 '16 at 04:58
  • take a look at this SO thread http://stackoverflow.com/questions/35366658/retrieve-excel-application-from-process-id – Mostafiz Aug 23 '16 at 05:18
0

Okay I have found the answer myself. I am sharing it just in case someone needs it.

 int myappid = Process.GetCurrentProcess().Id;
            Process[] processes = Process.GetProcessesByName("EXCEL");          

            foreach (Process prs in processes)
            {
                var query = string.Format("SELECT ParentProcessId FROM Win32_Process WHERE ProcessId = {0}", prs.Id);
                var search = new ManagementObjectSearcher("root\\CIMV2", query);
                var results = search.Get().GetEnumerator();
                results.MoveNext();
                var queryObj = results.Current;
                var parentId = (uint)queryObj["ParentProcessId"];

                if (ProcessExists((int)parentId))
                {
                    var parent = Process.GetProcessById((int)parentId);

                    if (parent.Id == myappid)
                    {
                        prs.Kill();
                    }
                }
            }

 private bool ProcessExists(int id)
        {
            return Process.GetProcesses().Any(x => x.Id == id);
        }

In the above code Process[] processes = Process.GetProcesses(); would give me all the processes. I am looping though the collection and finding parent process id of each. If parent id matches my application process id and the name of the child process is excel, I kill it.

SamuraiJack
  • 5,131
  • 15
  • 89
  • 195
0

Just an FYI, this bit of code I used to get existing excel processes and then kill excel processes created by my app.

Hashtable myHashtable;



    private void Get_Already_Running_Excel()
    {
        Process[] AllProcesses = Process.GetProcessesByName("excel");
        myHashtable = new Hashtable();
        int iCount = 0;

        foreach (Process ExcelProcess in AllProcesses)
        {
            myHashtable.Add(ExcelProcess.Id, iCount);
            iCount = iCount + 1;
        }
    }

    public void Close_User_Excel()
    {
        Process[] AllProcesses = Process.GetProcessesByName("excel");       

        // check to kill the right process
        foreach (Process ExcelProcess in AllProcesses)
        {
            if (myHashtable.ContainsKey(ExcelProcess.Id) == false)
            { ExcelProcess.Kill(); }
        }

        AllProcesses = null;
    }
Robert Altman
  • 161
  • 11
  • This doesn't do anything except terminate _every_ Excel process that was running at the time you call `Get_Already_Running_Excel()`. Since process IDs can be reused, it could also kill a different Excel process than the one you observed earlier. There's nothing about this code that meets your requirement that the Excel processes be the ones your program started. (And the use of the archaic `Hashtable` type is a poor choice as well; not that a correct solution would need any sort of collection, but if you're going to use something it should be `HashSet`.) – Peter Duniho Aug 23 '16 at 15:53
  • I was thinking the same thing. What if user starts excel himself manually after starting his application. This code will close that one as well.See my solution, it seems more appropriate. – SamuraiJack Aug 24 '16 at 12:28
  • @Arbaaz you guys are correct. This code really only works if nothing else is starting an excel process other than the application. – Robert Altman Aug 24 '16 at 12:57