欢迎光临散文网 会员登陆 & 注册

Altium Designer脚本系统数据提取

2023-03-25 23:35 作者:马尔代夫西安分夫  | 我要投稿

        Altium Designer脚本系统中自带的接口信息在安装目录下的ScriptingSystem.dll文件中,此文件的功能类似于VBA软件的类型库(OLE Type library)文件,里面包括当前版本脚本系统支持的接口、接口成员、常数、类型等信息,Altium Designer并没有介绍此文件如何打开,如何获取此文件中的全部接口信息。使用二进制文件查看工具,发现在脚本系统中的接口都是可以直接找到,接口名称信息是保存在此文件中的。

在脚本系统中接口名称显示为灰色

        此文件为二进制文件,先使用二进制文件查看工具打开ScriptingSystem.dll文件,搜索ISch_Port等字符串,在接口名称字符串的字符间是连续的,其他的接口名称也可使用相同的方式进行查找。

使用二进制文件查看工具可以看到接口名称字符信息

       如果要将此二进制文件中的全部接口名称提取出来,直接提取是不方便的,脚本系统对于读取和处理二进制文件支持性不太好,就需要将二进制信息转换成ASCII字符信息,再将得到的ASCII字符信息中非可见字符信息删除,即可得到全部的连续的单词字符串,这些字符串信息是包括接口、成员函数、属性、方法、常数等信息。将全部文本复制到脚本文件中,接口名称的颜色自动变成灰色,可将全部的接口提取出来。

      参考程序如下,由于ScriptingSystem.dll文件大小为16M,转换成ASCII字符串为32M,在Altium Designer脚本中处理32M文件时,直接将32M的数据作为一个字符串进行处理,处理的时间大于24h,非常耗时。在程序中将32M文件,分割成2000个文件,这样一个文件的大小只有17KB,这样处理起来就块多了,由于生成的文件较多会多次读写硬盘,将内存虚拟成一个磁盘,将程序文件和ScriptingSystem.dll文件复制进虚拟磁盘中,这样就提升程序的执行效率,可在50秒左右执行完毕。

      程序编写花费2周时间,程序优化花费2周,对于其他对于大文件的字符串文件处理也可参考此方法,将一个大文件分割成若干个小文件,可以极大的提高程序的执行效率。

Option Explicit

Call Main()

Sub Main()

Dim MilliSeconds_Start

Dim MilliSeconds_End

Dim Str_List_Temp

Dim Str_List_New

Dim Str_Temp

Dim Str_New

Dim Str_Folder_Path

Dim Str_File_Path

Dim Num_Length

Dim I

Dim Str_Temp1


Str_New = ""

Const Num_File_Count = 2000'拆分文件数量


MilliSeconds_Start = GetMilliSecondTime'


Str_Folder_Path = CreateObject("Scripting.FileSystemObject").GetParentFolderName(Client.CurrentView.OwnerDocument.FileName)

Str_Folder_Path = CreateObject("Scripting.FileSystemObject").GetParentFolderName(Str_Folder_Path)

Str_File_Path = Str_Folder_Path & "\新建文件夹\ScriptingSystem.dll"


If FileExists(Str_File_Path) Then

Set Str_List_Temp = TStringList.Create

Set Str_List_New = TStringList.Create


Str_Temp = ReadBinary(Str_File_Path)

Str_List_Temp.Text = Str_Temp

Str_List_Temp.SaveToFile(Str_Folder_Path & "\ScriptingSystem.txt")

Str_List_Temp.Text =""


Num_Length = Len(Str_Temp)/2


For I = 0 To (Num_File_Count-1)'对数据进行拆分成多个文件,确保每个文件均为双字节

If I<>(Num_File_Count-1) Then

Str_Temp1 = Mid(Str_Temp,Num_Length/Num_File_Count*2*I+1,Num_Length/Num_File_Count*2)

Str_List_Temp.Text = Str_Temp1

