How to detect system halt and recover last status in C#? - c#

I making a editor like program in Windows with C#.
I wonder that how the programs restore their working status or last working file that wasn't saved by user. The Photoshop and the 3Ds Max show a dialog to restore user's last working after system halt such as plugged out or bluescreen.
How do they do it? Do they just save their status every seconds? That's so simple and reasonable but not fancy. Is this only the way?

Use an unhandled exception handler and inside it save the current data to a special file.
Check AppDomain Unhandled Exception and Application DispatcherUnhandledException
If you want to protect yourself from other kind of issues like system errors then you need to save periodically the information

Related

Intermittently getting exception that states "FileStream was asked to open a device that was not a file" in C# program

When calling File.WriteAllText to generate files, intermittently the c# windows form program will hit a catch block due to an Exception with the message of "FileStream was asked to open a device that was not a file. For support for devices like 'com1:' or 'lpt1:', call CreateFile, then use the FileStream constructors that take an OS handle as an IntPtr."
The stacktrace shows Microsoft.Win32.Win32Native.SafeCreateFile as being where it got to last.
After days of researching and trying to find out why this was happening, most articles talk about the reserved file names like com and etc. However, this exception is hit in the middle of exporting files after getting through a few files already. These files don't have any reserved names in them. They all have the same path except for at the end of the file name where a hyphen and padded number for which file it is on is added. Since this gets through similar named files, I believed that this wasn't what was actually happening. The other issue is I could do the same export process multiple times and not get it to happen every time. In fact out of 100 or so export processes it would maybe happen only once even though nothing in the name or path had changed.
Today I found a way to actually get it to happen almost every time. If I go to Chrome and open say "a.singlediv.com" to test with, start the export, then as the export is running I repeatedly reload the div site, it will 99% of the time halt the export and hit the exception mentioned above.
Does anyone have any advice that could lead me to why this Exception message is shown for doing this? Task Manager doesn't seem to have any glaring issues with Memory or CPU overload and a log is being posted to our SQL server after hitting the Exception so I also dont believe it is a network issue.
Update
I was able to find out more about when the error happens with testing yesterday. When refreshing the website repeatedly, I tried a couple different ways of exporting to get more information.
A custom configuration file, a text file, and an excel file are used as setup files for our program. I made identical folders on the Desktop and on a mapped drive which points to a folder located on our server for where the setup files are located as well as where the exports will be saved. I tried a couple different ways of loading these files and export locations.
If I load the setup files from the Desktop folder and save to the Desktop, or load from the Desktop folder and save to the mapped drive, or load from the mapped drive and save to the Desktop folder all of these don't seem to hit the Exception. So far the only way I have gotten the Exception to occur is when I load from the mapped drive and save to the mapped drive while doing the constant refreshing of the div website.
Attached below is a screenshot of the Exception.ToString() (Except for our custom methods that called File.WriteAllText() before in the StackTrace). I manually added returns between each method call so that it is easier to read.
Workaround Update
Per Mason's suggestion I wrapped my File.WriteAllText call in a Polly Retry which has seemed to so far allowed the export to finish every file while debugging the code.
I first did a RetryPolicy.Execute that wrapped the File.WriteAllText. Before File.WriteAllText I wrote the Attempt # it was on to the Output window and after it wrote a message about completing. I did get an Attempt #2 but was getting Attempt #1 and completed for every time it was called which was not easy to see since it happens over 2000 times. So I tried to add an if statement to check if this was not the first attempt and if it wasn't it would write the Attempt # and that the retry handled Exception to the Output window. However, after adding these if statements I didn't get any Attempt #s and it didn't break on the Exception but I also saw that the Output window did have a line about hitting the Exception so I assume that means that the Retry handled it? I would of expected to see Attempt #2 and Retry handled Exception around the Exception message in the Output window since it didn't stop and created every file needed. I have added a code snippet of what I added below.
int attempt = 0;
Polly.Retry.RetryPolicy retryIfException = Policy.Handle<System.NotSupportedException>().Retry(3);
retryIfException.Execute(() =>
{
if (attempt>0)
{
Console.WriteLine($"Attempt #{++attempt}");
}
File.WriteAllText(saveLocation, this.currentFileText.ToString());
if (attempt>1)
{
Console.WriteLine("Retry handled Exception");
}
});

