在.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);
   }
  } 

 
}

 posted on 2005-06-15 22:42  沧海一声笑  阅读(1147)  评论(0编辑  收藏  举报