Str_List_Temp.SaveToFile(Str_Folder_Path & "\ScriptingSystem_" & CStr(I) & ".txt")

Else

Str_Temp1 = Mid(Str_Temp,Num_Length/Num_File_Count*2*I+1, Len(Str_Temp)-Num_Length/Num_File_Count*2*I+1)

Str_List_Temp.Text = Str_Temp1

Str_List_Temp.SaveToFile(Str_Folder_Path & "\ScriptingSystem_" & CStr(I) & ".txt")

End If

Next


For I = 0 To (Num_File_Count-1)'处理单个文件

Str_File_Path = Str_Folder_Path & "\ScriptingSystem_" & CStr(I) & ".txt"

If FileExists(Str_File_Path) Then

Call Deal_Single_File(Str_File_Path)

Else

MsgBox "单个文件不存在"

End If

Next


For I = 0 To (Num_File_Count-1)'将单个文件组合到一个文件中

Str_File_Path = Str_Folder_Path & "\ScriptingSystem_" & CStr(I) & ".txt"

If FileExists(Str_File_Path) Then

Str_List_Temp.LoadFromFile(Str_File_Path)

Str_List_New.Add(Str_List_Temp.Text)


Call Delete_File(Str_File_Path)'删除文件

Else

MsgBox "单个文件不存在"

End If

Next


Str_File_Path = Str_Folder_Path & "\ScriptingSystem.txt"

Call Delete_File(Str_File_Path)'删除文件


Str_List_New.Text = Str_List_Sorted(Str_List_New.Text)

Str_List_New.SaveToFile(Str_Folder_Path & "\ScriptingSystem_Text.txt")


MilliSeconds_End = GetMilliSecondTime


MsgBox "花费的时间为:" & formatnumber((MilliSeconds_End - MilliSeconds_Start)/1000,2) & "秒" '显示运行的秒数

Else

MsgBox "文件不存在"

End If

End Sub


Sub Delete_File(Str_File_Path)

If FileExists(Str_File_Path) Then'如果文件存在

DeleteFile(Str_File_Path)

End If

End Sub


'对单个文件进行处理

Sub Deal_Single_File(Str_File_Path)

Dim Str_List_Temp

Dim Str_List_New

Dim I

Dim Str_Temp

Dim Count

Dim Num_Length

Dim Num_Temp

Dim Str_New

Dim GUIMan

Set GUIMan = Client.GUIManager


If FileExists(Str_File_Path) Then

Set Str_List_Temp = TStringList.Create

Set Str_List_New = TStringList.Create


Str_List_Temp.LoadFromFile(Str_File_Path)

Str_Temp = Str_List_Temp.Text

Str_Temp = Replace(Str_Temp,vbCrLf,"")


Num_Length = Len(Str_Temp)/2

For I = 1 To Num_Length

Num_Temp = CLng("&H"& Mid(Str_Temp,I*2-1,2))

If (Num_Temp<=126 And Num_Temp=>32) Then

Str_New = Str_New & Chr(Num_Temp)

Else

Str_New = Str_New & vbCrLf

End If


' If (I Mod 1000 = 0) Then

' Call GUIMan.StatusBar_SetState(1,Str_File_Path & "        " & CStr(formatnumber((I+1)/Num_Length,4)*100) & "%")

' Call GUIMan.UpdateInterfaceState

' End If

Next


Call GUIMan.StatusBar_SetState(1,Str_File_Path)

Call GUIMan.UpdateInterfaceState


Str_New = Replace(Str_New," ",vbCrLf)

Str_New = Replace(Str_New,"!",vbCrLf)