Can I prevent invalid minidump file names

I have a WinForms (.NET C#) OLTP application based on Oracle.
From our support environment we regularly experience loss of connectivity to the database, and a resulting minidump file is generated (by what, i am not entirely certain of) - apparently it does not cause the application to crash, but in order to actually do anything you have to close it and start it again.
After a many such minidumps have been created in the same directory, all of a sudden the minidumps starts getting rather strange file names, filenames that are apparently "illegal" on windows.
For instance we have a file name like:
"°÷ƒ
_minidump_default_pid_20248_tid_x19AC_2015_9_1_8_31_51.dmp"
And yes the carriage return is PART of the file name.
We discovered this because log4net watches the directory and all of a sudden starts to bark unhandled exceptiosn due to these invalid file names.
So we are trying to figure out why the minidump is generated in the first place, but the question here is, can we somehow prevent the minidump from being generated with an invalid filename or otherwise control the naming process?
Secondly, does anybody know why is it even possible to create invalid file names in the first place?
Update:
For anyone looking at this trying to figure out why the dump files are created in the first place, our issue was that Windows was generating them when it was near running out of memory, but for some reason we would'nt always get an OOMException.
First, you should really try to find out how those dumps are generated. Microsoft e.g. provides a nice way using a Registry key called LocalDumps which has provided great help for me. I am sure that this approach won't generate invalid file names like above.
Second, if the application does not crash, it has probably registered an unhandled exception handler. This is basically ok and designed to write crash dumps, but the unhandled exception is handled by the crashing process itself. How can the code to handle the situation be sure he himself is not affected by the crash? The better option is to let Windows as the OS handle the crash. Then the Windows kernel (which is not affected by the crash) can really handle the situation. That's what LocalDumps does.
Third, direct file system access is possible in Windows via paths that start with \\.\ when passing it to the Windows API. Starting a path like that will skip any file name check so you can generate files with reserved characters such as *, ?, : or newlines as observed by you. The unhandled exception handler of your application is probably doing that and is affected by the crash in a way that parts of the file name are overwritten.
Chkdsk should be able to repair the file system.
pls check if you are installing from network path like \remoteserver\d$\client.
then change it to \remoteserver\d\clinet
"$" in share path create issue while extration on elevated permission files

How often should I write to the Event Log in Windows?

I have an automated Process that will run a certain task every hour. I am thinking of creating a logging for this that would allow the user to see, if they want, what values are being used. Should I do this in the Event Log or create a .log txt file for this?
Is there a guideline for Windows Event Logs and whether it should only be used for errors only?
Are there any issues that I should be on the lookout for if I write to the event log every hour?
First of all one line answer to question
How often should I write to the Event Log in Windows
It depends on your needs and frequency at which you want information. There is no "one size fits all" in case logging decisions.
Should I do this in the Event Log or create a .log txt file for this?
depends on your requirements and who is going to use the log. To consider the Event Log, are you sure your application will have access to write event log every time? (in simple words, Administrative privileges).
If there are no set of standards defined (assuming you are not writing it for personal use only), then you should set a convention/standard in place for organization for what to write in Event Log and what to write in Log file.
For example
Event log: Unhanded exceptions and warnings
Log file: Caught exception and General Information (so that if in any deployed app client can send you the log file on mail)
Is there a guideline Windows Event Logs and whether it should only be used for errors only
You can visit Enterprise logging library:
https://msdn.microsoft.com/en-us/library/dn169621.aspx
Edit:
**Why downvote without a reason !!! **

IsolatedStorageSettings.ApplicationSettings are dismissed after App-Restart (WP8)

This happens with the Emulator as well as with the real device, in Debug-Mode as well as in Release-Mode.
In the app I store several application settings successfully - from simple value types to more complex objects and lists of objects.
With "WP POWER TOOLS" I can track the file "__ApplicationSettings" in the root of the IsolatedStorage. It is "well filled" - in the first lines I find some classes and assemblies, that define the complex type definitions, and below the XML starts with the <ArrayOfKeyValueOfstringanyType...>
So, everything looks normal to me so far.
When I close my app, the last piece of running code is the "Application_Closing"-Handler in App.xaml.cs. In this moment I can check the ApplicationSettings the last time - everything is okay.
For example: I check the count of the entries:
var count = System.IO.IsolatedStorage.IsolatedStorageSettings.ApplicationSettings.Count;
...and the count is right and the keys/values are right.
Then - I restart the app at once (Visual-Studio-Debugging is not interrupted) and the first piece of running code is the ctor App() in App.xaml.cs.
In the first line I check the count of ApplicationSettings-Entries again, and: it is 0 !!!
But: WP POWER TOOLS still show me, that the "__ApplicationSettings"-File is existing and is still filled like before.
(The consequence of this error is afterwards, that with the first attempt to save any setting again, the whole __ApplicationSettings-File is overwritten and contains just the one new setting.)
So what could be preventing the App from "using" the existing "__ApplicationSettings"-File???
Thanks in advance!
(PS 1: I already experienced, that all ApplicationSettings are destroyed, when there happens an Exception while saving the settings. I investigated all of that already and are 99.9% sure, that there is no Exception anymore.)
(PS 2: Just to make it clear: It is NOT the case, that the complete IsolatedStorage is gone. I have also another file for logging purposes, that I write to the root of the IsolatedStorage. This file is always there. Also the __ApplicationSettings file is not "deleted", it just seems, that the app doesn´t "read" it when launching.)
I tried the repro scenario with an app of mine and confirmed what I expected, that IsolatedStorageSettings.ApplicationSettings.Count was nonzero on entry to the App() ctor upon running the app for a second time in the same emulator process. So there is hope for you to get to this desired state too!
Since you report that the _ApplicationSettings file is not empty, I'll guess 2 possibilities: Maybe an app (or some other process?) keeps the _ApplicationSettings file open when the 2nd run of the app is trying to open the file for reading? MSFT doesn't document how the read is done, so maybe the file is opened with FileShare.None, or with FileShare.Read but some other process still has the file open for writing? I have no idea how to test this on the emulator, but on the real device you might try this scenario:
Run the app for the first time, verify it saves a non-empty _ApplicationSettings.
Restart the phone device (debugger will disconnect)
Run the app for the second time, with a breakpoint in App() ctor.
After 2) I would be confident no other process could have the file open, so the app should be able to read its contents without interference. But if you discover that it still has zero count in 3), then another possibility exists:
Maybe the restarted app encounters an error trying to deserialize the settings from the file into your data structure(s)? The error might not prevent the data from being serialized when the first run of the app is exiting.
To check this possibility, first look for error messages in the Output, Debug window. Do you see any errors when restarting the app the a second time?
If you don't see any helpful error messages, the next thing to try is to simplify the data structures being saved as settings. Try cutting down to just one setting that is a simple type like an int or string. See whether that can be restored correctly, then add more of your settings back into the file until you home in on the one which causes a problem.
Do you call Save on settings? Does it throw any error?

C# IO exception the file or directory is corrupted and unreadable

Sometimes my application throws an exception saying that the file is corrupted or unredable. Basically this file is a log file. My Application writes events and some data to the log file.
My Application was put on to Embedded box in which Windows XP OS runs.The only way to close the application is to shutoff power to the embeeded box. Since windows is not shutdown gracefully, the file is corrupted sometimes(this is what i am thinking).
I am using Intel SSD as a drive.I have enabled write caching on the disk. Does this cause the file corruption?
If i capture the exception, then can I delete this file using c# file functions(file.delete)?
Regards
Write caching doesn't cause file corruption. Shutting the machine off while the file is open causes the file corruption.
If you capture the exception then you should be able to delete the file.
You can probably lessen the frequency of errors if you call Flush on the log file whenever you write to it. You can almost completely eliminate the error if you close the file after every write (which, of course, would require that you open it for append before every write). That might be prohibitively expensive.
You can't completely eliminate the error as long as the only way to shut down the application is to remove power. You might consider rotating the log, though, so if it does get corrupted you only lose the last hour (or 15 minutes, or whatever amount of time you use for your log rotate frequency).

Categories

Resources