嵌入式调用另一段代码

嵌入式调用另一段代码,第1张

将第三方程序集作为资源嵌入后,AppDomain.AssemblyResolve在应用程序启动期间添加代码以订阅当前域肆碰的事件。只要CLR的Fusion子系统未能根据有效的探测(策略)找到程序集,就会触发此事件。在的事件处理程序中AppDomain.AssemblyResolve,使用加载资源,Assembly.GetManifestResourceStream并将其内容作为字节数组送入相应的Assembly.Load重载。以下是一种这样的实现在C#中的样子:

AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>

{

var resName = args.Name + ".dll"

var thisAssembly = Assembly.GetExecutingAssembly()

using (var input = thisAssembly.GetManifestResourceStream(resName))

{

return input != null

? Assembly.Load(StreamToBytes(input))

: null

}

}

在那里StreamToBytes可以定义为:

static byte[] StreamToBytes(Stream input)

{

var capacity = input.CanSeek ? (int) input.Length : 0

using (var output = new MemoryStream(capacity))

{

int readLength

var buffer = new byte[4096]

do

{

readLength = input.Read(buffer, 0, buffer.Length)

output.Write(buffer, 0, readLength)

}

while (readLength != 0)

return output.ToArray()

}

}

最后,正如一些人已经提到的那样,ILMerge可能是另一个可以考虑的选择,尽管它涉及更多。

解决方法

我遇到兆慎的情况是,我正在创建一个使用另一个第三方DLL的DLL,但我希望能够将第三方DLL构建到我的DLL中,而不是尽可能将它们保持在一起。

这是C#和.NET 3.5。

我要这样做的方式是将第三方DLL存储为嵌入式资源,然后在执行第一个DLL时将其放置在适当的位置。

我最初计划执行此 *** 作的方法是编写代码以将第三方DLL放在System.Reflection.Assembly.GetExecutingAssembly().Location.ToString()

减去最后一个指定的位置/nameOfMyAssembly.dll。我可以.DLL在该位置成功保存第三方(最终被保存为

C:\ Documents and Settings \ myUserName \ Local Settings \ Application Data

\ assembly \ dl3 \ KXPPAX6Y.ZCY \裂猜谈 A1MZ1499.1TR \ e0115d44 \

91bb86eb_fe18c901

),但是当我到达需要此DLL的代码部分时,找不到它。

创建自定义程序集

若要创建自定义程序集,请执行以下步骤︰

创建 Visual Studio 的类库。在文件菜单上,指向新建、 指向项目,然后单击类库。

指定的名称和位置。例如,我使用了 SimpleClassLibrary 和 C:\Documents 以及 Settings\user1\My Documents\Visual Studio 2005\projects。

打开类文件 (在本例中,Class1.vb),然后再创建您想要在报表服务中使用的函数。我的情况而言,我只是创建一个简单的共享的函数。

