SUMMARY
This article describes how to close another application
from within your application. This article also describes how to close a
specific instance of another application, such as Notepad, if more than one
instance of the application is running.
back to the topDeclare Variables
You must define several variables. Because these variables are
used in multiple methods, define them outside any procedure so that they remain
in scope.
The first variable is an array to hold the process objects
that the
GetProcessByName method returns. In this code, "procName" is a String variable
that is used to hold the name of the process:
private:
Process *processes[];
static String *procName = S"Notepad";
back to the topObtain a List of Application Instances
The following code for the
BuildList function is called each time a new instance of Notepad is
created. This example stores the process information in a
ListView control. The code to populate the
ListView control is included only for consistency with the complete
example that follows.
The most important part of this code is the call
to the
GetProcessByName method of the
Process class. This method returns an array of Process object pointers,
which can be iterated over by using a
For loop.
ListViewItem *itemAdd ;
ListView1->Items->Clear();
processes = Process::GetProcessesByName(procName);
for (int i = 0; i < processes->Length; i++)
{
itemAdd = ListView1->Items->Add(processes[i]->MainWindowTitle);
itemAdd->SubItems->Add(processes[i]->Id.ToString());
}
back to the topClose a Specific Instance of an Application
When you have multiple instances of an application running, if you
want to close one instance, you must differentiate between those processes.
This example uses the
Id property to differentiate between the processes. The
Id property and the
MainWindowTitle property are stored in the
ListView control.
This code gets the item that is currently
selected in the
ListView control, obtains a reference to the process by using the
GetProcessById method of the
Process class, and then closes that process by calling the
CloseMainWindow method. Note that you cannot rebuild the list before the process
has exited fully because the
WaitForExit method of the
Process class prevents this.
try
{
ListViewItem *lvi = ListView1->SelectedItems->get_Item(0);
ListViewItem::ListViewSubItem *lvsi = lvi->SubItems->get_Item(1);
int procID = System::Convert::ToInt32(lvsi->Text);
Process *tempProc=Process::GetProcessById(procID);
tempProc->CloseMainWindow();
tempProc->WaitForExit();
BuildList();
}
catch(...)
{
MessageBox::Show(S"Select a process in the ListView.");
}
back to the topClose All Instances of an Application
To close all instances of a particular application, walk the array
that the
GetProcessByName method returns, and then call the
CloseMainWindow method on each process object.
try
{
for (int i = 0; i < processes->Length; i++)
{
processes[i]->CloseMainWindow();
}
ListView1->Items->Clear();
}
catch (System::NullReferenceException *)
{
MessageBox::Show("No instances of Notepad running.");
}
back to the topStep-by-Step Example
- Create a new Managed C++ Application in Microsoft Visual
Studio .NET or Microsoft Visual
Studio 2005. To do this, follow these steps:
- Start Visual Studio .NET or Visual Studio 2005.
- On the File menu, point to
New, and then click Project.
- In the New Project dialog box, click
Visual C++ Projects under Project Types, and
then click Managed C++ Application for
Visual Studio .NET 2002, click Console Application (.NET) for Visual Studio .NET 2003, or click CLR Console Application for Visual Studio 2005 under
Templates.
- Type a file name in the Name
box.
- In Solution Explorer, open the project .cpp
file.
- Replace the code in the Code window with the following:
#include "stdafx.h"
#include <windows.h>
#ifdef MessageBox
#undef MessageBox
#endif
#using <mscorlib.dll>
#using "System.Dll"
#using "System.Windows.Forms.Dll"
#using "System.Drawing.Dll"
using namespace System;
using namespace System::Drawing;
using namespace System::Collections;
using namespace System::ComponentModel;
using namespace System::Windows::Forms;
using namespace System::Diagnostics;
namespace CloseApplication_mc
{
public __gc class Form1 : public Form
{
protected:
Button *btnCloseAll;
ColumnHeader *ColumnHeader2;
ColumnHeader *ColumnHeader1;
Button *btnLaunch1;
ListView *ListView1;
Button *btnClose1;
private:
Process *processes[];
static String *procName = S"Notepad";
static String *specialFolder = Environment::GetFolderPath(Environment::SpecialFolder::System);
public:
Form1()
{
InitForm();
}
protected:
void Dispose( bool disposing )
{
Form::Dispose(disposing);
}
private:
void InitForm()
{
btnClose1 = new Button();
ColumnHeader2 = new ColumnHeader();
ColumnHeader1 = new ColumnHeader();
btnCloseAll = new Button();
btnLaunch1 = new Button();
ListView1 = new ListView();
SuspendLayout();
//
// btnClose1
//
btnClose1->Location = Point(160, 176);
btnClose1->Name = S"btnClose1";
btnClose1->Size = System::Drawing::Size(112, 32);
btnClose1->TabIndex = 4;
btnClose1->Text = S"Close Selected Process";
btnClose1->Click += new System::EventHandler(this, btnClose1_Click);
Controls->Add(btnClose1);
//
// btnCloseAll
//
btnCloseAll->Location = Point(160, 216);
btnCloseAll->Name = S"btnCloseAll";
btnCloseAll->Size = System::Drawing::Size(112, 32);
btnCloseAll->TabIndex = 3;
btnCloseAll->Text = S"Close All Processes";
btnCloseAll->Click += new System::EventHandler(this, btnCloseAll_Click);
Controls->Add(btnCloseAll);
//
// btnLaunch1
//
btnLaunch1->Location = Point(32, 176);
btnLaunch1->Name = S"btnLaunch1";
btnLaunch1->Size = System::Drawing::Size(112, 72);
btnLaunch1->TabIndex = 1;
btnLaunch1->Text = S"Start Notepad";
btnLaunch1->Click += new System::EventHandler(this, btnLaunch1_Click);
Controls->Add(btnLaunch1);
//
// ColumnHeader2
//
ColumnHeader2->Text = S"Process ID";
ColumnHeader2->Width = 85;
//
// ColumnHeader1
//
ColumnHeader1->Text = S"Window Title";
ColumnHeader1->Width = 160;
//
// ListView1
//
ListView1->Columns->Add(ColumnHeader1);
ListView1->Columns->Add(ColumnHeader2);
ListView1->Location = Point(22, 8);
ListView1->MultiSelect = false;
ListView1->Name = S"ListView1";
ListView1->Size = System::Drawing::Size(250, 152);
ListView1->TabIndex = 7;
ListView1->View = View::Details;
Controls->Add(ListView1);
//
// Form1
//
AutoScaleBaseSize = System::Drawing::Size(5, 13);
ClientSize = System::Drawing::Size(292, 266);
Name = S"Form1";
Text = S"Process Example";
Closing += new System::ComponentModel::CancelEventHandler(this, closing);
Load += new System::EventHandler(this, Form1_Load);
ResumeLayout(false);
}
void BuildList()
{
ListViewItem *itemAdd ;
ListView1->Items->Clear();
processes = Process::GetProcessesByName(procName);
for (int i = 0; i < processes->Length; i++)
{
itemAdd = ListView1->Items->Add(processes[i]->MainWindowTitle);
itemAdd->SubItems->Add(processes[i]->Id.ToString());
}
}
void btnLaunch1_Click(Object *sender, EventArgs *e)
{
ProcessStartInfo *p = new ProcessStartInfo();
p->FileName = String::Concat(specialFolder, S"\\eula.txt");
p->WindowStyle = ProcessWindowStyle::Minimized ;
Process *proc = Process::Start(p);
proc->WaitForInputIdle();
BuildList();
}
void Form1_Load(Object *sender, EventArgs *e)
{
}
void btnClose1_Click(Object *sender, EventArgs *e)
{
try
{
ListViewItem *lvi = ListView1->SelectedItems->get_Item(0);
ListViewItem::ListViewSubItem *lvsi = lvi->SubItems->get_Item(1);
int procID = System::Convert::ToInt32(lvsi->Text);
Process *tempProc=Process::GetProcessById(procID);
tempProc->CloseMainWindow();
tempProc->WaitForExit();
BuildList();
}
catch(...)
{
MessageBox::Show(S"Select a process in the ListView before clicking this button.");
}
}
void btnCloseAll_Click(Object *sender, EventArgs *e)
{
if (processes != 0)
{
for (int i = 0; i < processes->Length; i++)
{
processes[i]->CloseMainWindow();
}
ListView1->Items->Clear();
}
}
void closing(Object *sender, System::ComponentModel::CancelEventArgs *e)
{
btnCloseAll_Click(this,e);
}
};
}
using namespace CloseApplication_mc;
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
Form1 *FormInstance = new Form1;
Application::Run(FormInstance);
return 0;
}
- Build and then run the application.
- Click Start Notepad one or more
times.
- Click an instance of Notepad in the
ListView box, and then click Close Process.
This closes the specific instance of Notepad that you selected. You can also
click Close All Processes to close all the instances of
Notepad that are running.
Note This article uses the
Id property of the
Process class to differentiate between instances of the application. The
Id property is good for this task because all process IDs are
unique. You can use the
WindowHandle property of a
Process object to get the same results. Although you can use other
properties, they are less suitable for this task. If you do not know the
process ID, or if you have the handle of the main window, you can also use the
MainWindowTitle property to help identify the correct instance. However, because
the
MainWindowTitle property may not be unique, you cannot guarantee that you are
referring to the correct window.
back to the top