COM(VB/VBA/Script)利用服务标记调用WCF服务
之一使用类型化契约
LazyBee(http://lazybee.cnblogs.com/)
随着WCF的逐渐被广大开发人员采用,有时候就会遇到旧的系统调用新写的WCF服务的场景,这篇文章中主要介绍COM(VB/VBA/Script)利用类型化契约的服务标记调用WCF服务的方式。
第一步:创建WCF服务
1 打开Visual Studio 2008, 新建一项目,我们这里建立一个Web站点,采用WCF Service Application模板,新项目名称为WCFServiceMoniker,如下图所示:

2 单击“Ok”之后,VS2008将为我们生成相应的目录结构和文件,如下:

3 为了简单,我们不对生成的目录结构做任何改动。接下来,我们打开IService1.cs文
件,删除系统生成的操作契约,然后增加我们自己的契约如下:

Code
1
namespace WCFServiceMoniker
2
3

{
4
5
[ServiceContract]
6
7
public interface IService1
8
9
{
10
11
[OperationContract]
12
13
string SayHello(string yourwords);
14
15
}
16
17
}
18
19
4 接着我们打开Service1.cs文件,删除自动生成的内容,增加对SayHello方法的实现:
1
namespace WCFServiceMoniker
2
3

{
4
5
public class Service1 : IService1
6
7
{
8
9
public string SayHello(string yourwords)
10
11
{
12
13
return string.Format("Hello World! You entered: {0}", yourwords);
14
15
}
16
17
}
18
19
}
20
21
5 针对Web.config我们不做任何改动,其关于WCF部分的设置如下:

Code
1
<system.serviceModel>
2
3
<services>
4
5
<service name="WCFServiceMoniker.Service1" behaviorConfiguration="WCFServiceMoniker.Service1Behavior">
6
7
<!-- Service Endpoints -->
8
9
<endpoint address="" binding="wsHttpBinding" contract="WCFServiceMoniker.IService1">
10
11
<!--
12
13
Upon deployment, the following identity element should be removed or replaced to reflect the
14
15
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
16
17
automatically.
18
19
-->
20
21
<identity>
22
23
<dns value="localhost"/>
24
25
</identity>
26
27
</endpoint>
28
29
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
30
31
</service>
32
33
</services>
34
35
<behaviors>
36
37
<serviceBehaviors>
38
39
<behavior name="WCFServiceMoniker.Service1Behavior">
40
41
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
42
43
<serviceMetadata httpGetEnabled="true"/>
44
45
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
46
47
<serviceDebug includeExceptionDetailInFaults="false"/>
48
49
</behavior>
50
51
</serviceBehaviors>
52
53
</behaviors>
54
55
</system.serviceModel>
56
57
6 好了,我们的WCF服务已经建好了,编译一下,一切Ok. 接下来我们需要在IIS中创建一个虚拟目录了,我们叫WCFServiceMoniker,让其指向WCF服务所在的目录。
7 好了,我们在IE中输入http://localhost/WCFServiceMoniker/Service1.svc看看,是否能看到我们熟悉的WCF Service的界面,正常情况下应该没有问题。
第二步:创建客户端库文件
1 在解决方案中增加Client项目。这里我们选中的是Class Library模板,项目名称为Client.

2 单击”Ok”按钮之后,VS2008将为我们生成一个包含Class1.cs文件的项目,我们先删除Class1.cs文件,然后打开Client的项目属性页。在Build Events的Pre-build event command line中增加产生WCF Service客户端的命令:
Call "D:\Program Files\Microsoft Visual Studio 9.0\VC\vcvarsall.bat" x86

svcutil /language:cs /config:$(ProjectDir)App.config /out:$(ProjectDir)generatedClient.cs http://localhost/WCFServiceMoniker/service1.svc?wsdl

如下图所示:

注意:在这里我的VS2008是安装在D盘,如果你的VS2008安装在其他位置,你需要将第一个命令行改成相应的安装目录。
3 单击”Ok”按钮。好了,现在让我们编译一下Client项目,系统将在Client项目的目录中自动产生一个名为generatedClient.cs的文件,我们把这个文件增加的Client项目中。
4 打开Client项目的AssemblyInfo.cs文件,然后找到[assembly: ComVisible(false)],将其改成[assembly: ComVisible(true)],更改这个属性的目的是为了后面将类型库注册成COM。
5 再次打开Client的项目属性,选中Signing(签名)标签,然后在sign the assembly前面的Checkbox打上勾。这时下面的Choose a strong name key file将从disable变成enable,我们选择<New…>,然后将弹出一个创建强命名Key文件的对话框,我们输入WCFServiceMonikerKey,然后输入你所希望的密码,例如:http://lazybee.cnblogs.com/,然后点击“OK”我们的Key文件就创建好了。(这一步主要是为了将生成的程序集放入全局程序集缓存中。)
6 再次编译一下Client,发现系统找不到ServiceModel命名空间,我们将System.ServiceModel添加到Reference(应用)中,再次编译,一切搞定。
第三步:注册Client程序集
1 将Client.dll添加的全局程序集缓存中
Gacutil /i Client.dll
2 向COM注册Client.dll程序集中的类型
Regasm Client.dll /t
运行此命令之后,将会注册程序集中的类型,同时生成Client.tlb文件。
3 现在如果我们打开OLEView,我们就可以在Type Libraries(类型库)中看到刚才注册的Client类型了。
4 由于我们可能需要多次进行注册反注册工作,所以我为此写了两个批处理文件。以下是这两个批处理文件的内容:
注册的批处理文件Reg.bat的内容如下:
1
@echo off
2
3
"D:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\gacutil" /i Client.dll
4
5
%systemroot%\Microsoft.NET\Framework\v2.0.50727\Regasm Client.dll /t
6
7
Pause
8
反注册的批处理文件UnReg.bat
的内容如下:
1
@echo off
2
3
"D:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\gacutil" /u Client
4
5
%systemroot%\Microsoft.NET\Framework\v2.0.50727\Regasm Client.dll /t /u
6
7
rem del .\bin\debug\Client.dll
8
9
del Client.tlb
10
11
Pause
12
第四步:在Script中调用WCF服务
1 在我们写Script文件之前,首先让我们用OLE打开刚才注册的Client.dll的COM类型信息看看,打开之后如下图所示:

2 大家注意红色框框中的内容,左边红框中是我们的服务契约IService1接口,右边红框是注册之后的UUID,在我们的Script中将要使用这个UUID.
3 下面就是创建我们的Script文件了,我们起名为CallWCFService_TypedContract.vbs,内容如下:

Code
1
'---------------------------------------------------------------
2
3
' Typed Contract service moniker example
4
5
'---------------------------------------------------------------
6
7
' Create a service moniker object using a strongly typed contract
8
9
' This references the address, a standard binding type and the
10
11
' locally registered COM-visible contract ID
12
13
14
15
monikerString = "service:address='http://localhost/WCFServiceMoniker/Service1.svc'"
16
17
monikerString = monikerString + ", binding=wsHttpBinding"
18
19
monikerString = monikerString + ", contract={4FBDA94E-8B89-32EC-BC28-2A0A5E9B7C74}"
20
21
22
23
' Create the service moniker object
24
25
Set serviceMoniker = GetObject(monikerString)
26
27
28
29
' Call the service operations using the moniker object
30
31
WScript.Echo serviceMoniker.SayHello("I am LazyBee, My blog is http://lazybee.cnblogs.com/ ")
32
33
34
35
Set serviceMoniker= nothing
36
4 保存之后,直接双击运行,你就可以看到运行结果了:
第五步:在Word的宏中调用WCF服务
1 打开Word, 添加一个宏(宏-)Visal Basic编辑器或者通过录制宏的方式添加),增加下面的代码:

Code

Sub CallWCFService_TypedContract()Sub CallWCFService_TypedContract()


Dim strMonikerString As String

Dim serviceMoniker As Object


'---------------------------------------------------------------

' Typed Contract service moniker example

'---------------------------------------------------------------

' Create a service moniker object using a strongly typed contract

' This references the address, a standard binding type and the

' locally registered COM-visible contract ID


monikerString = "service:address='http://localhost/WCFServiceMoniker/Service1.svc'"

monikerString = monikerString + ", binding=wsHttpBinding"

monikerString = monikerString + ", contract={4FBDA94E-8B89-32EC-BC28-2A0A5E9B7C74}"


' Create the service moniker object

Set serviceMoniker = GetObject(monikerString)


' Call the service operations using the moniker object

MsgBox serviceMoniker.SayHello("I am LazyBee, My blog is http://lazybee.cnblogs.com/ ")


Set serviceMoniker = Nothing

End Sub


2 直接运行,同样能得到上图类似的结果。
注:在VB6中调用和Word中调用是一样的。
本文的源代码下载地址为:https://files.cnblogs.com/LazyBee/WCFServiceMonikerSolution.zip
(转载请注明出处:http://lazybee.cnblogs.com/)