gpt4 book ai didi

c# - access vba 中的 .net5 com 库

转载 作者:行者123 更新时间:2023-12-05 03:40:03 24 4
gpt4 key购买 nike

我们有一个旧的 Access 工具需要打开用 C# 编写的 guis - Winforms。目前我们只是启动 exe,但如果可能的话,我想直接加载 dll。

到目前为止,我已经有了创建 com 可见库的代码

using System;
using System.Runtime.InteropServices;

namespace COMs {
[ComVisible(true)]
[Guid("C412E308-0D12-42D1-9506-C64A7958B4F9")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IProduktionsstundenCOM {
public void StartProduktionsstunden();
}

[ComVisible(true)]
[Guid("C63D94CD-4978-40C2-AD88-799D9430683F")]
public class ProduktionsstundenCOM : IProduktionsstundenCOM {

public void StartProduktionsstunden() {
throw new NotImplementedException();
}
}
}

它会构建并创建 .comhost.dll,然后我将其注册到 regsvr32 appname.comhost.dll

这样做之后,我无法在 Access 引用窗口中找到该库,如果我浏览到它并尝试添加它,我会收到此错误“无法添加对所选文件的引用”(“Verweis auf die angegebene Datei kann nicht hinzugefügt韦登。”)。我能找到的唯一有用的文章是这篇 https://learn.microsoft.com/en-us/dotnet/core/native-interop/expose-components-to-com它还指出 .net5 无法创建 .tlb 文件,我什至不知道是否需要它们。

有没有办法让它工作?

最佳答案

我遇到了类似的问题并遇到了以下 github 存储库,它显示了 IDL 文件的外观。它还向您显示您将需要哪些额外的注册表项。您可以将其用作起点。 link

您的 IDL 文件的基本结构应如下所示:

[
uuid(your library GUID),
version(1.0),
helpstring("ComTestLibrary")
]
library ComTestLibrary
{
importlib("STDOLE2.TLB");

[
odl,
uuid(your interface GUID),
dual,
oleautomation,
nonextensible,
helpstring("ComTestLibrary"),
object,
]
interface IComTest : IDispatch
{
[
id(1),
helpstring("Test")
]
HRESULT Test(
[in] double firstValue,
[in] double secondValue,
[in] BSTR comment,
[out, retval] double* ReturnVal);

// Other methods
};

[
uuid(your class GUID),
helpstring("ComTest")
]
coclass ComTest
{
[default] interface IComTest;
};
}

对于注册表项,您可以将 DllRegisterServer 和 DllUnregisterServer 函数添加到您的 COM 类中。在我的例子中,它们看起来像这样:

[ComRegisterFunction]
public static void DllRegisterServer(Type t)
{
// Additional CLSID entries
using (RegistryKey key = Registry.ClassesRoot.CreateSubKey(@"CLSID\{" + AssemblyInfo.ClassGuid + @"}"))
{
using (RegistryKey typeLib = key.CreateSubKey(@"TypeLib"))
{
typeLib.SetValue(string.Empty, "{" + AssemblyInfo.LibraryGuid + "}", RegistryValueKind.String);
}
}

// Interface entries
using (RegistryKey key = Registry.ClassesRoot.CreateSubKey(@"Interface\{" + AssemblyInfo.InterfaceGuid + @"}"))
{
using (RegistryKey typeLib = key.CreateSubKey(@"ProxyStubClsid32"))
{
typeLib.SetValue(string.Empty, "{00020424-0000-0000-C000-000000000046}", RegistryValueKind.String);
}

using (RegistryKey typeLib = key.CreateSubKey(@"TypeLib"))
{
typeLib.SetValue(string.Empty, "{" + AssemblyInfo.LibraryGuid + "}", RegistryValueKind.String);
Version version = typeof(AssemblyInfo).Assembly.GetName().Version;
typeLib.SetValue("Version", string.Format("{0}.{1}", version.Major, version.Minor), RegistryValueKind.String);
}
}

// TypeLib entries
using (RegistryKey key = Registry.ClassesRoot.CreateSubKey(@"TypeLib\{" + AssemblyInfo.LibraryGuid + @"}"))
{
Version version = typeof(AssemblyInfo).Assembly.GetName().Version;
using (RegistryKey keyVersion = key.CreateSubKey(string.Format("{0}.{1}", version.Major, version.Minor)))
{
// typelib key for 32 bit
keyVersion.SetValue(string.Empty, AssemblyInfo.Attribute<AssemblyDescriptionAttribute>().Description, RegistryValueKind.String);
using (RegistryKey keyWin32 = keyVersion.CreateSubKey(@"0\win32"))
{
keyWin32.SetValue(string.Empty, Path.ChangeExtension(Assembly.GetExecutingAssembly().Location, ".comhost.tlb"), RegistryValueKind.String);
}

// typelib key for 64 bit
keyVersion.SetValue(string.Empty, AssemblyInfo.Attribute<AssemblyDescriptionAttribute>().Description, RegistryValueKind.String);
using (RegistryKey keyWin64 = keyVersion.CreateSubKey(@"0\win64"))
{
keyWin64.SetValue(string.Empty, Path.ChangeExtension(Assembly.GetExecutingAssembly().Location, ".comhost.tlb"), RegistryValueKind.String);
}

using (RegistryKey keyFlags = keyVersion.CreateSubKey(@"FLAGS"))
{
keyFlags.SetValue(string.Empty, "0", RegistryValueKind.String);
}
}
}
}

[ComUnregisterFunction]
public static void DllUnregisterServer(Type t)
{
Registry.ClassesRoot.DeleteSubKeyTree(@"TypeLib\{" + AssemblyInfo.LibraryGuid + @"}", false);
Registry.ClassesRoot.DeleteSubKeyTree(@"Interface\{" + AssemblyInfo.InterfaceGuid + @"}", false);
Registry.ClassesRoot.DeleteSubKeyTree(@"CLSID\{" + AssemblyInfo.ClassGuid + @"}", false);
}

关于c# - access vba 中的 .net5 com 库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68316022/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com