0

I’m trying to create add-in for outlook and have issue with deserialization and antivirus program.

I’ve noticed that when my add-in tried to deserialize any data, .NET framework created temporary dll in “C:\Users\{UserName}\AppData\Local\Temp\" folder.
This dll existed very short time, but from time to time antivirus locked it and add-in thrown error message that file is used by another process.

I’m tried to get rid of temporary dll and found recommendations to use sgen tool for creation of XmlSerializers.dll.

I generated MyAssembly. XmlSerializers.dll with strong name and placed it to the folder with add-in (C:\Program Files (x86)\MyAddin). But it doesn’t help.

Then I tried to place MyAssembly. XmlSerializers.dll to GAC and then to outlook folder, but had no success. When dll was called from GAC I got following error message, but dll has no any reference.

"System.IO.FileNotFoundException: Could not load file or assembly or one of its dependencies. The system cannot find the file specified."

Please add any thoughts how can I to get rid of temporary dll

Eugene Astafiev
  • 47,483
  • 3
  • 24
  • 45
P_rnd
  • 153
  • 1
  • 1
  • 11
  • It looks like the issue is not related to Outlook at all. I'd suggest creating a regular Windows Forms application and try to run the code there. Does it work? – Eugene Astafiev Jul 07 '15 at 19:14
  • I tried to create console application. Copied deserialization logic and created MyConsole.XmlSerializers.dll with using of sgen tool. It worked perfectly (temporary dll was not created). – P_rnd Jul 08 '15 at 14:42

1 Answers1

0

When an XmlSerializer for a type is first constructed, internally the XML serialization engine generates c# code to serialize and deserialize the type, writes it to %TEMP% in temporary file(s), then compiles and loads the resulting assembly, finally deleting any temporary files. (Subsequent usages of XmlSerializer reuse the created assembly, see here for details.)

It looks as though your antivirus software is being ultra-aggressive at scanning any "unexpected" files created by the Outlook process, immediately trapping the creation of the file and scanning the results. While under most circumstances this would seem praiseworthy, it clearly conflicts with Microsoft's design for XmlSerializer.

So, what to do about this? You have several options:

  1. Switch to DataContractSerializer, which does not use this architecture. DataContractSerializer is less flexible that XmlSerializer, however, and may not be able to parse your XML without preprocessing it.

  2. Enable precompiled serialization assemblies. It's not sufficient to simply set GenerateSerializationAssemblies = On as is specified in the documentation, you have to jump through several hoops to make this actually work. See answers to Generating an Xml Serialization assembly as part of my build for ways to do it. I was able to make the accepted answer work with my old Visual Studio 2008 by editing my project file as described and then removing the Platform="$(Platform)" attribute. You might need to tweak the answer differently for your VS version.

    After actually enabling pre-generated serialization DLLs I verified with Process Monitor that no files were written to %TEMP% when deserializing XML in a test console application.

    See also here: Boost performance with Pre-generated XmlSerializers.

    Update

    After a bit of testing, I found that, if your root object does not exist in the assembly you are building, or if is a generic collection like List<T> or T [], then precompiled serializer assemblies are not used. However, making a non-generic subclass of List<T> re-enables serializer assemblies, e.g. public class RootObjectList : List<RootObject> { }.

    For more, see here: All about XmlSerializer Performance and Sgen.

  3. Convert your XML to JSON with Json.NET, then deserialize the JSON.

  4. If your XML is simple, you could load it into an XDocument and query it with Linq to XML.

dbc
  • 104,963
  • 20
  • 228
  • 340