Can't add System.IO.Compression to trusted assemblies in SQL Server

♀尐吖头ヾ 提交于 2019-12-05 15:07:00

You are trying to import the wrong DLL. That is the "reference" DLL, not the actual "framework" DLL. The following will work as I not only tried it using SQL Server 2012, but I was able to also import System.IO.Compression.FileSystem and execute System.IO.Compression.ZipFile.CreateFromDirectory():

  1. This is needed as you cannot create an ASYMMETRIC KEY from the .Net Framework DLLs:

    ALTER DATABASE [{dbname}] SET TRUSTWORTHY ON;
    
  2. At minimum you need this:

    CREATE ASSEMBLY [System.IO.Compression]
    FROM N'C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.IO.Compression.dll'
    WITH PERMISSION_SET = EXTERNAL_ACCESS;
    
  3. If you want to use either the ZipFile or the ZipFileExtensions classes, you will need this (and this one needs to be set to UNSAFE, unfortunately):

    CREATE ASSEMBLY [System.IO.Compression.FileSystem]
    FROM N'C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.IO.Compression.FileSystem.dll'
    WITH PERMISSION_SET = UNSAFE;
    
  4. Just in case it is not obvious, your assembly that calls methods in the above mentioned assemblies will also need to have a PERMISSION_SET of EXTERNAL_ACCESS.

  5. And just to be completely clear for anyone who might not be aware of this:

    1. The Zip* classes as well as the System.IO.Compression and System.IO.Compression.FileSystem assemblies are new as of .Net 4.5
    2. You can only use items new to .Net 4.0 / 4.5 in SQL Server 2012 and 2014 (the current version); SQL Server 2005 / 2008 / 2008 R2 are stuck on the .Net 2.0 series.

I know this is an old question, but I was going down this same path earlier this week of writing a SQLCLR function that could be called by ssrs sql code after generating reports, to package them up in a zip file and email them to users.

After a bunch of research and trial and error, using the ssrs web service interface is the easier and more reasonable approach. You don't have to have to touch the database settings at all to use it and do the exact same thing.

To use it, you add a web reference to the ssrs execution service. You can find out which one you need here. Once you have configured and added your web reference, you can write C#/VB code to render whatever report you want as bytes in the format of your choosing, and save them or do what you wish with them like any other stream of bytes. In our case, we wrote a query to get a list of reports to send by user, rendered all of the reports for that user to temp files by using the api, zipped those temp files, attached them to an email, and sent the email off to the user.

there is a good, trivial example of how to render and save a report to disk with the api here. (code below in case the link dies)

string historyID = null;
string deviceInfo = null;
// Can be XML, NULL, CSV, IMAGE, PDF, HTML4.0, HTML3.2,
// MHTML, EXCEL, and HTMLOWC
string format = "Excel"; 
Byte[] results;
string encoding = String.Empty;
string mimeType = String.Empty;
string extension = String.Empty;
ReportingExec.Warning[] warnings = null;
string[] streamIDs = null;


ReportingExec.ReportExecutionService re = new ReportingExec.ReportExecutionService();
re.Credentials = System.Net.CredentialCache.DefaultCredentials;

ReportingExec.ExecutionInfo ei = re.LoadReport("/directory/ReportName", historyID);

ReportingExec.ParameterValue[] rptParameters = new ReportingExec.ParameterValue[1];

rptParameters[0] = new ReportingExec.ParameterValue();
rptParameters[0].Name = "DateFormatID";
rptParameters[0].Value = "fr-FR";

re.SetExecutionParameters(rptParameters, "en-us");


results = re.Render(
    format, deviceInfo, out extension, out encoding, 
    out mimeType, out warnings, out streamIDs);

FileStream stream = File.Create("C:\\report.xls", results.Length);
stream.Write(results, 0, results.Length);
stream.Close();

one thing that was confusing to me intially, was where to find the various types above. when you add the web reference to your project, the web reference will have all the necessary types pulled in, in the namespace named after the name you gave your web reference. so if you named your web reference FooService, all the reporting types would be in namespace FooService. so you could find FooService.ParameterValue, FooService.ReportExecutionService, etc there.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!