csc.exe - Application Error
The application failted to initialize properly (0xc0000142). Click on OK to terminate the application.
Some investigation reveals that the issue has to do with the .NET class XmlSerializer. My application stores user data into an XML file, which gets saved when the application is closed. In particular, the following code seems to cause the problem:
Dim serializer As New XmlSerializer(ConfigObj.GetType())
Dim writer As New StreamWriter(datafile)
serializer.Serialize(writer, ConfigObj)
writer.Close()
Dim writer As New StreamWriter(datafile)
serializer.Serialize(writer, ConfigObj)
writer.Close()
The error occurs as soon as XmlSerializer.Serialize() is called. A file system monitor tool such as Process Monitor shows me that csc.exe is creating temporary files in C:\Windows\Temp, which is perhaps interrupted by the shutdown process, causing the above problem. I am not even sure why csc.exe (the microsoft C# compiler) gets called even though I am using VB.NET!
Not sure how to fix the problem, I have to avoid calling XmlSerializer when Windows is shutting down by using:
Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
...
If e.CloseReason <> CloseReason.WindowsShutDown
Dim serializer As New XmlSerializer(ConfigObj.GetType())
Dim writer As New StreamWriter(datafile)
serializer.Serialize(writer, ConfigObj)
writer.Close()
Dim writer As New StreamWriter(datafile)
serializer.Serialize(writer, ConfigObj)
writer.Close()
End If
...
...
End Sub
This way, user data may be lost, but at least my application does not prevent the system from shutting down. I have to find another way to save user data more frequently...
Reference:
I have spent quite some time trying to figure this issue out. Simply not saving the data was not an option.
ReplyDeleteThe reason csc.exe is launched when using the XmlSerializer class is that it generates serialization assemblies on the fly by reflecting over the types to serialize at runtime. The assemblies are generated in the windows temp folder, but for some reason, csc.exe is not allowed to compile during the windows shutdown process.
This behaviour can be determined by adding this to your application config file.
...where tempFilesLocation is a folder you want to monitor and the diagnostics switch tells XmlSerializer not to delete the temp files after assembly generation.
The solution is of course not to avoid saving your data during shutdown, but to pre-generate your serialization assemblies and add them to your applications bin folder. XmlSerializer will then use the pre-generated assemblies rather than compiling them at run-time. Besides from the obvious performance improvement, csc.exe will not be launched at all and your data will safely be stored during shutdown and log off.
Use the sgen.exe tool from the visual studio SDK to pre-generate serialization assemblies.
Be advised that not all XMLSerializer constructors support pre-generated assemblies. Further, there are strict rules as to what objects can be obtained in a pre-generated assembly, fx. if you are serializing a list as the root element, you will need to create a class for it.
[XmlRoot]
MyList : List
Serializing just List will still cause csc.exe to be launched at runtime.
An easy way to add pre-generated assemblies to your project is to call sgen.exe in the post build event from visual studio and add a reference to the generated assemblies from the project.
I hope this will help others who are puzzled by this behavior.
Thanks for your suggestion. Using pre-generated assemblies for XmLSerializer, instead of letting it autogenerate on the fly has helped to resolve my problem after so long!
ReplyDeleteBy the way, your sample app.config file to change the location of temp files for XmlSerializer is missing, perhaps because blogspot considers the xml contructs invalid HTML and discard it. I re-post it here (remove the extra spaces)
< system.diagnostics >
< switches >
< add name="XmlSerialization.Compilation" value="1" />
< /switches >
< /system.diagnostics >
< system.xml.serialization >
< xmlSerializer tempFilesLocation="c:\\foo" />
< /system.xml.serialization >