在现代软件开发中,经常需要将不同的技术栈整合到一起,以实现更强大的功能。本文将介绍如何通过COM、SxS(Side-by-Side)和CLR(公共语言运行时)实现.NET程序集与FoxPro应用程序的无注册激活。
首先,需要创建一个.NET类,并将其作为COM服务器。这需要包括特定的命名空间,并为类生成一个GUID属性。
using System.Runtime.InteropServices;
namespace NetNamespace
{
[Guid("503322EE-482A-442F-8984-4FC3FDC53A0C")]
public class NetClass
{
public string NetMethod(string input)
{
// 在这里实现逻辑...
return "处理结果";
}
}
}
在默认情况下,如果没有指定ClassInterfaceType属性,它将使用AutoDispatch。如果需要通过类明确实现的接口暴露功能,可以将ClassInterfaceType设置为None。
为了实现无注册互操作性,必须使用强名称对程序集进行签名。可以通过在命令提示符中执行sn -k keypair.snk命令生成密钥对。然后在AssemblyInfo.cs中编辑以下程序集属性并构建项目。
// 启用COM可见性
[assembly: ComVisible(true)]
// 指向密钥对文件以签名程序集
[assembly: AssemblyKeyFileAttribute("..\\..\\keypair.snk")]
// 为类型库生成并应用GUID属性
[assembly: Guid("A67D75D0-7AE7-434F-8A41-2C1E0B48ADF3")]
注意:此属性可以应用于特定方法,以避免暴露整个程序集。
.NET程序集必须有一个SxS清单,描述COM注册信息。在项目中添加一个清单文件,并输入以下程序集标识。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32" name="" version="" publicKeyToken=""/>
<clrClass clsid="" progid="" threadingModel="Both" name="" runtimeVersion="">
</clrClass>
</assembly>
下载GenMan32.zip并解压GenMan32.exe。在命令提示符中执行以下命令以嵌入清单。
genman32.exe "..\bin\Release\assemblyname.dll" /add /manifest:"..\assemblyname.dll.manifest"
注意:根据项目调整相对路径或使用绝对路径。
下载projecthookex.zip并解压projecthookex.vct。通过FoxPro编辑moduleresourceeditor的getdefaultmanifest方法。然后,将编辑后的projecthookex.vct作为Project Class在FoxPro的Project Info中钩住。构建FoxPro应用程序将生成一个外部清单。
LOCAL lcReturn
TEXT TO m.lcReturn textmerge noshow XML
<?xml version="1.0" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity version="9.0.0.0" type="win32" name="" processorArchitecture="x86"/>
<description>
<Description about Foxpro EXE>
</description>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" language="*" processorArchitecture="x86" publicKeyToken="6595b64144ccf1df"/>
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="<.Net Assembly name>" version="<.Net Assembly version>" publicKeyToken="<.Net Assembly publickey token>"/>
</dependentAssembly>
</dependency>
</assembly>
ENDTEXT
RETURN (m.lcReturn)
在FoxPro应用程序中,可以通过以下方式创建对象并调用.NET类的方法。
objVFP = CreateObject("")
lresult = objVFP.NetMethod("")
注意:progid配置在.NET程序集清单中。
如果由于清单配置无效导致COM激活失败,FoxPro应用程序启动时会显示以下错误。
"The application has failed to start because its side by side configuration is incorrect. Please see the application event log or use the command-line sxstrace.exe tool for more detail".
在命令提示符中执行以下命令以开始跟踪。
C:\Windows\System32>SxsTrace Trace -logfile:SxsTrace.etl
启动FoxPro应用程序(COM客户端)并执行触发.NET程序集激活的事件。在命令提示符中停止跟踪。
C:\Windows\System32>SxsTrace Parse -logfile:SxsTrace.etl -outfile:SxsTrace.txt