Str_New = Replace(Str_New,"""",vbCrLf)

Str_New = Replace(Str_New,"#",vbCrLf)

Str_New = Replace(Str_New,"$",vbCrLf)

Str_New = Replace(Str_New,"%",vbCrLf)

Str_New = Replace(Str_New,"&",vbCrLf)

Str_New = Replace(Str_New,"'",vbCrLf)

Str_New = Replace(Str_New,"(",vbCrLf)

Str_New = Replace(Str_New,")",vbCrLf)

Str_New = Replace(Str_New,"*",vbCrLf)

Str_New = Replace(Str_New,"+",vbCrLf)

Str_New = Replace(Str_New,",",vbCrLf)

Str_New = Replace(Str_New,"-",vbCrLf)

Str_New = Replace(Str_New,".",vbCrLf)

Str_New = Replace(Str_New,"/",vbCrLf)


Str_New = Replace(Str_New,":",vbCrLf)

Str_New = Replace(Str_New,";",vbCrLf)

Str_New = Replace(Str_New,"<",vbCrLf)

Str_New = Replace(Str_New,"=",vbCrLf)

Str_New = Replace(Str_New,">",vbCrLf)

Str_New = Replace(Str_New,"?",vbCrLf)

Str_New = Replace(Str_New,"@",vbCrLf)


Str_New = Replace(Str_New,"[",vbCrLf)

Str_New = Replace(Str_New,"\",vbCrLf)

Str_New = Replace(Str_New,"]",vbCrLf)

Str_New = Replace(Str_New,"^",vbCrLf)

'Str_New = Replace(Str_New,"_",vbCrLf)'

Str_New = Replace(Str_New,"`",vbCrLf)


Str_New = Replace(Str_New,"{",vbCrLf)

Str_New = Replace(Str_New,"|",vbCrLf)

Str_New = Replace(Str_New,"}",vbCrLf)

Str_New = Replace(Str_New,"~",vbCrLf)


'Str_New = Replace(Str_New,"_",vbCrLf)'


Str_New = Replace(Str_New,"0",vbCrLf)

Str_New = Replace(Str_New,"1",vbCrLf)

Str_New = Replace(Str_New,"2",vbCrLf)

Str_New = Replace(Str_New,"3",vbCrLf)

Str_New = Replace(Str_New,"4",vbCrLf)

Str_New = Replace(Str_New,"5",vbCrLf)

Str_New = Replace(Str_New,"6",vbCrLf)

Str_New = Replace(Str_New,"7",vbCrLf)

Str_New = Replace(Str_New,"8",vbCrLf)

Str_New = Replace(Str_New,"9",vbCrLf)


Str_List_New.Text = Str_New

Str_List_New.Text = Str_List_Sorted(Str_List_New.Text)


'删除数字

Count = Str_List_New.Count

For I = 0 To Count-1

If IsNumeric(Str_List_New.Strings(I)) Then

Str_List_New.Strings(I) = ""

End If

Next


Str_List_New.SaveToFile(Str_File_Path)

Else

MsgBox "文件不存在"

End If

End Sub




Function ReadBinary(FileName)

Const adTypeBinary = 1

Dim stream, xmldom, node

Set xmldom = CreateObject("Microsoft.XMLDOM")

Set node = xmldom.CreateElement("binary")

node.DataType = "bin.hex"

Set stream = CreateObject("ADODB.Stream")

stream.Type = adTypeBinary

stream.Open

stream.LoadFromFile FileName

node.NodeTypedValue = stream.Read

stream.Close

Set stream = Nothing

ReadBinary = node.Text

Set node = Nothing

Set xmldom = Nothing

End Function


'对字符串进行排序

'如果第一个字符串为空字符串,删去第一行

Function Str_List_Sorted(Str_List_Temp)

Dim Str_List_Sort


Set Str_List_Sort = TStringList.Create

Str_List_Sort.Sorted = True

Str_List_Sort.Text = Str_List_Temp

Str_List_Sort.Sorted = False


If Str_List_Sort.Count>0 Then

If Str_List_Sort.Strings(0) = "" Then

Str_List_Sort.Delete(0)

End If

End If


Str_List_Sorted = Str_List_Sort.Text

End Function


Altium Designer脚本系统数据提取的评论 (共 条)

分享到微博请遵守国家法律