Tải bản đầy đủ - 0 (trang)
4-15. Start a New Process

4-15. Start a New Process

Tải bản đầy đủ - 0trang

CHAPTER 4 ■ THREADS, PROCESSES, AND SYNCHRONIZATION



Solution

Call one of the static Start method overloads of the System.Diagnostics.Process class. Specify the

configuration details of the process you want to start as individual arguments to the Start method or in

a System.Diagnostics.ProcessStartInfo object that you pass to the Start method.



How It Works

The Process class provides a managed representation of an operating system process and provides a

simple mechanism through which you can execute both managed and unmanaged applications. The

Process class implements five static overloads of the Start method, which you use to start a new

process. All these methods return a Process object that represents the newly started process. Two of

these overloads are methods that allow you to specify only the name and arguments to pass to the new

process. For example, the following statements both execute Notepad in a new process:

// Execute notepad.exe with no command-line arguments.

Process.Start("notepad.exe");

// Execute notepad.exe passing the name of the file to open as a

// command-line argument.

Process.Start("notepad.exe", "SomeFile.txt");

Another two overloads extend these and allow you to specify the name of a Windows user who the

process should run as. You must specify the username, password, and Windows domain. The password

is specified as a System.Security.SecureString for added security. (See recipe 11-18 for more

information about the SecureString class.) Here is an example:

System.Security.SecureString mySecureString = new System.Security.SecureString();

// Obtain a password and place in SecureString (see Recipe 11-18).

// Execute notepad.exe with no command-line arguments.

Process.Start("notepad.exe", "allen", mySecureString, "MyDomain");

// Execute notepad.exe passing the name of the file to open as a

// command-line argument.

Process.Start("notepad.exe", "SomeFile.txt", "allen", mySecureString, "MyDomain");

The remaining static overload requires you to create a ProcessStartInfo object configured with the

details of the process you want to run; using the ProcessStartInfo object provides greater control over

the behavior and configuration of the new process. Table 4-3 summarizes some of the commonly used

properties of the ProcessStartInfo class.



196



www.it-ebooks.info



CHAPTER 4 ■ THREADS, PROCESSES, AND SYNCHRONIZATION



Table 4-3. Properties of the ProcessStartInfo Class



Property



Description



Arguments



The command-line arguments to pass to the new process.



Domain



A string containing the Windows domain name to which the user belongs.



ErrorDialog



If Process.Start cannot start the specified process, it will throw a

System.ComponentModel.Win32Exception. If ErrorDialog is true, Start displays an

error dialog box to the user before throwing the exception.



FileName



The name of the application to start. You can also specify any type of file for which

you have configured an application association. For example, you could specify a

file with a .doc or an .xls extension, which would cause Microsoft Word or

Microsoft Excel to run.



LoadUserProfile



A bool indicating whether the user’s profile should be loaded from the registry when

the new process is started.



Password



A SecureString containing the password of the user.



UserName



A string containing the name of the user to use when starting the process.



WindowStyle



A member of the System.Diagnostics.ProcessWindowStyle enumeration, which

controls how the window is displayed. Valid values include Hidden, Maximized,

Minimized, and Normal.



WorkingDirectory



The fully qualified name of the initial directory for the new process.



When finished with a Process object, you should dispose of it in order to release system resources—

call Close, call Dispose, or create the Process object within the scope of a using statement.



■ Note Disposing of a Process object does not affect the underlying system process, which will continue to run.



The Code

The following example uses Process to execute Notepad in a maximized window and open a file named

C:\Temp\file.txt. After creation, the example calls the Process.WaitForExit method, which blocks the

calling thread until a process terminates or a specified timeout expires. This method returns true if the

process ends before the timeout and returns false otherwise.



197



www.it-ebooks.info



CHAPTER 4 ■ THREADS, PROCESSES, AND SYNCHRONIZATION



using System;

using System.Diagnostics;

namespace Apress.VisualCSharpRecipes.Chapter04

{

class Recipe04_15

{

public static void Main()

{

// Create a ProcessStartInfo object and configure it with the

// information required to run the new process.

ProcessStartInfo startInfo = new ProcessStartInfo();

startInfo.FileName = "notepad.exe";

startInfo.Arguments = "file.txt";

startInfo.WorkingDirectory = @"C:\Temp";

startInfo.WindowStyle = ProcessWindowStyle.Maximized;

startInfo.ErrorDialog = true;

// Declare a new Process object.

Process process;

try

{

// Start the new process.

process = Process.Start(startInfo);

// Wait for the new process to terminate before exiting.

Console.WriteLine("Waiting 30 seconds for process to finish.");

if (process.WaitForExit(30000))

{

Console.WriteLine("Process terminated.");

}

else

{

Console.WriteLine("Timed out waiting for process to end.");

}

}

catch (Exception ex)

{

Console.WriteLine("Could not start process.");

Console.WriteLine(ex);

}



198



www.it-ebooks.info



CHAPTER 4 ■ THREADS, PROCESSES, AND SYNCHRONIZATION



// Wait to continue.

Console.WriteLine(Environment.NewLine);

Console.WriteLine("Main method complete. Press Enter.");

Console.ReadLine();

}

}

}



4-16. Terminate a Process

Problem

You need to terminate a process such as an application or a service.



Solution

Obtain a Process object representing the operating system process you want to terminate. For Windowsbased applications, call Process.CloseMainWindow to send a close message to the application’s main

window. For Windows-based applications that ignore CloseMainWindow, or for non-Windows-based

applications, call the Process.Kill method.



How It Works

If you start a new process from managed code using the Process class (discussed in recipe 4-15), you can

