引用的Dll
Aveva.ApplicationFramework.dll
Aveva.ApplicationFramework.Presentation
菜单展示效果
创建Attribute,用于反射来动态创建菜单,不用每次都去写command
Public Class MyAmFunctionAtt
Inherits Attribute
Private _menuName As String
Public Property MenuName() As String
Get
Return _menuName
End Get
Set(ByVal value As String)
_menuName = value
End Set
End Property
Private _functionName As String
Public Property FunctionName() As String
Get
Return _functionName
End Get
Set(ByVal value As String)
_functionName = value
End Set
End Property
Sub New(_menuNam As String, _functionName As String)
Me.MenuName = _menuNam
Me.FunctionName = _functionName
End Sub
End Class
自定义类,在内存中储存方法的信息,方便后面反射调用。
Public Class MyAMFunction
Private _att As MyAmFunctionAtt
Public Property Att() As MyAmFunctionAtt
Get
Return _att
End Get
Set(ByVal value As MyAmFunctionAtt)
_att = value
End Set
End Property
Private _mi As MethodInfo
Public Property Method() As MethodInfo
Get
Return _mi
End Get
Set(ByVal value As MethodInfo)
_mi = value
End Set
End Property
Sub New(mi As MethodInfo)
Me.Att = mi.GetCustomAttributes(True).First(Function(att)
Return att.GetType().FullName = GetType(MyAmFunctionAtt).FullName
End Function)
Me.Method = mi
End Sub
End Class
插件启动加载的类
Public Class MianClsss
Implements IAddin
Public CurAss As Assembly = Assembly.GetExecutingAssembly()
Public ReadOnly Property Description As String Implements IAddin.Description
Get
Return Me.GetType().FullName
End Get
End Property
Public ReadOnly Property Name As String Implements IAddin.Name
Get
Return Me.GetType().FullName
End Get
End Property
Public Sub Start(serviceManager As ServiceManager) Implements IAddin.Start
Dim wm As WindowManager = serviceManager.GetService(GetType(WindowManager))
'Dim cmd As New MyCommand(wm)
'Dim cmdManager As CommandManager = serviceManager.GetService(GetType(CommandManager))
'cmdManager.Commands.Add(cmd)
Dim cbm As CommandBarManager = serviceManager.GetService(GetType(CommandBarManager))
cbm.AllowCustomization = True
cbm.BeginUpdate()
Dim cbar = cbm.CommandBars.AddCommandBar(System.IO.Path.GetFileNameWithoutExtension(CurAss.Location))
cbar.DockedPosition = DockedPosition.Top
cbar.AllowHiding = False
cbar.AllowFloating = True
Dim assemblyDate = System.IO.File.GetLastWriteTime(System.Reflection.Assembly.GetExecutingAssembly().Location).ToString("yyyy年MM月dd日-HH点mm分")
cbar.Caption = cbar.Key + $",软件版本({assemblyDate})"
'读取全部的自定义命令
Dim cmds = GetAllCommand()
For Each item As KeyValuePair(Of String, List(Of MyAMFunction)) In cmds
Dim curMenu As MenuTool = cbm.RootTools.AddMenuTool(item.Key, item.Key, Nothing)
Dim it1 As MenuTool = cbar.Tools.AddTool(curMenu.Key)
Dim curMenuItems = item.Value.OrderBy(Function(c)
Return c.Att.FunctionName
End Function).ToList()
For Each myCmd As MyAMFunction In curMenuItems
Dim cmdBtn As ButtonTool = cbm.RootTools.AddButtonTool(myCmd.Att.FunctionName, myCmd.Att.FunctionName, Nothing)
cmdBtn.Tooltip = $"{myCmd.Att.MenuName}.{myCmd.Att.FunctionName}"
AddHandler cmdBtn.ToolClick, Sub()
Try
wm.StatusBar.Text = $"正在执行命令{ myCmd.Att.FunctionName}..."
If myCmd.Method.DeclaringType Is Nothing Then Return
If myCmd.Method.IsStatic Then
myCmd.Method.Invoke(Nothing, {wm})
Else
myCmd.Method.Invoke(Activator.CreateInstance(myCmd.Method.DeclaringType), {wm})
End If
wm.StatusBar.Text = $"执行命令{ myCmd.Att.FunctionName}完成...."
Catch ex As Exception
MsgBox(ex.StackTrace)
End Try
End Sub
it1.Tools.AddTool(cmdBtn.Key)
Next
Next
cbm.EndUpdate(True)
cbm.SaveLayout()
End Sub
Public Sub [Stop]() Implements IAddin.Stop
End Sub
Public Function GetAllCommand() As Dictionary(Of String, List(Of MyAMFunction))
Dim dicts As New Dictionary(Of String, List(Of MyAMFunction))
Dim allClass As List(Of Type) = Me.CurAss.GetTypes().Where(Function(c)
Return c.IsClass And c.IsPublic
End Function).ToList()
Dim mis As New List(Of MyAMFunction)
For Each item As Type In allClass
Dim curClsMis = item.GetMethods().Where(Function(m)
Return m.GetCustomAttributes(GetType(MyAmFunctionAtt), True).Any()
End Function).ToList()
If curClsMis.Count > 0 Then
For Each mi As MethodInfo In curClsMis
mis.Add(New MyAMFunction(mi))
Next
End If
Next
If mis.Count = 0 Then Return dicts
For Each item As MyAMFunction In mis
Dim temp As New List(Of MyAMFunction)
If dicts.ContainsKey(item.Att.MenuName) Then temp = dicts(item.Att.MenuName)
temp.Add(item)
dicts(item.Att.MenuName) = temp
Next
Return dicts
End Function
End Class
创建测试函数
Public Class MyAmCommand
<MyAmFunctionAtt(NameOf(MyAmCommand), NameOf(测试功能))>
Sub 测试功能(wm As WindowManager)
MsgBox(NameOf(测试功能) + "ok")
End Sub
End Class
修改文件,让插件随软件启动
在空白位置右键选择刚才我们开发的插件,即可达到开始的效果。