locked
Process.StartInfo.Arguments RRS feed

  • Question

  • I am trying to GET the arguments that were used to start a process (console app). But it always seems to be returning empty string. Is there a way to get the command line arguments that were passed to start a process?

    Example: Lets say I opened "notepad" using a file name on the command line. Then I need a way in .NET to get the file name value that was passed to this process.

    string sProcessName = "notepad";
    foreach(
    Process oActiveProcess in Process.GetProcessesByName(sProcessName
    ))
    {
      // Get the parameters passed to the process when it was started
      Console.WriteLine(" => " + oActiveProcess.StartInfo.Arguments);
    }


    The real-world problem: I want to able to prevent an instance of my console app from running if there is already an instance alive which was invoked using the same set of command line arguments. i.e. if an instance of "MyApp.exe 100 200" is running I dont want another instance of "MyApp.exe 100 200" to run, but "MyApp.exe 300 400" can run. I am not able to do this using the Process.StartInfo.Arguments - I can understand .NET may not be able to get this value from a running process. Is there any other way I can get this information?

    Thanks

    Raj

     

    Tuesday, May 2, 2006 9:56 PM

Answers

  • You can use following code :

        static List<string> cmdLines = new List<string>();
        static void GetWindbgProcessesRunning()
        {
            ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\CIMV2",
                "Select * from Win32_Process where Name=\"notepad.exe\"");
            cmdLines.Clear();
    
            foreach (ManagementObject obj in searcher.Get())
            {
                cmdLines.Add(obj["CommandLine"].ToString());
            }
        }
    • Marked as answer by DumboDotNet Friday, November 6, 2009 3:29 PM
    Thursday, October 29, 2009 8:48 AM

All replies

  • to prevent another process of your app starting, it can be done as I have done it for one of my applications in .NET 2.0

     

    you need to get a list of processes running, then compare each process with the current application's assembly/product name

     

    example:

     



    Process[] theListOfProcesses = Process.GetProcessesByName(Application.ProductName, Environment.MachineName);
    if (theListOfProcesses > 1)
    {
       //another instance is running, notify user and exit application
    }

     

    • Unmarked as answer by DumboDotNet Friday, November 6, 2009 3:29 PM
    Tuesday, May 2, 2006 10:19 PM
  • This is because if the process was not started with Process.Start then the StartInfo will not return the arguments passed.

    From MSDN:

    "If you did not use the Start method to start a process, the StartInfo property does not reflect the parameters used to start the process. For example, if you use GetProcesses to get an array of processes running on the computer, the StartInfo property of each Process does not contain the original file name or arguments used to start the process."

    Tuesday, May 2, 2006 10:55 PM
  • As mentioned, getting the command line for a random, running process isn't easy.  There are 3 paths you can take to solve your problem.  Two requiring more work would be:

    1) Get the command-line.  The only way I'm aware of is directly accessing the process memory.  I'm not sure how easily it would translate to managed code (C#), but one article can be found at:   http://www.codeproject.com/threads/CmdLine.asp.

    2) Interprocess communication.  Look up various techniques to have one process talk to another via pipes, sockets, WM_COPYDATA, or other mechanisms.

     

    The last option, however, is to queue the data yourself.  Since you own all the processes, you can have each application store the data of it's running state, in the registry, memory mapped file, or some other external cache.  Each instance would merely check this location on start - to see what else is running.

    The biggest issue with this approach is guaranteeing it's cleaned up after an application closes - something a critical stop or exception would prevent.

     

    • Unmarked as answer by DumboDotNet Friday, November 6, 2009 3:29 PM
    Wednesday, May 3, 2006 4:21 AM
  • Thanks everybody for the responses.

    John: I did consider the options 1 and 3. Since they have the downsides, as you pointed out, I had to look for other ways to solve this.

    I am running my app using the WinXP SP2 "Schedule Tasks" setup. I have already created individual tasks each with different arguments. I have scheduled them to run every 10 minutes. Lets say:

    Task A is [MyApp.exe 100 200]

    Task B is [MyApp.exe 300 400]

    Task A and B can run simultaneously.

    Now I just need a way to tell the windows scheduler - "if Task A is already running dont start Task A again". Though it needs to start an instance every 10 minutes, it shouldnt if that task is already running. I couldnt get the scheduler to do this. If that cant be done - Is there a way to find, in my app (managed), which schedule tasks are running currently? That way I can stop the app if the task is already running.

    Thanks

    Raj

     

    Wednesday, May 3, 2006 9:03 PM
  • Maybe I am over-simplifying this, but won't you be able to do this using the Task Scheduler API?
    Wednesday, May 3, 2006 10:38 PM
  • Is there a managed way to access this API? Does System.Management or any other .net assembly provide this?

    Thanks

    Raj

     

    Thursday, May 4, 2006 9:13 PM
  • You can use following code :

        static List<string> cmdLines = new List<string>();
        static void GetWindbgProcessesRunning()
        {
            ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\CIMV2",
                "Select * from Win32_Process where Name=\"notepad.exe\"");
            cmdLines.Clear();
    
            foreach (ManagementObject obj in searcher.Get())
            {
                cmdLines.Add(obj["CommandLine"].ToString());
            }
        }
    • Marked as answer by DumboDotNet Friday, November 6, 2009 3:29 PM
    Thursday, October 29, 2009 8:48 AM
  • Wow! Thanks Sandy.

    After almost three and a half years I am happy to see this resolved!
    Now I dont even remember what I was doing back in 05/06 and how it all worked out.
    But I am sure I will need this again sometime in future.

    Thank you!!
    Friday, November 6, 2009 3:46 PM