I create a setup file of a winform app using VS 2017 installer. When I test this setup file on my PC, the login runs fine. So I run this setup file on other PCs.
However, when I login the app in these PCs, the app say "Object reference not set to an instance of an object", though I am sure that the username and password were correct in the db.
I have seen What is a NullReferenceException, and how do I fix it?, but I do not think it is the null exception, because the installed app did not throw above error in my PC. This error only happens when I install the app in other PCs.
I also try replacing the .exe and .config files in folder of the installed app in other PCs with the same files of the app in my PC (which work well), and the app runs ok. But then I restart those PCs, and try to login the app, the same error happens.
This is the code for login. I believe that I have checked for the null exception properly. Am I right?
private void btnLogin_Click(object sender, EventArgs e)
{
try
{
var info = UsersBiz.Login(txtUserName.Text.Trim(), txtPassWord.Text);
if (info != null && info.user.Id > 0)
{
Constants.USERINFO = info;
this.Hide();
var frm = new frmMain();
frm.Show();
if (ckbRemember.Checked)
{
ManagementInventory.Properties.Settings.Default.User = txtUserName.Text;
ManagementInventory.Properties.Settings.Default.Pass = txtPassWord.Text;
ManagementInventory.Properties.Settings.Default.Save();
}
}
else
{
MessageBox.Show("UserName or Password not correct!");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
The most easy way would be to use visual studio debugger on the computer where the program runs. If there is no visual studio on that computer, consider using remote debugging. See how to start debugging on a remote computer
If for security reasons remote debugging is out of the question, consider to log the exception, especially the stack trace. If you know where it occurs, simply surround it with a try-catch
try
{
// Here are the statements that cause your ArgumentNullException
}
catch (ArgumentNullException exc)
{
// log the exception
}
If your program has no logging facility, consider adding something like NLOG. Another possibility is to append it to a text file.
void WriteExceptionToTextFile(Exception exc, string fileName)
{
using (var writer = File.AppendText(fileName))
{
writer.WriteLine("Exception {0}", exc.GetType());
write.WriteLine("Stack trace" + exc.StackTrace);
... // etc
}
}
If you don't know where the exception occurs, you can't try-catch it. In that case consider to catch the unhandled exception and log it:
See: catching unhandled exception
In your forms program is a file program.cs which contains the main:
public static void Main()
{
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.UnhandledException += OnUnhandledException;
...
}
static void OnUnhandledException(object sender, UnhandledExceptionEventArgs args)
{
Exception undhandledException = (Exception) args.ExceptionObject;
// TODO log the unhandled exception
}
Related
I came across a problem that is the AccessViolationException was unhandled after i run my program for about a day long.
(More information: I am using Visual Studio 2010)
However, it does not state where this exception occurs, there were two options given to me which is "ok" and "continue". When i pressed ok, nothing happened so i pressed continue and the program stops debugging.
When i tried to find a solution, i understand that i can implement HandleProcessCorruptedStateExceptions to fix this problem. However, i have no clue where to start.
Do i simply include the codes below only? And where do i include these code?
[HandleProcessCorruptedStateExceptions]
[SecurityCritical]
public static int Main()
{
try
{
// Catch any exceptions leaking out of the program CallMainProgramLoop();
}
catch (Exception e)
// We could be catching anything here
{
// The exception we caught could have been a program error
// or something much more serious. Regardless, we know that
// something is not right. We'll just output the exception
// and exit with an error. We won't try to do any work when
// the program or process is in an unknown state!
System.Console.WriteLine(e.Message);
return 1;
}
return 0;
}
Alternatively, i can also do this legacyCorruptedStateExceptionsPolicy but it says that i should input the required statement in the config file. Where can i find the config file?
Appreciate all the replies!
The actual answer for you question is here and I really shouldn't answer it again, but I want to show you some code sample and I don't want to write it in comment :)
In one of my projects from time to time there was an unpredictable exception. To catch it I write this code in Program.cs:
[STAThread]
static void Main()
{
// add UnhandledException handler
AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler;
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
private static void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs e)
{
// prepare message for user
var message = "There was an unknown exception while running <app_name>!";
var exception = e.ExceptionObject as Exception;
if (exception != null)
{
// change message if there was actual exception
message = $"There was an {exception.GetType().Name} exception while running <app_name>! {exception.Message}";
// adding inner exceptions messages
var innerException = exception.InnerException;
while (innerException != null)
{
message += $"\r\n-> {innerException.GetType().Name}: {innerException.Message}";
innerException = innerException.InnerException;
}
#if DEBUG
// add tracing info
message += $"\r\n\r\n{GetStackTrace(exception)}";
#endif
}
if (e.IsTerminating) message += "\r\n\r\n<app_name> will be closed.";
// showing message to the user
MessageBox.Show(message, "Unhandled Exception", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
#if DEBUG
private static string GetStackTrace(Exception exception)
{
var trace = new System.Diagnostics.StackTrace(exception, fNeedFileInfo: true);
var frames = trace.GetFrames()
.Select((f, i) => {
var filename = f.GetFileName();
var methodInfo = f.GetMethod();
var frame = $"#{i} in the method {methodInfo.DeclaringType.FullName}.{methodInfo.Name}()";
if (filename != null) frame += $" (source file: {System.IO.Path.GetFileName(filename)}#{f.GetFileLineNumber()}:{f.GetFileColumnNumber()})";
return frame;
});
return $"Full stack trace ({trace.FrameCount} frames total):\r\n{string.Join("\r\n", frames)}";
}
#endif
Now, when unhandled exception occurring - there will be a message box, that shows full exception message (and inner exceptions messages). There was also a full stack trace for Debug build with method name, line number and source filename where exception occure.
About HandleProcessCorruptedStateExceptions
You mention a HandleProcessCorruptedStateExceptions attribute in your comment. The docs clearly says that you shouldn't use it unless you absolutely sure that you need it.
Corrupted process state exceptions are exceptions that indicate that
the state of a process has been corrupted. We do not recommend
executing your application in this state.
By default, the common language runtime (CLR) does not deliver these
exceptions to managed code, and the try/catch blocks (and other
exception-handling clauses) are not invoked for them. If you are
absolutely sure that you want to maintain your handling of these
exceptions, you must apply the
HandleProcessCorruptedStateExceptionsAttribute attribute to the method
whose exception-handling clauses you want to execute. The CLR delivers
the corrupted process state exception to applicable exception clauses
only in methods that have both the
HandleProcessCorruptedStateExceptionsAttribute and
SecurityCriticalAttribute attributes.
Corrupted process state means that some really catastrophic things happens and it safer for your app to die right now. If you are still not scared enough, here is the Main() method from the example above with the HandleProcessCorruptedStateExceptions attribute set:
[STAThread]
[HandleProcessCorruptedStateExceptions, SecurityCritical]
static void Main()
{
try
{
// add UnhandledException handler
// AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler;
// * in this particular case is not quite useful to handle this exceptions,
// because you already wrap your entire application in a try/catch block
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
catch (Exception ex)
{
// handle it somehow
}
}
How do I debug the finally block in a try {...} finally{...} in the event of an uncaught exception? It seems that no matter what I do with the exception settings or debugger, Visual Studio will not let me proceed past the point of the thrown exception in the try block in order to debug the finally code.
Here's a representative, short example:
public static void Main()
{
var instrument = new Instrument();
try
{
instrument.TurnOnInstrument();
instrument.DoSomethingThatMightThrowAnException();
throw new Exception(); // Visual Studio won't let me get past here. Only option is to hit "Stop Debugging", which does not proceed through the finally block
}
finally
{
if(instrument != null)
instrument.TurnOffInstrument();
}
}
Context: I have a program that controls some hardware instruments used for taking electronic measurements in a lab, e.g. programmable PSUs. In the event that something goes wrong, I want it to fail fast: first shut down the instruments to prevent possible physical damage and then exit. The code to shut them down is in the finally block, but I have no way to debug that this code works in the error case. I don't want to try to handle any possible errors, just turn the instruments and then shut the program down. Maybe I'm going about this the wrong way?
A finally block is never executed if the exception results in a crash of the application, that is the case in your code.
To debug the finally block in your exemple, you have to put the whole code of your main function in an other try statement, and catch the exception to prevent the application to crash, like this:
public static void Main()
{
try
{
var instrument = new Instrument();
try
{
instrument.TurnOnInstrument();
instrument.DoSomethingThatMightThrowAnException();
throw new Exception();
}
finally
{
if (instrument != null)
instrument.TurnOffInstrument();
}
}
catch (Exception)
{
Console.Writeline("An exception occured");
}
}
You can set breakpoint ( F9 key ) and Alt + Ctrl + B Keys to see the list of breakpoints.
You can break in between using IntelliTrace, As :
You need to put a breakpoint on the first line inside the finally block, then click "Run" again after the exception.
My application calls a library (which I do not have control) that creates a new EventLog source and uses EventLog.SourceExists. It throws System.Security.SecurityException: The source was not found, but some or all event logs could not be searched. Inaccessible logs: Security.
The app needs read access to HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\Security. How do I give Network Service permissions to registry (programmatically)?
Thanks for any pointers.
You are getting this error message because your "new Source" is not registered, and for that you need administration privileges. Try run your APP as "Administrator" in Console.
I once hacked the "registry" as well, by adding in the "Source" myself, but that's probably ill-advised.
I hit this same problem today and none of the answers for WinForms or ASPX seemed practicable for my situation (a non-installing scheduled task exe). So I did this: -
protected void prog_Load(object sender, EventArgs e)
{
boolean setupComplete = false;
try // setting an Event log entry, just to see if we can
{
logEvent = "prog started";
EventLog.WriteEntry(logSource, logEvent, EventLogEntryType.Information, 0);
setupComplete = true;
}
catch (Exception eLog1) // we can't, so try to fix
{
try
{
EventLog.CreateEventSource(logSource, logLog);
logEvent = "prog registered for Event Logging";
EventLog.WriteEntry(logSource, logEvent, EventLogEntryType.Information, 0);
}
catch (Exception eLog2) // aha! we probably lack admin rights to set the registry key
{
MessageBox.Show("prog needs admin rights the first time it runs", "prog Setup", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
// run
if (setupComplete == true)
{
DoTheWork();
}
// exit
this.Close();
}
I have a website on appharbor.
I know there is logentries for logs on demand.
But, how can I see all unhandled server-side exceptions?
I have found this snippet (to put int Global.ascx), but couldn't find what are all the required dlls to reference.
protected void Application_Error(object sender, EventArgs e)
{
try
{
var exception = Server.GetLastError();
var logEntry = new LogEntry
{
Date = DateTime.Now,
Message = exception.Message,
StackTrace = exception.StackTrace,
};
var datacontext = new LogDBDataContext();
datacontext.LogEntries.InsertOnSubmit(logEntry);
datacontext.SubmitChanges();
}
catch (Exception)
{
// failed to record exception
}
}
AppHarbor already logs application errors, you can inspect them by clicking "Errors" in the menu to the left of the application dashboard.
Another great option is to add Elmah to your AppHarbor application, but remember to lock down Elmah view.
Should you still want to use the snippet above, then take a look at the full sample to see what other dependencies are required.
I have a command line program in C# that I've wrapped with a try-catch block to keep it from crashing the console. However, while I am debugging it, if an exception is thrown somewhere in the DoStuff() method, Visual Studio will break on the "catch" statement. I want Visual Studio to break where the exception occurred. What's the best way to do this?
Comment out the try?
A setting in Visual Sudio?
An #if DEBUG statement?
static void Main(string[] args)
{
try
{
DoStuff();
}
catch (Exception e)
{ //right now I have a breakpoint here
Console.WriteLine(e.Message);
}
}
private void DoStuff()
{
//I'd like VS to break here if an exception is thrown here.
}
You can turn on First chance exceptions in VS. This will allow you to be notified as soon as an exception is raised.
I think setting VS to break on uncaught exceptions and wrapping the try/catch in ifdefs is how I would go about doing it.
There is an option to "Break on all exceptions". I'm not sure what version of VS you are using but in VS 2008 you can press Ctrl + D, E. You can then click the checkbox the Thrown checkbox for the types of exceptions you want to break on
I believe in previous versions of VS there was a Debug menu item to the effect of "Break on all exceptions". Unfortunately I don't have a previous version handy.
Here's how I do it for console tools running at continuous integration server:
private static void Main(string[] args)
{
var parameters = CommandLineUtil.ParseCommandString(args);
#if DEBUG
RunInDebugMode(parameters);
#else
RunInReleaseMode(parameters);
#endif
}
static void RunInDebugMode(IDictionary<string,string> args)
{
var counter = new ExceptionCounters();
SetupDebugParameters(args);
RunContainer(args, counter, ConsoleLog.Instance);
}
static void RunInReleaseMode(IDictionary<string,string> args)
{
var counter = new ExceptionCounters();
try
{
RunContainer(args, counter, NullLog.Instance);
}
catch (Exception ex)
{
var exception = new InvalidOperationException("Unhandled exception", ex);
counter.Add(exception);
Environment.ExitCode = 1;
}
finally
{
SaveExceptionLog(parameters, counter);
}
}
Basically, in release mode we trap all unhandled exceptions, add them to the global exception counter, save to some file and then exit with error code.
In debug more exception goes right to the throwing spot, plus we use console logger by default to see what's happening.
PS: ExceptionCounters, ConsoleLog etc come from the Lokad Shared Libraries