2009-11-03 5 views
8

.NETプロジェクトを作成するときにProgram.csで使用する共通のルーチン/プロシージャ/メソッドに興味があります。たとえば、私はデスクトップアプリケーションで次のコードをよく使用して、簡単なアップグレード、単一インスタンスの実行、未知のシステムアプリケーションエラーのフレンドリーで簡単なレポートを可能にします。C#用のProgram.csに共通のルーチンを入れます


using System; 
    using System.Diagnostics; 
    using System.Threading; 
    using System.Windows.Forms; 

    namespace NameoftheAssembly 
    { 
     internal static class Program 
     { 
      /// <summary> 
      /// The main entry point for the application. Modified to check for another running instance on the same computer and to catch and report any errors not explicitly checked for. 
      /// </summary> 
      [STAThread] 
      private static void Main() 
      { 
       //for upgrading and installing newer versions 
       string[] arguments = Environment.GetCommandLineArgs(); 
       if (arguments.GetUpperBound(0) > 0) 
       { 
        foreach (string argument in arguments) 
        { 
         if (argument.Split('=')[0].ToLower().Equals("/u")) 
         { 
          string guid = argument.Split('=')[1]; 
          string path = Environment.GetFolderPath(Environment.SpecialFolder.System); 
          var si = new ProcessStartInfo(path + "\\msiexec.exe", "/x" + guid); 
          Process.Start(si); 
          Application.Exit(); 
         } 
        } 
        //end of upgrade 
       } 
       else 
       { 
        bool onlyInstance = false; 
        var mutex = new Mutex(true, Application.ProductName, out onlyInstance); 
        if (!onlyInstance) 
        { 
         MessageBox.Show("Another copy of this running"); 
         return; 
        } 
        AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; 
        Application.ThreadException += ApplicationThreadException; 
        Application.EnableVisualStyles(); 
        Application.SetCompatibleTextRenderingDefault(false); 
        Application.Run(new Form1()); 
       } 
      } 

      private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) 
      { 
       try 
       { 
        var ex = (Exception) e.ExceptionObject; 
        MessageBox.Show("Whoops! Please contact the developers with the following" 
            + " information:\n\n" + ex.Message + ex.StackTrace, 
            " Fatal Error", MessageBoxButtons.OK, MessageBoxIcon.Stop); 
       } 
       catch (Exception) 
       { 
        //do nothing - Another Exception! Wow not a good thing. 
       } 
       finally 
       { 
        Application.Exit(); 
       } 
      } 

      public static void ApplicationThreadException(object sender, ThreadExceptionEventArgs e) 
      { 
       try 
       { 
        MessageBox.Show("Whoops! Please contact the developers with the following" 
            + " information:\n\n" + e.Exception.Message + e.Exception.StackTrace, 
            " Error", MessageBoxButtons.OK, MessageBoxIcon.Stop); 
       } 
       catch (Exception) 
       { 
        //do nothing - Another Exception! Wow not a good thing. 
       } 
      } 
     } 
    } 

私は、これらのルーチンは非常に有用であることがわかりました。 Program.csで役立つ方法はありますか?

+0

私はあなたが床に何か追加の例外をドロップしているのはかなり恐ろしいことがわかります。 –

+3

私は彼が床に追加の例外を落としているとは思わない。彼が無視している唯一の例外は、実際にユーザーにエラーメッセージ、つまりMessageBox.Show()の呼び出しを実際に表示したときの例外です。 –

答えて

5

私はProgram.csファイルに重要なものを置かないようにしています。単純なコンソールアプリケーション用に書いたものは、いつかはクラスライブラリに移動することができるので、実際のプログラムロジック用に別のクラスを作成します。

つまり、何度も何度も繰り返し使う一般的なコードがあります。主なものは、Traceクラスを使用してコンソール出力を処理するため、クラスライブラリやGUIアプリケーションへの必然的な移行が発生したときに、ログファイルやその他の場所にリダイレクトするために、アプリケーション自体の重要なコードを変更する必要はありません発生:

using System; 
using System.Diagnostics; 

public static void Main(string[] args) 
{ 
    Trace.Listeners.Add(new ConsoleTraceListener()); 
    Trace.WriteLine("Program Started - " + DateTime.Now.ToString());Trace.WriteLine(""); 

    //Call into a separate class or method for the actual program logic 
    DoSomething(); //I'll use Trace for output in here rather than Console 

    Trace.WriteLine("");Trace.WriteLine("Program Finished - " + DateTime.Now.ToString()); 

    Console.Write("Press a key to exit..."); 
    Console.ReadKey(true); 
    Console.WriteLine(); 
} 
+0

それは素晴らしい考えです! – Rick

1

私は通常、別の関数(例えばスタート)を呼び出して、非常に小さな主な機能持っている - いくつかのアセンブリが欠落しているとスタートがJITコンパイルすることができないならば、私はTypeLoadExceptionをキャッチし、人間を表示することができ、そのように読み取り可能なエラーメッセージ。

2

引数の解析では、私が見たことのあるところでは"Best way to parse command line arguments in C#"Novell Optionsクラスが最適です。私はまた、対話型コンソールアプリケーションのためだけに実行して終了しないプログラムのためにadapted itを持っています。ここで

はオプションクラスの例です:

static void Main(string[] args) 
{ 
    var p = new new OptionSet() 
     .Add ("v|verbose", v=> setVerbose()) 
     .Add ("h|?|help", v=> showHelp()) 
     .Add ("n|name=", v=> showName(v)); 

    p.Parse (args); 
} 
1

我々は通常、クラッシュハンドリングのセットアップ、ライセンスのチェック、およびメインフォームの作成は(それがWindowsアプリケーションだと仮定していない、基本的なコマンドライン構文解析のための主な使用しますコンソールアプリケーション)。

しかし、その機能のほとんどは、インスタンシエーションと呼び出しを行うだけの他のオブジェクトによって処理されます。

0

コードのみ間違いなく私が、にすべてのプログラムは、私の例外ハンドラです:

開始時:

#If Not Debug Then 
     AddHandler AppDomain.CurrentDomain.UnhandledException, AddressOf Me.Application_UnhandledException 
     AddHandler Application.ThreadException, AddressOf Me.Application_ThreadException 
#End If 

Private Sub Application_UnhandledException(ByVal sender As Object, ByVal e As System.UnhandledExceptionEventArgs) 
    Me.UnhandledExceptionLog(TryCast(e.ExceptionObject, Exception).Message, New StackTrace(TryCast(e.ExceptionObject, Exception), True), e.ExceptionObject) 
End Sub 
Private Sub Application_ThreadException(ByVal sender As Object, ByVal e As System.Threading.ThreadExceptionEventArgs) 
    Me.UnhandledExceptionLog(e.Exception.Source & Environment.NewLine & e.Exception.Message & Environment.NewLine & e.Exception.StackTrace, New StackTrace(e.Exception, True), e.Exception) 
End Sub 

Public Sub UnhandledExceptionLog(ByVal message As String, ByVal stack As StackTrace, ByVal ex As Object) 
    ' write the exception details to a log and inform the user the he screwed something ;) ' 
End Sub 

これは私が逃したすべての例外をキャッチしますします私自身のログに書いてください(エラーメッセージが実際には最善のことではないことをクライアントに尋ねます...)。

ボビー

関連する問題