在VB6中检测调试器是否已连接

6
我正在维护一款旧应用程序,它是用Visual Basic 6编写的。由于各种原因,我们有一部分代码仅在通过VB6 IDE(即调试器已连接)运行程序时需要运行。
在VB.NET中,您可以使用System.Diagnostics.Debugger.IsAttached()属性来实现此目的,但我在Google上找不到类似的VB6方法。
是否有一些简单的方法来获取这些信息?

请参阅问题VB6中的调试模式 - MarkJ
在IDE中运行与附加调试器不同,当然也可以这样做,但这是两回事。 - Bob77
6个回答

11

这是我们正在使用的内容,它没有任何副作用。

Public Property Get InIde() As Boolean
    Debug.Assert pvSetTrue(InIde)
End Property

Private Function pvSetTrue(bValue As Boolean) As Boolean
    bValue = True
    pvSetTrue = True
End Function

2
“没有副作用”是指,如果您打开了“全部错误中断”,这不会像@Jay Riggs的答案那样停止程序的执行(如果您在许多地方使用InIde,这可能非常烦人)。 - Kris Erickson
@Kris:还有就是如果使用“On Error Resume Next”+“Err.Number <> 0”的错误检查方式,不要重置“Err”对象。顺便说一句,我从来没有见过有人使用除了“Break On Unhandled Errors”之外的任何东西(除非对这些IDE设置一无所知)。 - wqw
1
@Kris:在你原来的评论两年后,我相信“在所有错误处中断”是任何稍微专业一点的项目中应该采取的方式。虽然重构了我所有的“代码”花费了我很多时间和精力,但它是值得的。感谢你的启示! - wqw

7

这是我一直在使用的一个函数:

Private Function RunningInIde() As Boolean
    On Error GoTo ErrHandler
    Debug.Print 1 / 0
ErrHandler:
    RunningInIde = (Err.Number <> 0)
End Function            ' RunningInIde

看起来很不错!但是有一个问题。如果我们在此函数之外还有其他On Error GoTo语句,我需要重置这些语句吗?还是错误处理程序在函数内部作用域限定? - bhamby
@galador 此函数中抛出的所有错误将在此函数内部处理,您无需重置。 - Jay Riggs
2
此函数会作为副作用重置 Err 对象。 - wqw
这里提到了更好的解决方案,因此不应将其标记为答案。 - tmighty

2

我之前写过类似的内容,但是现在找不到了,需要再次使用。所以我重新写了一遍,我认为这次写对了:

Public Function IsRunningInIde() As Boolean
    Static bFlag As Boolean
    bFlag = Not bFlag
    If bFlag Then Debug.Assert IsRunningInIde()
    IsRunningInIde = Not bFlag
    bFlag = False
End Function

没有引发任何错误。

没有重置Err。

只有一个函数。

第1行:“bFlag”的“Static”声明使得bFlag的值在多次调用“IsRunningInIde”时保持不变。我们希望这样做是因为我会在函数内部调用这个函数,而我不想在函数中添加用户不需要的输入参数。

第3行:“Debug.Assert”在不运行IDE时不会被调用。所以只有在IDE中才会递归调用“IsrunningInIde”。

第2行:如果不是递归调用,则bFlag的初始值为false,并且被设置为true。如果是递归调用(仅在运行IDE时发生),则它的初始值为true,并被设置回false。

第3行:只有在bFlag为true时,才调用“IsRunningInIde”,以避免递归调用该函数。

第4行:如果是递归调用,则始终返回True,这并不重要,但不会导致Assert失败。如果不是递归调用,则返回“Not bFlag”,其中bFlag现在为“False”,如果IsRunningInIde被递归调用,则bFlag为“True”。因此,Not bFlag返回“True”表示正在运行IDE。

第5行:清除bFlag,以便在下一次调用此函数时始终为“False”。

很难解释,最好在脑海中逐步执行两种情况。

如果您想要更简单易懂的代码,请不要使用它。

如果这段代码有问题,请告诉我,以便我可以修复它。


好的,我更新了并附上了解释。我意识到这个逻辑很令人困惑。 - Mafu Josh

2

这是我的函数,类似于Josh的函数,但更易读(请参见内部注释)。

我使用它已经很长时间了,以至于我忘记了从哪里借来的...

Public Function InDesign() As Boolean
' Returns TRUE if in VB6 IDE
Static CallCount    As Integer
Static Res          As Boolean

    CallCount = CallCount + 1
    Select Case CallCount
    Case 1  ' Called for the 1st time
        Debug.Assert InDesign()
    Case 2  ' Called for the 2nd time: that means Debug.Assert 
            ' has been executed, so we're in the IDE
        Res = True
    End Select
    ' When Debug.Assert has been called, the function returns True
    ' in order to prevent the code execution from breaking
    InDesign = Res

    ' Reset for further calls
    CallCount = 0

End Function

0
Public Function InIDE() As Boolean
On Error GoTo ErrHandler

    Debug.Print 1 \ 0 'If compiled, this line will not be present, so we immediately get into the next line without any speed loss

    InIDE = False

Exit Function
ErrHandler:
InIDE = True 'We'll get here if we're in the IDE because the IDE will try to output "Debug.Print 1 \ 0" (which of course raises an error).
End Function

0
Public Function InIDE(Optional ByRef bool As Boolean = True) As Boolean
    If bool Then Debug.Assert Not InIDE(InIDE) Else bool = True
End Function

使用方法:

If InIDE() Then
    '- Yes
End If

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接