注意:因为这是一个共享的函数 (在 C# 静态),我们不需要通过使用实例化的对象来访问它。这起我们是如何引用在本文的后面我们程序集,请记住这一点。

Public Class Class1

Public Shared Function DoSomething() As String

Return "string data returned from custom assembly"

End Function

End Class

一旦您添加完所有代码,单击生成菜单生成 SimpleClassLibrary 。此步骤创建各自的 bin 文件夹中的程序集或托管的.dll。在我的示例中,此步骤创建我的程序集,SimpleClassLibrary.dll,我 Documents\Visual Studio 2005\Projects\ SimpleClassLibrary\bin\Debug 文件夹中。

将自定义程序集复制到 SQL 报表服务文件夹

使您的程序集可供报表设计器和报表在报表服务的服务器。若要执行此 *** 作,必须将.dll 复制到报表设计器文件夹和报表服务器文件夹。

注意:该路径可能是有点不同,这取决于您的安装路径。

报告服务 2005 年将.dll 文件复制到以下文件夹︰

编写该 Visual Studio 8\Common7\IDE\PrivateAssemblies

计划该 SQL Server\MSSQL.3\Reporting Services\ReportServer\bin

对于报告服务 2000,将.dll 文件复制到以下文件夹︰

计划该 SQL Server\80\Tools\Report 设计器

计划该 SQL Server\MSSQL\中前Reporting Services\ReportServer\bin

注意:由于您所要做的每次更改的代码时,空侍它可能有点乏味。许多开发人员创建批处理文件来斗培吵处理此任务。下面是可以使用的示例批处理文件。

@ECHO OFF

REM Name: SRSDeploy.bat

REM

REM This batch files copies my custom assembly to my Reporting Services folders.

REM Run this from the directory where the customer assembly was compiled.

REM Be sure to close any applications that have your custom assembly open.

REM

REM This is the SQL Server 2005 version:

copy SimpleClassLibrary.dll "C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies"

copy SimpleClassLibrary.dll "C:\Program Files\Microsoft SQL Server\MSSQL.3\Reporting Services\ReportServer\bin"

REM This is the SQL Server 2000 version:

REM copy SimpleClassLibrary.dll "C:\Program Files\Microsoft SQL Server\80\Tools\Report Designer"

REM copy SimpleClassLibrary.dll "C:\Program Files\Microsoft SQL Server\MSSQL\Reporting Services\ReportServer\bin"

我通常通过在项目中创建自定义生成后事件处理此任务。为此,转到您的项目的属性。接下来,单击编译选项卡,然后单击生成事件。这将打开生成事件对话框。选择生成后事件命令行,然后再键入以下命令︰

复制"$(目标路径)""C:\Program 数值 Visual Studio 8\Common7\IDE\PrivateAssemblies\"

复制"$(目标路径)""C:\Program 该 SQL Server\MSSQL.3\Reporting Services\ReportServer\bin\"

这可以使用后期生成宏来指定我的程序集的位置。创建生成后事件的详细信息,请访问下面的 Microsoft 开发人员网络 (MSDN) Web 站点︰

http://msdn2.microsoft.com/en-us/library/42x5kfw4.aspx

在报表服务中添加自定义程序集的引用

要添加到您的自定义程序集的引用,请在报表设计器中打开报表服务报表。若要执行此 *** 作,请按照下列步骤 *** 作:

打开将引用自定义程序集的报表。

在报表菜单上单击报表属性。

在报表属性对话框中,单击引用选项卡。

在引用,单击程序集名称的列标题旁边的省略号 (...) 按钮。

注意:基于实例的成员是类部分。它不是静态成员。静态 (也称为"共享"在某些我们报告服务文档) 表示成员可用类的每个实例,并且每个实例都使用同一存储位置。通过使用共享的关键字在 Microsoft Visual Basic 和在 C# static 关键字声明静态成员。这可能是有点令人困惑。这意味着,如果您自定义的程序集包含需要访问的实例成员,则将需要类部分中指定的类名和实例名。因为我将从报表服务呼叫的方法被定义为静态,在 Visual Basic 中使用共享的关键字,我将代替类节使用参考部分。

在添加引用对话框中,单击浏览。(在 SQL Server 2005 中,请单击浏览选项卡)。

找到并单击自定义程序集。单击打开。(在 SQL Server 2005 中,请单击添加,而不是打开)。

在添加引用对话框中,单击确定。

在报表属性对话框中,单击确定。

现在我们就可以使用报表服务中的自定义程序集。

在报表设计器中打开报表 (.rdl 文件)。

为了说明如何在报表服务中使用的自定义程序集,请添加一个文本框。若要执行此 *** 作,将从工具箱向报表空白文本框。

文本框属性,在单击值属性,然后使用下面的语法调用的函数。

=ClassLibraryName.ClassName.MethodName or Namespace.ClassName.MethodName

在我的示例中,指定以下。

=SimpleClassLibrary.Class1.DoSomething()

其他格式用于引用报表服务中的代码。如果调用嵌入的代码,例如,使用以下格式。

=Code.MethodName()

如果使用实例来调用非静态的还是基于实例的方法中,自定义程序集中,请使用以下格式。

=Code.InstanceName.Method

注意:您已设置引用以不同的方式如果您想要使用基于实例的方法。要做到这一点,请需要转到报表属性,单击引用选项卡,然后在类部分指定的类名和实例名。

如果自定义程序集需要更多权限的代码访问安全性

如果自定义程序集需要更多比默认执行级别权限的权限,您必须进行一些代码访问安全的更改。如果使用代码访问安全的权限问题发生,很可能会看到"#Error"的是您自定义的程序集,而不是预期的结果。若要确定是否出现此问题,您可以执行的几个快速步骤以及有关如何为您的自定义程序集授予其他权限的详细说明,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章︰

842419如何向报表中报告服务引用自定义程序集授予权限

注意:以下方法是测试可帮助确定是否出现了代码访问安全问题。不建议使用以下方法,因为它为您自定义程序集授予完全信任权限。

为您的自定义程序集,创建新的代码组,然后再授予完全信任权限。若要执行此 *** 作,打开程序该 SQL Server\MSSQL.3\Reporting Services\ReportServer\rssrvpolicy.config 文件,然后添加以下代码。

<CodeGroup class="UnionCodeGroup"

version="1"

PermissionSetName="FullTrust"

Name="MyCodeGroup"

Description="Code group for my data processing extension">

<IMembershipCondition class="UrlMembershipCondition"

version="1"

Url="C:\pathtocustomassembly\customassembly.dll"

/>

</CodeGroup>

我们建议您创建更特定的权限,而不是分配给代码组设置此权限设置。这篇文章已预期,您并且正在运行的自定义程序集,并且这需要更多详细信息。

注意:自定义程序集通常报表设计器中正常工作。但是,您可能会发现,当您部署,然后尝试在报表服务器中运行的自定义程序集,默认执行级别权限不足。这样做的原因是,默认情况下,报表设计器使用"完全信任"权限运行自定义程序集。但是,在将报表部署到报表服务器时,在报表服务器中授予的默认权限设置为执行级别。如果发生此问题,您很可能会看到而不是从自定义程序集的预期结果报表控件中的"#Error"。

嵌入的代码

嵌入的代码是报表属性对话框中的代码部分中编写的代码。嵌入的代码是一个不错的选择,将在报告中多次调用的代码。如果您想要重用代码在多个报表,自定义的程序集可能是更好的选择。若要创建嵌入式的函数,请执行以下步骤︰

在报表菜单上单击报表属性。

在报表属性对话框中,单击代码选项卡

添加下面的函数,然后单击确定。

Public Function EmbeddedFunction() as String

Return "this is from embedded code function"

End Function

在报告中,将添加一个新的文本框。

值属性中添加以下。

=code.EmbeddedFunction


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/12337564.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-24
下一篇 2023-05-24

发表评论

登录后才能评论

评论列表(0条)

保存