Vb6 VB中自动化错误的处理
编辑#1 我正在开发一个VB6 EXE应用程序,用于向Adobe Illustrator输出一些特殊图形 下面的示例代码将Adobe Illustrator中的给定图形绘制为虚线多段线Vb6 VB中自动化错误的处理,vb6,automation,ui-automation,Vb6,Automation,Ui Automation,编辑#1 我正在开发一个VB6 EXE应用程序,用于向Adobe Illustrator输出一些特殊图形 下面的示例代码将Adobe Illustrator中的给定图形绘制为虚线多段线 ' Proconditions: ' ai_Doc As Illustrator.Document is an open AI document ' Point_Array represented as "array of array (0 to 1)" contains point coordinates '
' Proconditions:
' ai_Doc As Illustrator.Document is an open AI document
' Point_Array represented as "array of array (0 to 1)" contains point coordinates
'
Private Sub Draw_AI_Path0(ByRef Point_Array As Variant)
Dim New_Path As Illustrator.PathItem
Set New_Path = ai_Doc.PathItems.Add
New_Path.SetEntirePath Point_Array
New_Path.Stroked = True
New_Path.StrokeDashes = Array(2, 1)
End Sub
但是,此简单代码可能会引发各种运行时自动化错误,这些错误由以下原因引起:
- 客户端代码不正确(例如,将数组以外的值分配给
)New_Path.StrokeDashes
- 客户端数据不正确(例如,将太大的
传递到点数组
)新路径。SetEntirePath
- 某些服务器功能不可用(例如,当AI的当前层被锁定时)
- 意外的服务器行为
点数组
传递到新路径.SetEntirePath
的示例(Windows XP SP3,Adobe Illustrator CS3):
- 对于32767及以上的数组大小,错误为-2147024809(&H80070057)“非法参数”
- 对于32000到32766的数组大小,错误为-2147212801(&H800421FF)“无法在路径中插入更多段。最大值为8191”
Private Sub Draw_AI_Path1(ByRef Point_Array As Variant)
Dim New_Path As Illustrator.PathItem
On Error GoTo PROCESS_ERROR
Set New_Path = ai_Doc.PathItems.Add
New_Path.SetEntirePath Point_Array
New_Path.Stroked = True
New_Path.StrokeDashes = Array(2, 1)
Exit Sub
PROCESS_ERROR:
MsgBox "Failed somewhere in Draw_AI_Path1 (" & Format(Err.Number) & ")" _
& vbCrLf & Err.Description
End Sub
如您所见,可以轻松访问错误号和错误描述。但是,我还需要知道是什么调用导致了错误。这对于包含许多自动化接口调用的大型复杂过程非常有用。因此,我需要知道:
Private Sub Draw_AI_Path2(ByRef Point_Array As Variant)
Dim New_Path As Illustrator.PathItem
Dim Proc As String
On Error GoTo PROCESS_ERROR
Proc = "PathItems.Add"
Set New_Path = ai_Doc.PathItems.Add
Proc = "SetEntirePath"
New_Path.SetEntirePath Point_Array
Proc = "Stroked"
New_Path.Stroked = True
Proc = "StrokeDashes"
New_Path.StrokeDashes = Array(2, 1)
Exit Sub
PROCESS_ERROR:
MsgBox "Failed " & Proc & " in Draw_AI_Path2 (" & Format(Err.Number) & ")" _
& vbCrLf & Err.Description
End Sub
弱点:
- 代码变大,可读性变差
- 由于复制粘贴,可以指定不正确的原因
- 两个目标都得到了满足
- 最小处理速度影响
Private Function Invoke( _
ByRef Obj As Object, ByVal Proc As String, ByVal CallType As VbCallType, _
ByVal Needs_Object_Return As Boolean, Optional ByRef Arg As Variant) _
As Variant
On Error GoTo PROCESS_ERROR
If (Needs_Object_Return) Then
If (Not IsMissing(Arg)) Then
Set Invoke = CallByName(Obj, Proc, CallType, Arg)
Else
Set Invoke = CallByName(Obj, Proc, CallType)
End If
Else
If (Not IsMissing(Arg)) Then
Invoke = CallByName(Obj, Proc, CallType, Arg)
Else
Invoke = CallByName(Obj, Proc, CallType)
End If
End If
Exit Function
PROCESS_ERROR:
MsgBox "Failed " & Proc & " in Draw_AI_Path3 (" & Format(Err.Number) & ")" _
& vbCrLf & Err.Description
If (Needs_Object_Return) Then
Set Invoke = Nothing
Else
Invoke = Empty
End If
End Function
Private Sub Draw_AI_Path3(ByRef Point_Array As Variant)
Dim Path_Items As Illustrator.PathItems
Dim New_Path As Illustrator.PathItem
Set Path_Items = Invoke(ai_Doc, "PathItems", VbGet, True)
Set New_Path = Invoke(Path_Items, "Add", VbMethod, True)
Call Invoke(New_Path, "SetEntirePath", VbMethod, False, Point_Array)
Call Invoke(New_Path, "Stroked", VbSet, False, True)
Call Invoke(New_Path, "StrokeDashes", VbSet, False, Array(2, 1))
End Sub
弱点:
- 由于自动化错误440总是由
CallByName
- 需要拆分表达式,如
PathItems。添加
- 某些类型的自动化接口调用的处理速度显著下降(高达3倍)
- 简洁易读的代码,没有重复的错误语句
Serge将在VB6调试器中运行它。如果编译时未进行优化(优化后您将无法识别代码),您还可以从WinDbg或WER获取堆栈跟踪(使用GFlags进行设置)。HKEY\U LOCAL\U MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug是存储设置的位置 也可以在调试器中启动 windbg或ntsd(ntsd是一个控制台程序,可能已安装)。这两个都来自Windows调试工具 下载并安装Windows调试工具 安装Windows SDK,但只需选择调试工具 在C中创建名为Symbols的文件夹:\ 启动Windbg。文件菜单-符号文件路径并输入
srv*C:\symbols*http://msdl.microsoft.com/download/symbols
然后
您可以按F12停止它,kb将显示调用堆栈(g继续程序)。如果出现错误,它也会停止并显示错误
键入lm以列出加载的模块,x*!*列出符号和bp symbolname以设置断点
da显示在该地址找到的ascii数据
dda显示指针的值
kv 10显示最后10个堆栈帧
lm列表模块
x*!*列出所有模块中的所有功能
p步
!!sysinfo机器ID
如果在VB6中编程,则此环境变量link=/pdb:none将符号存储在dll中,而不是单独的文件中。确保编译程序时没有优化,并勾选“创建符号调试信息”框。两者都位于项目属性的“编译”选项卡上
此外,CoClassSyms(microsoft.com/msj/0399/hood/hood0399.aspx)还可以从类型库中生成符号。想想原因,您可能想知道从何处引发错误。一个原因是出于简单的调试目的。另一个更重要的原因是,您想做一些特定的事情来处理发生的特定错误 调试的正确解决方案实际上取决于您试图解决的问题。简单的
Debug.Print
语句可能是您所需要的全部,如果这是一个临时的bug查找,并且您正在交互工作。如果您只需要对一些例程进行粒度错误识别,并且您可以容忍弹出消息框,那么您的解决方案#1就可以了。然而,正如你所说,它有点乏味,而且容易出错,所以把它变成样板文件或某种“标准实践”是个坏主意
但这里真正的危险信号是您的声明,即您有“包含许多对自动化接口的调用的大型复杂过程”,另外还需要以细粒度的方式处理或至少跟踪错误。解决这个问题的办法就是把你庞大而复杂的过程分解成一组简单的过程
比如说
windbg -o -g -G c:\windows\system32\cmd.exe /k batfile.bat
Sub SetEntirePath(New_Path As Illustrator.PathItem, ByRef Point_Array As Variant)
On Error Goto EH
New_Path.SetEntirePath Point_Array
Exit Sub
EH:
'whatever you need to deal with "set entire path" errors
End Sub
Private Sub Draw_AI_Path4(ByRef Point_Array As Variant)
...
path_wrapper.SetEntirePath Point_Array
path_wrapper.Stroked = True
path_wrapper.StrokeDashes = Array(2, 1)
...
End Sub