繁体   English   中英

如何读取.NET库中从VB6 IDE传递的命令行参数?

[英]How to read command line parameters passed from VB6 IDE in a .NET library?

我有app1.exe(用VB6构建),它需要一堆命令行参数。 它调用lib1.dll - 一个C#/ .net互操作库,需要访问EXE的命令行参数。 我使用Environment.CommandLine来读取命令行参数,这很有用。

当我在VB6 IDE中调试app1.exe时,我通常会进入项目属性,Make选项卡并手动设置命令行参数文本框。 但是,.NET库在调用时根本看不到命令​​行参数。 它只是看到整个事情在VB6.exe进程下运行。

这是有道理的(因为在调试时,它确实在VB6.exe下运行),但它使调试变得困难,因为.NET库永远不会访问实际的命令行参数。

我的问题:没有手动将命令行参数传递给.NET lib,在VB6 IDE中进行调试时,有没有其他方法可以看到它们?

这只是VB6 IDE设计方式的核心。 当您调试VB6代码然后您不运行进程时,您运行解释器。 它执行p代码,而不是机器代码。 这是一个意外的好功能,它允许调试你做的[ComVisible]的VB6代码和.NET代码。 这通常是不可能的,只有一个调试器附加到进程。 这也解释了为什么你的.NET调试器看到VB6.exe进程,这是同时拥有解释器和调试器的进程。

因此,当您使用Environment.CommandLine时,实际上是在读取传递给VB6 IDE的命令行。 通常这是空的。

正确的方法是明确的:不要试图通过后门获取信息。 只需在对象上拥有VB6代码集属性即可。

您可以使用命令行参数启动VB6 IDE,以便进行调试运行。 虽然看起来不方便(每次运行之前必须重新启动IDE)。 如果.NET库关心作为命令行一部分的程序名,它也应该不起作用。

替代方法可能是修改运行VB6.exe进程的命令行后再去。 由于命令行在创建时被复制到进程的地址空间中,因此进程可以对其进行修改。 理论上。 据我所知,坏消息是没有支持的方法来做到这一点。 实施不受支持的方式可能很棘手。

另一种替代方法是.NET库可以测试它是否在VB6.exe下运行(这应该在命令行中清楚),并从这种调试方案中的某些备用存储中获取数据。

编辑

下面的代码改变了GetCommandLine WinAPI函数返回的内存位置。 希望这个相同的函数由Environment.CommandLine在引擎盖下使用。

我还没有使用.NET库测试代码,但您可能希望尝试一下。 为了尝试这个方法:

使用任意但足够长的命令行参数字符串运行VB6 IDE(VB6.exe)。 安排在VB6 IDE中运行时执行下面的SetCmdLineWhenRunInVB6IDE过程。 它旨在用项目参数中设置的值替换IDE的命令行。 GetCmdLineSetCmdLine仅仅是帮助探索的助手。

Option Explicit

Private Declare Function GetCommandLine _
    Lib "kernel32" Alias "GetCommandLineW" () As Long
Private Declare Function lstrlen _
    Lib "kernel32" Alias "lstrlenW" (ByVal lpString As Long) As Long
Private Declare Sub CopyMemory _
    Lib "kernel32" Alias "RtlMoveMemory" (ByVal pDst As Any, ByVal pSrc As Any, ByVal ByteLen As Long)

Public Function GetCmdLine() As String
    Dim hStr As Long
    Dim hLen As Long

    hStr = GetCommandLine
    hLen = lstrlen(hStr)
    If hLen > 0 Then
        GetCmdLine = Space$(hLen)
        CopyMemory StrPtr(GetCmdLine), hStr, (hLen) * 2
    End If
End Function

Public Sub SetCmdLine(sNewCmdLine As String)
    Dim hStr As Long
    Dim hLen As Long
    Dim sBuf As String

    hStr = GetCommandLine
    hLen = lstrlen(hStr)
    If hLen > 0 Then
        Dim i As Long, hEndMark As Long

        sBuf = Space$(hLen)
        hEndMark = IIf(Len(sNewCmdLine) < Len(sBuf), Len(sNewCmdLine), Len(sBuf))

        For i = 1 To hEndMark
            Mid$(sBuf, i) = Mid$(sNewCmdLine, i)
        Next i

        CopyMemory ByVal hStr, StrPtr(sBuf), LenB(sBuf)
    End If
End Sub

Public Sub SetCmdLineFromVBACommand()
    Dim sVBACmdLine As String

    sVBACmdLine = """" & App.Path & "\" & App.EXEName & ".exe"" " & VBA.Command$
    SetCmdLine sVBACmdLine
End Sub

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM