开发者

What common routines do you put in your Program.cs for C#

I'm interested in any common routine/procedures/methods that you might use in you Program.cs when creating a .NET project. For instance I commonly use the following code in my desktop applications to allow easy upgrades, single instance execution and friendly and simple reporting of uncaught system application errors.


    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)
                    {
                     开发者_JS百科   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.
                }
            }
        }
    }

I find these routines to be very helpful. What methods have you found helpful in Program.cs?


I try to avoid putting anything significant in the Program.cs file. Anything that I write for a simple Console app could someday be moved to a class library, and so I'll build a separate class for the actual program logic.

That said, there is some generic code that I use over and over. The main thing is using the Trace class to handle the console output, so I don't have to change any important code in the app itself to redirect things to a log file or somewhere else later when the inevitable transition to class library or gui app occurs:

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();
}


For argument parsing, the Novell Options class is the best I've seen (via "Best way to parse command line arguments in C#"). I've also adapted it for interactive console applications, for programs that don't just run and quit.

Here's an example of the Options class:

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


I usually have a very small Main function that calls another function (e.g. Start) - that way, if some assembly is missing and Start cannot be JITted, I can catch the TypeLoadException and display a human-readable error message.


We usually use main for basic command-line parsing, crash handling setup, license checking, and creation of main form (assuming it's a windows application and not a console application).

However, most of that functionality is handled by other objects that main just instantiates and calls.


The only code I definitely but into every program is my Exception Handler:

At the start:

#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

This will catch every Exception I missed and will write it to a log of my own (asking the client what the error message stated is actually not the wisest thing...).

Bobby

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