Search code examples
c#exit-code

Specifying the Return Error Code on Application Exit


How can the return error code be specified on application exit? If this were a VC++ application, I could use the SetLastError(ERROR_ACCESS_DENIED) -- return GetLastError() APIs. Is there a way to do this in C#?

  static int Main(string[] args)
  {
     Tool.Args = args;

     Application.EnableVisualStyles();
     Application.SetCompatibleTextRenderingDefault(false);
     Application.Run(new Download_Tool());

     return Tool.ErrorCode;
  }

How can the Tool.ErrorCode value be set intelligably? If I try something like Tool.ErrorCode = ERROR_ACCESS_DENIED, I get an error, "The name ERROR_ACCESS_DENIED does not exist in the current context." Thanks.

ADDITIONAL INFORMATION

My example is over-simplified. Is there a way to something like this:

Tool.ErrorCode = ERROR_ACCESS_DENIED;
return Tool.ErrorCode;

...which generates a compile-error, rather than this:

Tool.ErrorCode = 5;
return Tool.ErrorCode;

...which works, but uses a "magic number." I'd like to avoid the use of magic numbers.


Solution

  • http://msdn.microsoft.com/en-us/library/system.environment.exit.aspx

    Environment.Exit(exitCode)
    

    Update

    The reason why you get a compile error with "ERROR_ACCESS_DENIED" is because you have not defined it. You need to define it yourself:

    const int ERROR_ACCESS_DENIED = 5;
    

    Then you can use:

    Environment.Exit(ERROR_ACCESS_DENIED)
    

    Update 2

    If you are looking for a ready-made set of winerror.h constants for your C# needs, then here it is:

    http://www.pinvoke.net/default.aspx/Constants/WINERROR.html

    I would probably modify the GetErrorName(...) method to do some caching though, e.g.:

    private static Dictionary<int, string> _FieldLookup;
    
    public static bool TryGetErrorName(int result, out string errorName)
    {
        if (_FieldLookup == null)
        {
            Dictionary<int, string> tmpLookup = new Dictionary<int, string>();
    
            FieldInfo[] fields = typeof(ResultWin32).GetFields();
    
            foreach (FieldInfo field in fields)
            {
                int errorCode = (int)field.GetValue(null);
    
                tmpLookup.Add(errorCode, field.Name);
            }
    
            _FieldLookup = tmpLookup;
        }
    
        return _FieldLookup.TryGetValue(result, out errorName);
    }