在大多数情况下,必须在使用前注册VB6 DLL和OCX。在Visual Basic项目(VBP)文件中,引用的对象列出如下:
Object={70031B70-1070-0D70-AC0E-B049A0701010}#1.0#0; Component.ocx
Reference=*\G{000CD090-0D00-4F07-0707-80040E010704}#1.0#0#..\References\GeneralLibrary.dll#General Purpose Libraries
更新这些文件后,我需要更改VB6项目中的所有引用。由于VBP文件只是文本文件,因此可以使用文本解析更新这些引用。需要注意的是,我需要提前知道每个组件和版本的GUID。
经过一些搜索后,我发现Windows中的oleaut32.dll
库可用于从DLL收集信息。这可以通过C#使用ITypeLib
和ITypeInfo
来充分利用。
我能够搜索一个使用C#来读取有问题的DLL文件以获取GUID和版本信息的方法。但是,ITypeLib
和ITypeInfo
的可用文档没有任何示例。我也无法在网上找到任何例子。
示例代码:
class Program
{
[DllImport("oleaut32.dll", PreserveSig=false)]
public static extern ITypeLib LoadTypeLib([In, MarshalAs(UnmanagedType.LPWStr)] string typelib);
static void Main(string[] args)
{
ITypeLib dllLibrary;
ITypeInfo information;
dllLibrary = LoadTypeLib("C:\\common_files\\Common.dll");
dllLibrary.GetTypeInfo(0, out information);
Console.ReadLine();
}
}
问题
如何使用ITypeLib和ITypeInfo获取DLL或OCX的GUID和版本信息?
警告:由于我们的系统部署方式以及注册表中有许多旧的DLL工件同名的事实,我想避免注册DLL然后读取从注册表中注册的内容
我也无法找到用于获取版本信息的DLL,如this question中所述。
答案 0 :(得分:2)
以下代码将在C#中加载tlb - 我没有尝试使用嵌入式tlb的DLL或OCX,但它可能适用于那些。如果没有,你需要从嵌入资源中提取tlb(yay!more PInvoke),然后直接在tlb上运行。这是一个完整的命令行应用程序 - 您可以将其复制并粘贴到新的源文件中,并在命令行上进行编译和测试。
using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
public class TypeLibTest
{
[DllImport("oleaut32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)]
private static extern IntPtr LoadTypeLib(string fileName, out System.Runtime.InteropServices.ComTypes.ITypeLib typeLib);
public static void Main(string[] args)
{
System.Runtime.InteropServices.ComTypes.ITypeLib typeLib = null;
IntPtr ptr = IntPtr.Zero;
string file = arg[0];
try
{
LoadTypeLib(file, out typeLib);
typeLib.GetLibAttr(out ptr);
var typeAttr = (System.Runtime.InteropServices.ComTypes.TYPELIBATTR) Marshal.PtrToStructure(ptr, typeof(System.Runtime.InteropServices.ComTypes.TYPELIBATTR));
Console.WriteLine("{0}.{1}", typeAttr.wMajorVerNum, typeAttr.wMinorVerNum);
}
catch (COMException ex)
{
Console.WriteLine("Error: " + ex.Message);
}
finally
{
if (typeLib != null && ptr != IntPtr.Zero)
{ typeLib.ReleaseTLibAttr(ptr); }
}
}
}