terminate the process using the Process object that represents the new process. You can also obtain

Process objects that refer to other currently running processes using the static methods of the Process

class summarized in Table 4-4.

Table 4-4. Methods for Obtaining Process References



Method



Description



GetCurrentProcess



Returns a Process object representing the currently active process.



GetProcessById



Returns a Process object representing the process with the specified ID. This is

the process ID (PID) you can get using Windows Task Manager.



GetProcesses



Returns an array of Process objects representing all currently active processes.



GetProcessesByName



Returns an array of Process objects representing all currently active processes

with a specified friendly name. The friendly name is the name of the executable

excluding file extension or path; for example, a friendly name could be notepad

or calc.



199



www.it-ebooks.info



CHAPTER 4 ■ THREADS, PROCESSES, AND SYNCHRONIZATION



Once you have a Process object representing the process you want to terminate, you need to call

either the CloseMainWindow method or the Kill method. The CloseMainWindow method posts a WM_CLOSE

message to a Windows-based application’s main window. This method has the same effect as if the user

had closed the main window using the system menu, and it gives the application the opportunity to

perform its normal shutdown routine. CloseMainWindow will not terminate applications that do not have

a main window or applications with a disabled main window—possibly because a modal dialog box is

currently displayed. Under such circumstances, CloseMainWindow will return false.

CloseMainWindow returns true if the close message was successfully sent, but this does not guarantee

that the process is actually terminated. For example, applications used to edit data will usually give the

user the opportunity to save unsaved data if a close message is received. The user usually has the chance

to cancel the close operation under such circumstances. This means CloseMainWindow will return true,

but the application will still be running once the user cancels. You can use the Process.WaitForExit

method to signal process termination and the Process.HasExited property to test whether a process has

terminated. Alternatively, you can use the Kill method.

The Kill method simply terminates a process immediately; the user has no chance to stop the

termination, and all unsaved data is lost. Kill is the only option for terminating Windows-based

applications that do not respond to CloseMainWindow and for terminating non-Windows-based

applications.



The Code

The following example starts a new instance of Notepad, waits 5 seconds, and then terminates the

Notepad process. The example first tries to terminate the process using CloseMainWindow. If

CloseMainWindow returns false, or the Notepad process is still running after CloseMainWindow is called, the

example calls Kill and forces the Notepad process to terminate; you can force CloseMainWindow to return

false by leaving the File Open dialog box open.

using System;

using System.Threading;

using System.Diagnostics;

namespace Apress.VisualCSharpRecipes.Chapter04

{

class Recipe04_16

{

public static void Main()

{

// Create a new Process and run notepad.exe.

using (Process process =

Process.Start("notepad.exe",@"c:\SomeFile.txt"))

{

// Wait for 5 seconds and terminate the notepad process.

Console.WriteLine(

"Waiting 5 seconds before terminating notepad.exe.");

Thread.Sleep(5000);

// Terminate notepad process.

Console.WriteLine("Terminating Notepad with CloseMainWindow.");



200



www.it-ebooks.info



CHAPTER 4 ■ THREADS, PROCESSES, AND SYNCHRONIZATION



// Try to send a close message to the main window.

if (!process.CloseMainWindow())

{

// Close message did not get sent - Kill Notepad.

Console.WriteLine("CloseMainWindow returned false - " +

" terminating Notepad with Kill.");

process.Kill();

}

else

{

// Close message sent successfully; wait for 2 seconds

// for termination confirmation before resorting to Kill.

if (!process.WaitForExit(2000))

{

Console.WriteLine("CloseMainWindow failed to" +

" terminate - terminating Notepad with Kill.");

process.Kill();

}

}

}

// Wait to continue.

Console.WriteLine("Main method complete. Press Enter.");

Console.ReadLine();

}

}

}



4-17. Ensure That Only One Instance of an Application Can

Execute Concurrently

Problem

You need to ensure that a user can have only one instance of an application running concurrently.



Solution

Create a named System.Threading.Mutex object, and have your application try to acquire ownership of it

at startup.



How It Works

The Mutex provides a mechanism for synchronizing the execution of threads across process boundaries

and in addition provides a convenient mechanism through which to ensure that only a single instance of

an application is running concurrently. By trying to acquire ownership of a named Mutex at startup and



201



www.it-ebooks.info



CHAPTER 4 ■ THREADS, PROCESSES, AND SYNCHRONIZATION



exiting if the Mutex cannot be acquired, you can ensure that only one instance of your application is

running.



The Code

This example uses a Mutex named MutexExample to ensure that only a single instance of the example can

execute:

using System;

using System.Threading;

namespace Apress.VisualCSharpRecipes.Chapter04

{

class Recipe04_17

{

public static void Main()

{

// A Boolean that indicates whether this application has

// initial ownership of the Mutex.

bool ownsMutex;

// Attempt to create and take ownership of a Mutex named

// MutexExample.

using (Mutex mutex =

new Mutex(true, "MutexExample", out ownsMutex))

{

// If the application owns the Mutex it can continue to execute;

// otherwise, the application should exit.

if (ownsMutex)

{

Console.WriteLine("This application currently owns the" +

" mutex named MutexExample. Additional instances of" +

" this application will not run until you release" +

" the mutex by pressing Enter.");

Console.ReadLine();

// Release the mutex.

mutex.ReleaseMutex();

}

else

{

Console.WriteLine("Another instance of this application " +

" already owns the mutex named MutexExample. This" +

" instance of the application will terminate.");

}

}



202



www.it-ebooks.info



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

4-15. Start a New Process

Tải bản đầy đủ ngay(0 tr)

×