尝试从SSIS包保存大于~1.5 MiB的文件时,EPPlus 2.9.0.1抛出System.IO.IsolatedStorage.IsolatedStorageException

问题

当我尝试使用EPPlus保存文件超过~1.5 MiB时ExcelPackage.Save()抛出System.IO.IsolatedStorage.IsolatedStorageException

说明

我正在使用Visual Studio 2008 9.0.30729.4462 QFE.NET Framework 3.5 SP1创建一个SSIS包,以通过EPPlus 2.9.0.1库导出SQL Server 2008 SP2 10.0.4311.0 64 bit表的EPPlus 2.9.0.1

SSIS包非常简单:一个Execute SQL Task ,它读取表的内容并将其放入一个变量后跟一个Script task ,该Script task读取记录集变量并通过EPPlus将内容保存到磁盘。

脚本任务的代码是:

 namespace ST_00a0b40814db4c7290b71f20a45b62c6.csproj { using System; using System.AddIn; using System.Data; using System.Data.OleDb; using System.IO; using Microsoft.SqlServer.Dts.Runtime; using Microsoft.SqlServer.Dts.Tasks.ScriptTask; using OfficeOpenXml; [AddIn("ScriptMain", Version = "1.0", Publisher = "", Description = "")] public partial class ScriptMain : VSTARTScriptObjectModelBase { public void Main() { DataTable documentList = new DataTable(); using (OleDbDataAdapter adapter = new OleDbDataAdapter()) { adapter.Fill(documentList, this.Dts.Variables["DocumentList"].Value); } if (documentList.Rows.Count > 0) { FileInfo fileInfo = new FileInfo(@"C:\Temp\Test.xlsx"); if (fileInfo.Exists) { fileInfo.Delete(); } using (ExcelPackage package = new ExcelPackage(fileInfo)) { ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("Documents"); for (Int32 i = 0; i < documentList.Rows.Count; i++) { for (Int32 j = 0; j < documentList.Columns.Count; j++) { worksheet.Cells[i + 1, j + 1].Value = documentList.Rows[i][j]; } } package.Save(); } } Dts.TaskResult = Convert.ToInt32(DTSExecResult.Success); } } } 

当我提供脚本任务时,只有几个记录包运行正常,但是当我针对整个表运行它时, package.Save(); 使用System.IO.IsolatedStorage.IsolatedStorageException: Unable to determine the identity of domain爆炸System.IO.IsolatedStorage.IsolatedStorageException: Unable to determine the identity of domainexceptionSystem.IO.IsolatedStorage.IsolatedStorageException: Unable to determine the identity of domain

在这里,您可以看到完整的堆栈跟踪:

 Error: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.InvalidOperationException: Error saving file C:\Temp\Test.xls ---> System.IO.IsolatedStorage.IsolatedStorageException: Unable to determine the identity of domain. at System.IO.IsolatedStorage.IsolatedStorage._GetAccountingInfo(Evidence evidence, Type evidenceType, IsolatedStorageScope fAssmDomApp, Object& oNormalized) at System.IO.IsolatedStorage.IsolatedStorage.GetAccountingInfo(Evidence evidence, Type evidenceType, IsolatedStorageScope fAssmDomApp, String& typeName, String& instanceName) at System.IO.IsolatedStorage.IsolatedStorage._InitStore(IsolatedStorageScope scope, Evidence domainEv, Type domainEvidenceType, Evidence assemEv, Type assemblyEvidenceType, Evidence appEv, Type appEvidenceType) at System.IO.IsolatedStorage.IsolatedStorage.InitStore(IsolatedStorageScope scope, Type domainEvidenceType, Type assemblyEvidenceType) at System.IO.IsolatedStorage.IsolatedStorageFile.GetStore(IsolatedStorageScope scope, Type domainEvidenceType, Type assemblyEvidenceType) at System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForDomain() at MS.Internal.IO.Packaging.PackagingUtilities.ReliableIsolatedStorageFileFolder.GetCurrentStore() at MS.Internal.IO.Packaging.PackagingUtilities.ReliableIsolatedStorageFileFolder..ctor() at MS.Internal.IO.Packaging.PackagingUtilities.GetDefaultIsolatedStorageFile() at MS.Internal.IO.Packaging.PackagingUtilities.CreateUserScopedIsolatedStorageFileStreamWithRandomName(Int32 retryCount, String& fileName) at MS.Internal.IO.Packaging.SparseMemoryStream.EnsureIsolatedStoreStream() at MS.Internal.IO.Packaging.SparseMemoryStream.SwitchModeIfNecessary() at MS.Internal.IO.Packaging.SparseMemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count) at MS.Internal.IO.Packaging.CompressEmulationStream.Write(Byte[] buffer, Int32 offset, Int32 count) at MS.Internal.IO.Packaging.CompressStream.Write(Byte[] buffer, Int32 offset, Int32 count) at MS.Internal.IO.Zip.ProgressiveCrcCalculatingStream.Write(Byte[] buffer, Int32 offset, Int32 count) at MS.Internal.IO.Zip.ZipIOModeEnforcingStream.Write(Byte[] buffer, Int32 offset, Int32 count) at System.IO.StreamWriter.Flush(Boolean flushStream, Boolean flushEncoder) at System.IO.StreamWriter.Write(String value) at System.IO.TextWriter.Write(String format, Object arg0, Object arg1) at OfficeOpenXml.ExcelWorksheet.UpdateRowCellData(StreamWriter sw) at OfficeOpenXml.ExcelWorksheet.SaveXml() at OfficeOpenXml.ExcelWorksheet.Save() at OfficeOpenXml.ExcelWorkbook.Save() at OfficeOpenXml.ExcelPackage.Save() --- End of inner exception stack trace --- at OfficeOpenXml.ExcelPackage.Save() at ST_00a0b40814db4c7290b71f20a45b62c6.csproj.ScriptMain.Main() in C:\Temp\ScriptMain.cs:line 39 --- End of inner exception stack trace --- at System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner) at System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner) at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks) at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) at System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams) at System.Type.InvokeMember(String name, BindingFlags invokeAttr, Binder binder, Object target, Object[] args, CultureInfo culture) at Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTATaskScriptingEngine.ExecuteScript() 

