如何在 Windows 服务中承载远程对象
更新日期: 2004年04月20日
本页内容
目标
本章的目标是:
• |
在 Windows 服务中承载远程对象。 |
• |
使用 TCP 通道从客户端应用程序访问远程对象。 |
适用范围
本章适用于以下产品和技术:
• |
Microsoft Windows XP 或 Windows 2000 Server (Service Pack 3) 以及更高版本的操作系统 |
• |
Microsoft .NET Framework 版本 1.0 (Service Pack 2) 以及更高版本 |
• |
Microsoft Visual Studio® 1.0 .NET 以及更高版本 |
• |
Microsoft Visual C#® .NET |
如何使用本章内容
若要学好本章内容:
• |
您必须具有使用 Visual C# .NET 进行编程的经验。 |
• |
您必须具有使用 Visual Studio .NET 开发环境的经验。 |
• |
您必须具有开发和实现 Windows 服务的经验。 |
• |
您必须知道如何使用 Windows 管理工具来创建 Windows 用户帐户。 |
摘要
使用 Microsoft® .NET Framework Remoting 功能生成的远程对象必须驻留在 Microsoft Windows® 服务、自定义的可执行文件或 ASP.NET 中,以便客户端应用程序访问。本章介绍如何在 Windows 服务中承载远程对象,以及如何从客户端应用程序调用它。
您必须了解的背景知识
在开始学习本章之前,您应该知道:
• |
远程对象是使用 .NET Remoting 技术进行远程访问的 .NET 对象。它们可驻留在 Windows 服务、自定义的可执行文件或 ASP.NET 中。 |
• |
客户端使用 TCP 通道与自定义的可执行文件或 Windows 服务中承载的远程对象进行通信。 |
• |
客户端使用 HTTP 通道与 ASP.NET 中承载的远程对象进行通信。 |
• |
如果安全是首要的考虑因素,则在 ASP.NET 中承载对象并使用 HTTP 通道。这使您可以从 ASP.NET 和 IIS 的基本安全功能中受益。 有关如何在 ASP.NET 中(通过 IIS)承载远程对象的信息,请参见 Microsoft 知识库文章 312107“HOW TO:Host a Remote Object in Microsoft Internet Information Services”(如何在 Microsoft Internet 信息服务中承载远程对象),网址如下: http://support.microsoft.com/default.aspx?scid=312107。 |
• |
如果性能是首要考虑的因素,则在 Windows 服务中承载对象并使用 TCP 通道。此选项不提供内置安全性。 |
创建远程对象类
此过程创建一个简单的远程对象类。它提供单个名为 Add 的方法,该方法将两个数相加并返回结果。
• |
创建远程对象类
1. |
启动 Visual Studio .NET 并创建一个新的名为 RemoteObject 的 Visual C# 类库项目。 |
2. |
使用解决方案资源管理器将 class1.cs 重命名为 Calculator.cs。 |
3. |
在 Calculator.cs 中,将 Class1 重命名为 Calculator 并相应地重命名默认的构造函数。 |
4. |
从 MarshalByRefObject 类派生 Calculator 类以使该类是远程的。 public class Calculator : MarshalByRefObject
|
5. |
将下面的公共方法添加到 Calculator 类中。 public int Add( int operand1, int operand2 )
{
return operand1 + operand2;
}
|
6. |
在“生成”菜单上,单击“生成解决方案”。 | |
创建 Windows 服务宿主应用程序
此过程创建一个用来承载远程对象的 Windows 服务应用程序。当服务启动时,它配置 TCP 远程处理通道以侦听客户端请求。
注意:此过程使用 Installer 类和 Installutil.exe 命令行实用程序来安装 Windows 服务。要卸载该服务,可带 /u 命令选项运行 Installutil.exe。或者,您也可以使用“安装和部署项目”来帮助安装和卸载 Windows 服务。
• |
创建 Windows 服务宿主应用程序
1. |
将一个新的名为 RemotingHost 的 Visual C# Windows 服务项目添加到当前的解决方案中。 |
2. |
使用解决方案资源管理器将 Service1.cs 重命名为 RemotingHost.cs。 |
3. |
在 RemotingHost.cs 中将 Service1 类重命名为 HostService 并相应地重命名默认的构造函数。 |
4. |
在文件顶部,在现有 using 语句的下面添加以下 using 语句。 using System.Runtime.Remoting;
|
5. |
找到 Main 方法,用下面的代码行替换用来初始化 ServicesToRun 变量的现有代码行。 ServicesToRun = new System.ServiceProcess.ServiceBase[] {
new HostService() };
|
6. |
找到 InitializeComponent 方法,将 ServiceName 属性设置为 RemotingHost。 this.ServiceName = "RemotingHost";
|
7. |
找到 OnStart 方法,然后添加下面的代码行以配置远程处理。配置文件的完全限定路径将作为启动参数传递给该服务。 RemotingConfiguration.Configure(args[0]);
|
8. |
将新的 C# 类文件添加到项目中,并将其命名为 HostServiceInstaller。 |
9. |
添加对 System.Configuration.Install.dll 程序集的程序集引用。 |
10. |
在 HostServiceInstaller 顶部的现有 using 语句下面添加以下 using 语句。 using System.ComponentModel;
using System.ServiceProcess;
using System.Configuration.Install;
|
11. |
从 Installer 类派生 HostServiceInstaller 类。 public class HostServiceInstaller : Installer
|
12. |
按如下所示的类级别添加 RunInstaller 属性。 [RunInstaller(true)]
public class HostServiceInstaller : Installer
|
13. |
将下面的两个私有成员变量添加到 HostServiceInstaller 类中。当安装该服务时,将会用到这些对象。 private ServiceInstaller HostInstaller;
private ServiceProcessInstaller HostProcessInstaller;
|
14. |
将下面的代码添加到 HostServiceInstaller 类的构造函数中。 HostInstaller = new ServiceInstaller();
HostInstaller.StartType = System.ServiceProcess.ServiceStartMode.Manual;
HostInstaller.ServiceName = "RemotingHost";
HostInstaller.DisplayName = "Calculator Host Service";
Installers.Add (HostInstaller);
HostProcessInstaller = new ServiceProcessInstaller();
HostProcessInstaller.Account = ServiceAccount.User;
Installers.Add (HostProcessInstaller);
|
15. |
在解决方案资源管理器中,右键单击 RemotingHost,指向“添加”,然后单击“添加新项”。 |
16. |
在“模板”列表中,单击“文本文件”并将文件命名为 app.config。 作为生成过程的一部分,具有 app.config 名称的配置文件被 Visual Studio .NET 自动复制到输出文件夹(例如,<项目目录>\bin\debug)并重命名为 <应用程序名称>.config。 |
17. |
单击“确定”添加该新的配置文件。 |
18. |
将下面的配置元素添加到该新配置文件中。 <configuration>
<system.runtime.remoting>
<application name="RemoteHostService">
<service>
<wellknown type="RemoteObject.Calculator, RemoteObject"
objectUri="RemoteObject.Calculator" mode="Singleton" />
</service>
<channels>
<channel ref="tcp" port="8085">
<serverProviders>
<formatter ref="binary" />
</serverProviders>
</channel>
</channels>
</application>
</system.runtime.remoting>
</configuration>
|
19. |
在“生成”菜单上,单击“生成解决方案”。 | |
创建一个用来运行该服务的 Windows 帐户
此过程创建一个用来运行 Windows 服务的 Windows 帐户。
• |
创建一个用来运行该服务的 Windows 帐户
1. |
创建一个名为 RemotingAccount 的新本地用户帐户。输入密码并选择“密码永不过期”复选框。 |
2. |
在“管理工具”程序组中,单击“本地安全策略”。 |
3. |
使用“本地安全策略”工具授予新帐户“作为服务登录”权限。 | |
安装 Windows 服务
此过程使用 installutil.exe 实用程序安装 Windows 服务,然后启动该服务。
• |
安装 Windows 服务
1. |
打开命令窗口,将目录更改至 RemotingHost 项目文件夹下的 Bin\Debug 目录。 |
2. |
运行 installutil.exe 实用程序来安装该服务。 installutil.exe remotinghost.exe
|
3. |
在“设置服务登录”对话框中,输入前面在上一过程中创建的帐户的用户名和密码并单击“确定”。 查看 installutil.exe 实用程序的输出结果,并确认该服务已正确安装。 |
4. |
将 RemoteObject.dll 程序集复制到 RemotingHost 项目输出目录(即 RemotingHost\Bin\Debug)中。 |
5. |
从“管理工具”程序组中,启动“服务”MMC 管理单元。 |
6. |
在“服务”列表中,右键单击“Calculator 宿主服务”,然后单击“属性”。 |
7. |
在“启动参数”字段中输入该服务的配置文件 (remotinghost.exe.config) 的完整路径。
注意:完成此操作的快捷方法是选择并复制“可执行文件的路径”字段,然后将其粘贴到“启动参数”字段中。然后附上“.config”字符串。 |
8. |
单击“启动”以启动服务。 |
9. |
确认服务状态更改为“已启动”。 |
10. |
单击“确定”以关闭“属性”对话框。 | |
创建一个供测试用的客户端应用程序
此过程创建一个供测试用的控制台应用程序,用于调用 Windows 服务内的远程对象。
• |
创建一个供测试用的客户端应用程序
1. |
将一个新的名为 RemotingClient 的 Visual C# 控制台应用程序添加到当前解决方案中。 |
2. |
在解决方案资源管理器中,右键单击 RemotingClient,然后单击“设为启动项目”。 |
3. |
添加对 System.Runtime.Remoting.dll 程序集的程序集引用。 |
4. |
添加对 RemoteObject 项目的项目引用。 |
5. |
在 class1.cs 顶部的现有 using 语句下面添加以下 using 语句。 using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using RemoteObject;
|
6. |
将下面的测试代码添加到 Main 方法中,以调用由 Windows 服务承载的 Calculator 对象。 TcpChannel chan = new TcpChannel();
ChannelServices.RegisterChannel(chan);
Calculator calc = (Calculator)Activator.GetObject(
typeof(RemoteObject.Calculator),
"tcp://localhost:8085/RemoteObject.Calculator");
if (calc == null)
System.Console.WriteLine("未能找到服务器");
else
Console.WriteLine("21 + 21 is : " + calc.Add(21,21) );
|
7. |
在“生成”菜单上,单击“生成解决方案”。 |
8. |
运行客户端应用程序,确认控制台输出窗口中显示了正确的结果。 | |
其他资源
有关在 ASP.NET(通过 IIS)中承载远程对象的信息,请参见 Microsoft 知识库文章 312107“HOW TO:Host a Remote Object in Microsoft Internet Information Services”(如何在 Microsoft Internet 信息服务中承载远程对象),网址如下: http://support.microsoft.com/default.aspx?scid=312107。