2017-11-18 130 views
0

我需要将文件打包到TSQL脚本中的rar归档中。从下面的C#-script功能,所以我编译DLL:TSQL:执行CLR存储函数抛出System.Security.SecurityException错误

using System; 
using System.Diagnostics; 
using System.Collections; 
using System.Collections.Generic; 
using System.Data.SqlTypes; 
using Microsoft.SqlServer.Server; 

public partial class UserDefinedFunctions 
{ 
    [Microsoft.SqlServer.Server.SqlFunction()] 
    static public SqlInt32 RarFiles(SqlString WORK, SqlString TARGET, SqlString SRC, SqlString SIZE) 
    { 
     ProcessStartInfo p = new ProcessStartInfo(); 
     p.FileName = @"C:\Program Files\WinRAR\rar.exe"; 
     p.Arguments = String.Format 
     (
      "a -cfg- -ep1 -idcdp -m5 -r -s -v{0} {1} {2}", 
      SIZE.ToString(), 
      TARGET.ToString(), 
      SRC.ToString() 
     ); 
     p.WorkingDirectory = WORK.ToString(); 
     Process x = Process.Start(p); 
     return x.ExitCode; 
    } 
} 

用命令:

%SYSTEMROOT%\Microsoft.NET\Framework64\v2.0.50727\csc.exe /target:library c:\test\rarfiles.cs

然后在TSQL我创建组件,代码:

ALTER AUTHORIZATION ON DATABASE::[Test] TO [sa]; 
GO 
ALTER DATABASE [Test] SET TRUSTWORTHY ON 
GO 
CREATE ASSEMBLY [CLRFunctions] 
FROM 'C:\test\RarFiles.dll' 
WITH PERMISSION_SET = EXTERNAL_ACCESS; 
GO 
CREATE FUNCTION [dbo].RarFilesCLR 
(
    @work [nvarchar](max), 
    @target [nvarchar](max), 
    @source [nvarchar](max), 
    @size [nvarchar](max) 
) 
RETURNS INT 
AS EXTERNAL NAME CLRFunctions.UserDefinedFunctions.RarFiles; 
GO 

最后,我试图执行功能:

DECLARE @work nvarchar(max) = 'c:\test'; 
DECLARE @target nvarchar(max) = 'c:\test\res.rar'; 
DECLARE @source nvarchar(max) = 'c:\test\source'; 
DECLARE @size nvarchar(max) = '20M'; 
SELECT [dbo].RarFilesCLR(@work, @target, @source, @size); 

抛出一个错误

System.Security.SecurityException: 
in UserDefinedFunctions.RarFiles(SqlString WORK, SqlString TARGET, SqlString SRC, SqlString SIZE)`... 

有人能向我解释什么是错在这里?

+0

你的(SQL服务器服务)帐户权限的路径应该位于WinRAR.exe,源文件和目标权限? – Deadsheep39

+0

@ Deadsheep39我不确定。但我正在自己的笔记本电脑上测试代码,所以我希望我所做的全部都是管理员权限... –

+0

请更新完整的错误消息,因为它会在搜索时帮助其他人。谢谢。 –

回答

1

创建程序集时,您需要使用UNSAFE作为权限集。这是您开始新的Process所必需的。

此外,您应该发布整个错误消息,因为它经常会提供有关正在进行的和/或要做什么的线索。只发布错误信息的第一个小部分使得难以获得您请求的帮助。

+1

正确。开始一个新的进程是多线程,这就是为什么它是不安全的,而不是EXTERNAL_ACCESS。 –