具有插件展望的XmlSerializers

时间:2015-07-07 13:31:58

标签: c# .net xmlserializer

我正在尝试为Outlook创建加载项,并且在反序列化和防病毒程序方面存在问题。

我注意到当我的插件试图反序列化任何数据时,.NET框架在“C:\Users\{UserName}\AppData\Local\Temp\"文件夹中创建了临时dll。
这个dll存在的时间非常短,但是防病毒软件会不时将其锁定并添加错误消息file is used by another process

我试图摆脱临时dll并找到使用sgen工具创建XmlSerializers.dll的建议。

我生成了MyAssembly。 XmlSerializers.dll具有强名称,并将其放置到带有加载项的文件夹(C:\ Program Files(x86)\ MyAddin)。但它没有帮助。

然后我尝试放置MyAssembly。 XmlSerializers.dll到GAC然后到outlook文件夹,但没有成功。当从GAC调用dll时,我收到了以下错误消息,但是dll没有任何引用。

  

“System.IO.FileNotFoundException:无法加载文件或程序集或   其中一个依赖项。系统找不到指定的文件。“

请添加任何想法如何摆脱临时dll

1 个答案:

答案 0 :(得分:0)

首次构造类型的XmlSerializer时,XML序列化引擎在内部生成c#代码以序列化和反序列化类型,将其写入临时文件中的%TEMP%,然后编译并编译加载生成的程序集,最后删除任何临时文件。 (XmlSerializer的后续用法重用已创建的程序集,有关详细信息,请参阅here。)

看起来您的防病毒软件在扫描任何"意外"时非常积极。 Outlook进程创建的文件,立即捕获文件的创建并扫描结果。虽然在大多数情况下这看起来值得称赞,但它明显与微软XmlSerializer的设计冲突。

那么,该怎么办?您有几种选择:

  1. 切换到DataContractSerializer,但不使用此架构。 DataContractSerializer XmlSerializer的灵活性较低,但可能无法在不预处理的情况下解析XML。

  2. 启用预编译的序列化程序集。仅仅根据documentation中指定的GenerateSerializationAssemblies = On来设置Platform="$(Platform)"是不够的,你必须跳过几个箍才能使其真正起作用。有关方法,请参阅Generating an Xml Serialization assembly as part of my build的答案。通过按照描述编辑项目文件,然后删除%TEMP%属性,我能够使用旧的Visual Studio 2008进行accepted answer工作。您可能需要以不同的方式调整VS版本的答案。

    在实际启用预生成的序列化DLL之后,我使用Process Monitor验证了在测试控制台应用程序中反序列化XML时没有文件写入List<T>

    另见:Boost performance with Pre-generated XmlSerializers

    <强>更新

    经过一些测试后,我发现如果您正在构建的程序集中不存在您的根对象,或者如果是T []List<T>这样的通用集合,则会发现预编译的序列化程序集没用过。但是,创建public class RootObjectList : List<RootObject> { }的非通用子类会重新启用序列化程序集,例如@echo off pushd "%USERPROFILE%\Desktop\images" :: Sorting images in '\Desktop\images' (subfolders only) for /f "delims=" %%I in (' dir /b /A:D ') do ( if exist "%%~nxI\*.jpg" ( md "%%~nxI\kck" 2>NUL move "%%~nxI\*.jpg" "%%~nxI\kck\" ) ) popd exit

    有关详情,请参阅此处:All about XmlSerializer Performance and Sgen

  3. Convert your XML to JSON使用Json.NET,然后deserialize the JSON

  4. 如果您的XML很简单,可以将其加载到XDocument并使用Linq to XML进行查询。