VB6 COM +调用.Net COM DLL

时间:2018-04-03 21:59:35

标签: .net vb.net vb6 com-interop com+

祝20岁生日快乐VB6! 是的,即使支持在13年前用完,VB6仍然存在。 请随意饶恕我,但请提供您对此问题的任何见解。

我在Citrix服务器场上安装了VB6 EXE。 数据是通过COM +从托管VB6 COM + DLL的另一台服务器获得的。 COM +包将导出并安装在每台Citrix计算机上。

EXE和COM + DLL都写入旧的记录器。我正试图摆脱旧的记录器,转而使用Log4Net版本。

我编写了一个.NET COM DLL,其唯一目的是写入日志。

使用.NET DLL的EXE日志(只要我将log.config放在与EXE相同的文件夹中),但COM +组件没有。我已经尝试将log.config复制到各种文件夹中,希望这可能是问题所在。我还写了另一个EXE来测试.NET DLL,它可以工作。

只是为了踢,我尝试在COM + DLL上使用后期绑定,但这也没有帮助。我在Citrix计算机和COM服务器上注册了.Net COM DLL。

我还试图从vb6写入事件日志 - 都失败了。

我确信我的COM + DLL正在实现,因为没有日志被写入旧记录器。此外,当从我的本地机器运行时,我从我的EXE和COM + DLL获取日志。

这是一些代码......

这是我的VB.NET COM记录代码

Imports System.IO
Imports log4net

<Assembly: Config.XmlConfigurator(ConfigFile:="Log.config", Watch:=True)>

<ComClass(log.ClassId, log.InterfaceId, log.EventsId)>
Public Class log

    Public logger As log4net.ILog = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType)

#Region "COM GUIDs"
    Public Const ClassId As String = "6fae24c7-f86b-4fab-8b49-1d441de5bd18"
    Public Const InterfaceId As String = "223a30c4-ec1e-45a6-82d3-d23cd4c933f9"
    Public Const EventsId As String = "2087d93e-dd38-4cd1-b757-44dee322a8e3"
    Public Property TraceExtension As Object
#End Region

    Public Sub New()
        MyBase.New()

        WriteEvent("New Start")

        If Not log4net.LogManager.GetRepository().Configured Then
            Dim configFileDirectory = (New DirectoryInfo(TraceExtension.AssemblyDirectory)).Parent
            Dim configFile = New FileInfo(configFileDirectory.FullName + "\log.config")

            If configFile.Exists Then
                WriteEvent("New Config Exists")
                log4net.Config.XmlConfigurator.Configure(configFile)
            Else
                WriteEvent(String.Format("The configuration file {0} does not exist", configFile))
                Throw New FileLoadException(String.Format("The configuration file {0} does not exist", configFile))
            End If
        End If

        WriteEvent("New End")

    End Sub

    Private Sub WriteEvent(msg As String, Optional id As Integer = 11)
        Using eventLog As New EventLog("Application")
            eventLog.Source = "CSS"
            eventLog.WriteEntry(msg, EventLogEntryType.Error, id)
        End Using
    End Sub

    Public Sub Debug(msg As String)
        logger.Debug(msg)
    End Sub
    Public Sub Info(msg As String)
        logger.Info(msg)
    End Sub
    Public Sub Warn(msg As String)
        logger.Warn(msg)
    End Sub
    Public Sub Err(msg As String)
        logger.Error(msg)
    End Sub
    Public Sub Fatal(msg As String)
        logger.Fatal(msg)
    End Sub
End Class

,这是从EXE和COM + DLL调用的VB6代码。

Public Sub AppLog(ByVal LogType As Integer, ByVal Data As String)
10  On Error Resume Next
20  Dim klog As New KerryLog.Log
30  Data = "EXE > " + Data ' the COM+ DLL has a Prefix of COM instead of EXE

    Select Case LogType
            Case LogTypeNone: klog.Info Data
            Case LogTypeAppStart: klog.Info Data
            Case LogTypeAppEnd: klog.Info Data
            Case LogTypeInfo: klog.Info Data
            Case LogTypeVerbose: klog.Debug Data
            Case LogTypeWarning: klog.Warn Data
            Case LogTypeHandledException: klog.Err Data
            Case LogTypeUnhandledException: klog.Fatal Data
            Case LogTypeAutomated: klog.Info Data
            Case LogTypeUsage: klog.Debug Data
    End Select

40  Set klog = Nothing

以下是我用来写入事件日志的方法1:

App.StartLogging "", vbLogToNT
App.LogEvent "this is the error message", vbLogEventTypeError

以及写入事件日志的方法2

Private Declare Function ReportEvent _
    Lib "advapi32.dll" Alias "ReportEventA" ( _
    ByVal hEventLog As Long, _
    ByVal wType As Integer, _
    ByVal wCategory As Integer, _
    ByVal dwEventID As Long, _
    ByVal lpUserSid As Long, _
    ByVal wNumStrings As Integer, _
    ByVal dwDataSize As Long, _
    plpStrings As String, _
    lpRawData As Long) As Long

Private Declare Function RegisterEventSource _
    Lib "advapi32.dll" Alias "RegisterEventSourceA" ( _
    ByVal lpUNCServerName As String, _
    ByVal lpSourceName As String) As Long

Public Sub LogThis(nErrNo As Long, sLogMsg As String, EventType As LogEventTypeConstants)
    Dim hEvent As Log

    hEvent = RegisterEventSource("", "CSS")
    Call ReportEvent(hEvent, EventType, 0, nErrNo, 0, 1, Len(sLogMsg), sLogMsg, 0)
End Sub

事件日志是一个旁注 - 我正在尝试写一些东西,所以我可以调试。我想我的下一步将是尝试写入文本文件。

也许这是一个许可问题? Citrix和COM +服务器都是Win Server 2008 R2标准SP1 / 64位

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

COM+ 组件会将其当前工作文件夹放在 C:\Windows\System32 中,因此它很可能会因路径访问错误或 COM+ 中的文件写入错误而失败,直到您在配置中为 COM+ 日志记录设置绝对路径。

我的方法是使用进程外 COM+ 服务器进行日志记录,我通过 ActiveX“中间件”代理访问它以独立于日志记录机制,并且不受现有日志记录解决方案的限制。对于进程外的COM+激活,我写了一个小模块直接调用CoCreateInstance,实现了和VB6类似的方法,New只使用进程内COM+激活,没有办法选择进程外激活。< /p>

在这种架构下,寻找适当的日志记录机制和错误处理的所有职责都从目标 VB6 项目转移到 VB6 ActiveX,它使用与现有 COM+ 服务器的连接(进程外,还记得吗?)或回退到默认值ActiveX 中的记录器实现,因此任何代码似乎都不会编写任何日志记录错误处理代码,也不会编写除“New ILoggerFactory.CreateLogger”之外的其他内容。因为 ActiveX 组件本身具有用于日志记录支持的 COM+ 接口的实现。

在我的 COM+ 服务器(.NET 5 应用程序)启动并运行之前,我可以使用 NLog 格式获得额外的高级结构化日志记录,包括扩展(DB 等)。同样,您可以使用自己的带有配置的 log4net .NET 可执行文件将其用作 COM+ 日志记录接口的默认实现,因此您无需向 COM+ 提供任何配置信息,只要它对系统,在最坏的情况下,您可以将默认记录器实现作为 EventLog 记录器嵌入到您的 ActiveX 库中,因此它永远不会因文件/访问异常而失败,从而使主 COM+ 服务器记录器远离安全的可写位置