前段时间有个业务需求要在PB程序里上传文件到文件服务器(文件上传服务是个Java Web Service),由于PB7在调用Web service方面存在很多的弊端,而且极其不好用,所以决定用C#2005写个dll,给PB调用。PB通过调用c# dll实现文件上传。现在问题变成了PB如何调用C#写的dll和C#如何调用Java Web Service,由于C#调用Java Web Service很方便而且资料也很多,所以本文接下去只讨论PB如何调用C#写的dll?
1.C# dll制作
1) 新建工程,工程类型为“类库”,即工程编译之后能得到dll,假设工程名称为CallForPB,默认的命名空间也为CallForPB;
2) 工程的属性设置,主要有下述2个重要的技术点,如不设置的话,PB无法访问编译之后的dll
a) 在“生成”属性页中把“为Com Interrop注册”选项勾上
b) 在AssemblyInfo.cs程序集信息文件中,设置[assembly: ComVisible(true)]
c) 新建一个类,命名为ServiceProvider,其有个方法uploadFile(string fileName);
d) 至于uploadFile方法如何调用WEB Service上传文件,这里不再细说。
3)编译生成CallForPB.dll文件,编译的时候C# 2005就会为该dll写注册表信息。
2. PB如何调用该dll
1)如果pb程序开发和刚才提到的C#dll开发在同一台机器的话,那么不需要写注册表信息,因为C#2005在编译生成该dll文件的时候已经在注册表中写入com服务注册信息了。如果不是的话,就要导入注册表信息,大概如下:
[HKEY_CLASSES_ROOT\CLSID\{A4C29508-149C-3D3A-B68D-5D5103E79AEF}]
@="CallForPB.ServiceProvider"
[HKEY_CLASSES_ROOT\CLSID\{A4C29508-149C-3D3A-B68D-5D5103E79AEF}\Implemented Categories]
[HKEY_CLASSES_ROOT\CLSID\{A4C29508-149C-3D3A-B68D-5D5103E79AEF}\Implemented Categories\{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}]
[HKEY_CLASSES_ROOT\CLSID\{A4C29508-149C-3D3A-B68D-5D5103E79AEF}\InprocServer32]
@="mscoree.dll"
"ThreadingModel"="Both"
"Class"="CallForPB.ServiceProvider"
"Assembly"="CallForPB, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
"RuntimeVersion"="v2.0.50727"
"CodeBase"="file:///C:/WINDOWS/system32/CallForPB.dll"
[HKEY_CLASSES_ROOT\CLSID\{A4C29508-149C-3D3A-B68D-5D5103E79AEF}\InprocServer32\1.0.0.0]
"Class"="CallForPB.ServiceProvider"
"Assembly"="CallForPB, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
"RuntimeVersion"="v2.0.50727"
"CodeBase"="file:///C:/WINDOWS/system32/CallForPB.dll"
[HKEY_CLASSES_ROOT\CLSID\{A4C29508-149C-3D3A-B68D-5D5103E79AEF}\ProgId]
@="CallForPB.ServiceProvider"
[HKEY_CLASSES_ROOT\CallForPB.ServiceProvider]
@="CallForPB.ServiceProvider"
[HKEY_CLASSES_ROOT\CallForPB.ServiceProvider\CLSID]
@="{A4C29508-149C-3D3A-B68D-5D5103E79AEF}"
大家可以通过在C#dll开发机上搜索注册表信息得到详细注册信息,然后将其导出即可。
2)PB调用dll,假设是w_frame窗体调用
a)申明一个窗体变量:OLEObject callForPB
b)在open事件里,初始化callForPB
int li_return
//
callForPB= create OLEObject
li_return = callForPB.ConnectToNewObject("CallForPB.ServiceProvider")
//初始化失败
if li_return < 0 then
messagebox('load ocx error',li_return)
DESTROY callForPB
close(this)
end if
c)在close时间销毁callForPB
if not isnull(callForPB) then
destroy callForPB
end if
d)调用uploadFile函数
callForPB.uploadFile(文件路径);