在.net 开发RichClient应用程序中,有时要调用另外一个应用程序,并且在被调用的程序结束后,希望返回执行结果的状态。
下面的代码用appDomain 和 Process 两种技术实现这种应用:
1, 用process调用一个应用程序
appExePath: 应用程序
ProcessStartInfo p = new ProcessStartInfo (AppExePath);
p.WorkingDirectory = Path.GetDirectoryName(AppExePath);
//如果有参数就写在Arguments
p.Arguments = CommandLineString;
AppProcess = Process.Start (p);
//如果希望程序结束后返回结束状态
AppProcess.WaitForExit();
if (AppProcess.ExitCode == 2)
{
restartApp = true;
AppProcess = null;
StartApp_Process(true);
}
else
restartApp = false;
//AppProcess.ExitCode 返回一个int值。 被调用的程序在退出的时候可以设置Environment.ExitCode返回这个值,默认=0
//根据应用程序返回的值,可以做不同的处理。
2. 用AppDomain实现上述功能
AppDomain NewDomain = AppDomain.CreateDomain (
"New App Domain",
AppDomain.CurrentDomain.Evidence,
Path.GetDirectoryName(AppExePath)+@"\",
"",
false);
//Execute the app in the new appdomain
string[] cmdLineArgs;
cmdLineArgs = CommandLineArgs;
retValue = NewDomain.ExecuteAssembly(AppExePath,AppDomain.CurrentDomain.Evidence,cmdLineArgs);
//Unload the app domain
appDomain.Unload(NewDomain);
if (returnCode == 2)
{
restartApp = true;
}
else
restartApp = false;
这里retValue和应用Process返回的ExitCode一样,都是调用的程序在退出的时候的Environment.ExitCode值。
下面是详细的代码供大家参考
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Xml;
using System.Reflection;
using System.IO;
using System.Threading;
using System.Windows.Forms;
//**************************************************************
// AppStart Class
// This is the main class for appstart.exe
//**************************************************************
public class AppStart
{
public AppStart() {}
static string AppExePath;
static Process AppProcess;
static string[] CommandLineArgs;
static string[] RestartCommandLineArgs;
static string CommandLineString;
static string RestartCommandLineString;
//**************************************************************
// Main()
//**************************************************************
[STAThread]
static void Main(string[] args)
{
//Retrive cmdline to pass to new process
CommandLineString = "";
for (int i = 0; i < args.Length; i++)
{
CommandLineString = string.Format ("{0} {1}", CommandLineString, args[i]);
}
CommandLineString += " /appstartversion " + Assembly.GetExecutingAssembly().GetName().Version.ToString();
RestartCommandLineString = CommandLineString + " /restart ";
CommandLineArgs = new String[args.Length+2];
CommandLineArgs[CommandLineArgs.Length-2] = "/appstartversion";
CommandLineArgs[CommandLineArgs.Length-1] = Assembly.GetExecutingAssembly().GetName().Version.ToString();
RestartCommandLineArgs = new String[CommandLineArgs.Length+1];
RestartCommandLineArgs[RestartCommandLineArgs.Length-1] = "/restart";
AppStartConfig Config = LoadConfig();
if (Config.AppLaunchMode == AppStartConfig.LaunchModes.Process)
StartAndWait_Process();
else
StartAndWait_Domain();
}
/*********************************************************************
* StartAndWait_Domain()
* 应用AppDomain
**********************************************************************/
private static void StartAndWait_Domain()
{
bool restartApp = true;
int returnCode = 0;
while (restartApp)
{
try
{
returnCode = StartApp_Domain(false);
Debug.WriteLine(returnCode.ToString());
}
catch (Exception e)
{
Debug.WriteLine("APPLICATION STARTER: Process.WaitForExit() failed, it's possible the process is not running");
HandleTerminalError(e);
}
if (returnCode == 2)
{
restartApp = true;
}
else
restartApp = false;
}
}
/*********************************************************************
* StartAndWait_Process()
**********************************************************************/
private static void StartAndWait_Process()
{
bool restartApp = true;
StartApp_Process(false);
while (restartApp)
{
try
{
AppProcess.WaitForExit();
}
catch (Exception e)
{
Debug.WriteLine("APPLICATION STARTER: Process.WaitForExit() failed, it's possible the process is not running");
Debug.WriteLine("APPLICATION STARTER: " + e.ToString());
return;
}
if (AppProcess.ExitCode == 2)
{
restartApp = true;
AppProcess = null;
StartApp_Process(true);
}
else
restartApp = false;
}
}
/*********************************************************************
* StartApp_Domain()
**********************************************************************/
public static int StartApp_Domain(bool restartApp)
{
Debug.WriteLine("APPLICATION STARTER: Starting the app in a seperate domain");
//Load the config file
AppStartConfig Config;
Config = LoadConfig();
AppExePath = Config.AppExePath;
//Load the app
int retValue=0;
try
{
//Create the new app domain
AppDomain NewDomain = AppDomain.CreateDomain (
"New App Domain",
AppDomain.CurrentDomain.Evidence,
Path.GetDirectoryName(AppExePath)+@"\",
"",
false);
//Execute the app in the new appdomain
string[] cmdLineArgs;
if(restartApp)
cmdLineArgs = RestartCommandLineArgs;
else
cmdLineArgs = CommandLineArgs;
retValue = NewDomain.ExecuteAssembly(AppExePath,AppDomain.CurrentDomain.Evidence,cmdLineArgs);
//Unload the app domain
AppDomain.Unload(NewDomain);
}
catch (Exception e)
{
Debug.WriteLine("APPLICATION STARTER: Failed to start app at: " + AppExePath);
HandleTerminalError(e);
}
return (retValue);
}
/*********************************************************************
* StartApp_Process()
**********************************************************************/
public static void StartApp_Process(bool restartApp)
{
Debug.WriteLine("APPLICATION STARTER: Starting the app in a seperate process");
//Load the config file
AppStartConfig Config;
Config = LoadConfig();
AppExePath = Config.AppExePath;
//If the app has been started by this process before
if (AppProcess != null)
{
//& the app is still running, no need to start the app
if (!AppProcess.HasExited)
return;
}
//Start the app
try
{
ProcessStartInfo p = new ProcessStartInfo (AppExePath);
p.WorkingDirectory = Path.GetDirectoryName(AppExePath);
// Notify the app if we are restarting in case there's something they want to do differently
if(restartApp)
p.Arguments = RestartCommandLineString;
else
p.Arguments = CommandLineString;
AppProcess = Process.Start (p);
Debug.WriteLine("APPLICATION STARTER: Started app: " + AppExePath);
}
catch (Exception e)
{
Debug.WriteLine("APPLICATION STARTER: Failed to start process at: " + AppExePath);
HandleTerminalError(e);
}
}
}