65.9K
CodeProject is changing. Read more.
Home

Test for additional instances of a process – short and simple

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.20/5 (2 votes)

Jan 4, 2006

CPOL

4 min read

viewsIcon

31123

A simple method to test for additional instances of an application.

Introduction

For many applications, it is necessary to ensure that only one instance of the program is running at a time. Data management applications which transfer data to an archive folder should not run twice at the same time. Especially in the deleting of files, the behaviour of the application cannot be determined for each case if a second instance is running.

In a data management application I implemented, lots of result files of an industrial test system were to be transferred, depending on the content, to several folders. Some of them were to be deleted and others to be updated. For this, the application has to go through the working folders. All these activities have to be registered in a log file. This application runs for some minutes. I had to ensure that nothing incalculable happens if a user starts the application for a second time. For this, I was looking for a very short and simple solution.

In this article, the possibilities of C# .NET are discussed, including a little experiment. After that, a very simple method for universal use is presented.

Background

The namespace System.Diagnostics.Process provides all the information which is necessary for this. The process names and process identifiers of all processes are available from GetProcesses(). Here, only the process name and the process identifier are necessary.

We need GetCurrentProcess().Id to get the process ID number, and GetCurrentProcess().ProcessName to get the process name of our own process. For user started processes, the process name is usually the same as the filename of the exe file from which the process is started. The process ID and name of our own processes are to be found out from the list of all processes.

An experiment with a small example code

The sample program below is for doing an experiment to show the context. It is implemented as a console application to keep it as simple as possible. This console application lists all process names and their process IDs. For this, a process array is set up and filled with all process information of the system. A foreach loop is used to go through the list of process identifiers and process names. The namespace GetCurrentProcess is used to get the information of the process to compare.

using System;

namespace InstanzenAuflisten
{
    class Class1
    {
        [STAThread]
        static void Main(string[] args)
        {
            string strRemark;
            // remarks to insert into the console output
    
            Console.WriteLine("all processes of the system");
            Console.WriteLine();

            System.Diagnostics.Process[] myProcesses = 
              System.Diagnostics.Process.GetProcesses();
              // all processes into the array

            foreach(System.Diagnostics.Process p in myProcesses)
            {
                if(p.Id == System.Diagnostics.Process.GetCurrentProcess().Id)
                // the process id is unique in the system
                    strRemark = " < = my application";
                else
                    strRemark = "";

                if(p.ProcessName == 
                  System.Diagnostics.Process.GetCurrentProcess().ProcessName && 
                  p.Id != System.Diagnostics.Process.GetCurrentProcess().Id)
                {
                    // an additional instance of the same
                    // application has the same name, 
                    // but an other process id

                    strRemark = " <= another instance of my application";
                }
    
                Console.WriteLine("{0}  {1}  {2}",p.ProcessName,p.Id,strRemark);
            }

            Console.WriteLine();
            Console.ReadLine();
            // this ReadLine command is to hold the application open
        }
    }
}

The running process has the same process identifier and the same process name like the compared process. This case is marked here as " < = my application" and marks our process itself. If a process is found which has the same process name as the compared process but another process ID, then another instance of our program in the system is found. This case is marked with " <= another instance of my application".

To do the experiment, the exe file (InstanzenAuflisten.exe) of the source code below has to be started twice. The listing of the application started at first shows the list of running processes. Only one line is marked as “my application”. This is the process with the same name and identifier as the current process, my "own" process.

To keep the applications running for a longer time, a ConsoleReadline command is inserted to keep the application open until the Enter key is pressed.

Now, the application has to be started for a second time without pressing the Enter key in the first application. The listing shows here another process identifier (because it is another process) with the same name as “my application”, but the first started application is also to be seen, marked with "another instance …".

The first started application shows a console output like this:

all processes of the system
 
wmiprvse 320
wmiprvse 4064
...
smss 816
ltmoh 2420
InstanzenAuflisten 4024 < = my application
svchost 1348
iexplore 384
svchost 1132
FrameworkService 596
...
System 4
notepad 1072
awhost32 536
Idle 0
 

In the second screen, the first started application is to be seen as “another instance” with its process identifier we know from the first listing. Both listings are shortened a little here.

all processes of the system
 
wmiprvse 320
nipalsm 2136
...
UpdaterUI 2584
svchost 1396
InstanzenAuflisten 1120 < = my application
explorer 404
almxptray 2436
naPrdMgr 388
...
smss 816
ltmoh 2420
InstanzenAuflisten 4024 <= another instance of my application
svchost 1348
iexplore 384
svchost 1132
FrameworkService 596
...
System 4
notepad 1072
awhost32 536
 

With this knowledge, it is simple to build a universal testing method for additional instances like it's shown below, named as OnlyInstance().

The code for universal use

The source code of the universal test method:

/// <summary>
/// Test, if a second instance is running.
/// Return: false, if additional instance, in other case false.
/// </summary>

static bool OnlyInstance()
{
    Process[] myProcesses = Process.GetProcesses();
    // array of all processes of the system

    bool bOnly = true;

    foreach(Process p in myProcesses)
    {
        if(p.ProcessName == Process.GetCurrentProcess().ProcessName 
                          && p.Id != Process.GetCurrentProcess().Id)
        // an additional instance has the same
        // process name, but a different process id
        {
            bOnly = false;
            break; // finish, if a second instance is found
        }
    }
    return bOnly;
}

Using the code

This method can be used to test for additional instances of an application in the following way:

if(OnlyInstance())
{
    ... // do what to do if there is no other instance
}
else
{
    ... // do whot to do if there are other instances
        // (e.g. send a message and terminate)
}

This is a very simple and short method to take care about additional instances of a running application.