我已经能够根据生成的文件的大小确定问题:当Excel文件的大小增加大约1.5 MiB时(这是一个或多或少的值,我无法找到确切的大小),错误出现了。

我能在网上找到的唯一信息是博客文章 ,博客提出了一个解决方案,他将代码“外包”到DLL并将其上传到服务器的GAC,然后运行以下代码:

 AppDomainSetup setup = new AppDomainSetup(); setup.ApplicationBase = rootPath; setup.DisallowBindingRedirects = false; setup.DisallowCodeDownload = true; setup.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile; Evidence evidence = new Evidence(); evidence.AddHost(new Zone(SecurityZone.MyComputer)); AppDomain ad = AppDomain.CreateDomain("NewAppDomain", evidence, setup); YourClass yourClass = (YourClass)ad.CreateInstanceAndUnwrap(typeof(YourClass).Assembly.FullName, typeof(YourClass).FullName); yourClass.aMethod(); AppDomain.Unload(ad); 

但是,我无法尝试此解决方案,因为我无法访问服务器的GAC,我无法上传DLL。

还有其他方法可以绕过这个问题吗?

我还在EPPlus问题跟踪器上打开了关于此事的错误报告 。

摘要

  • SSIS包
  • Visual Studio 2008 9.0.30729.4462 QFE
  • .NET Framework 3.5 SP
  • SQL Server 2008 SP2 10.0.4311.0 64位
  • EPPlus 2.9.0.1
  • 大输出文件
  • System.IO.IsolatedStorage.IsolatedStorageException:无法确定域的标识

事实certificate,您不需要创建一个全新的DLL并将其上传到GAC以使其工作。 您可以在另一个AppDomain中创建原始类的新实例(或具有您需要调用的方法的新类)。

1)获取导致exception的代码并将其置于单独的方法中。 确保将传入或传出的所有对象都是Serializable或扩展MarshalByRefObject。 在你的情况下:

 public void SavePackage(FileInfo fileInfo, DataTable documentList) { using (ExcelPackage package = new ExcelPackage(fileInfo)) { ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("Documents"); for (Int32 i = 0; i < documentList.Rows.Count; i++) { for (Int32 j = 0; j < documentList.Columns.Count; j++) { worksheet.Cells[i + 1, j + 1].Value = documentList.Rows[i][j]; } } package.Save(); } } 

2)使用上面提到的代码创建一个新类的实例。

 AppDomainSetup setup = new AppDomainSetup(); setup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory; Evidence evidence = new Evidence(AppDomain.CurrentDomain.Evidence); evidence.AddAssembly(Assembly.GetExecutingAssembly().FullName); evidence.AddHost(new Zone(SecurityZone.MyComputer)); AppDomain ad = AppDomain.CreateDomain(DomainName, evidence, setup); ScriptMain mainClass = (ScriptMain)ad.CreateInstanceAndUnwrap(typeof(ScriptMain).Assembly.FullName, typeof(ScriptMain).FullName); 

3)调用方法,然后卸载AppDomain。

 try { mainClass.SavePackage(fileInfo, documentList); } finally { AppDomain.Unload(ad); }