AVEVE MARINE 二次开发之插件管理器
由于AVEVA 的产品部署插件比较麻烦,随机想到开发一个插件管理器
选择模块用来管理该模块的插件和自定义菜单
根据插件的部署原理
1.从注册表读取PDMS产品的安装路径
我用的是AM所以我写死了注册表路径
插件一般2个文件一个是dll文件,一个是菜单文件,uic是复制的模板然后进入AM修改的,这样便于部署,后期熟悉了可以根据反射写uic文件
Imports System.IO Imports Microsoft.Win32 Public Class Form1 Public AMinfor As AvevaMarinInfor Public AmAddin As PDMSAddin Public Const AmregPath As String = "SOFTWARE\WOW6432Node\AVEVA Solutions Ltd\Marine\12.14" Public ModuleNameAddin As New List(Of String) Public ModuleNameCustomization As New List(Of String) Public Const 模块自定义菜单后缀 As String = "Customization.xml" Public Const 模块插件后缀 As String = "Addins.xml" Public CurModuleName As String Public InstalledCurModuleAddins As List(Of String) Public InstalledCurModuleUics As List(Of PDMSAddinUic) Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Dim amReg = My.Computer.Registry.LocalMachine.OpenSubKey(AmregPath) If amReg IsNot Nothing Then Me.AMinfor = New AvevaMarinInfor(amReg) Dim di As New DirectoryInfo(Me.AMinfor.InstallPath) Me.ModuleNameAddin.AddRange(di.GetFiles("*Addins.xml").Select(Of String)(Function(c) c.Name.Replace(模块插件后缀, vbNullString))) Me.ComboBox1.Items.AddRange(Me.ModuleNameAddin.ToArray()) End If End Sub ''' <summary> ''' 选择插件 ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> Private Sub Button1_Click(sender As Object, e As EventArgs) Handles btnOpen.Click Dim ofd As New OpenFileDialog() With {.InitialDirectory = Application.StartupPath, .Filter = "C# or VbNet AM dll file (*.dll)|*.dll", .FilterIndex = 2, .RestoreDirectory = True, .Multiselect = False } If ofd.ShowDialog() = DialogResult.OK Then Me.AmAddin = New PDMSAddin(New IO.FileInfo(ofd.FileName)) Me.Text += "(" & Me.AmAddin.dllName & ")" Me.TextBox1.Text = ofd.FileName If Me.InstalledCurModuleAddins.Any(Function(c) Path.GetFileName(c) = Path.GetFileNameWithoutExtension(Me.AmAddin.dllName)) Then '检查dll的配置 'MessageBox.Show($"插件{Path.GetFileNameWithoutExtension(Me.AmAddin.dllName)}已经存在请确认继续安装!") Dim curAddin = Me.InstalledCurModuleAddins.FirstOrDefault(Function(c) c.EndsWith(Path.GetFileNameWithoutExtension(Me.AmAddin.dllName))) Dim index = Me.CheckedListBox1.Items().IndexOf(curAddin) Me.CheckedListBox1.SetItemChecked(index, True) '检查uic的配置 If Me.InstalledCurModuleUics.Any(Function(c) Path.GetFileName(c.Dir) = Me.AmAddin.UicName) Then Dim curAddinUic = Me.InstalledCurModuleUics.FirstOrDefault(Function(c) Path.GetFileName(c.Dir) = Me.AmAddin.UicName) Dim index1 = Me.CheckedListBox2.Items().IndexOf(curAddinUic.Dir) Me.CheckedListBox2.SetItemChecked(index1, True) End If End If End If End Sub ''' <summary> '''删除插件 ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> Private Sub BtnDeleteAddin_Click(sender As Object, e As EventArgs) Handles BtnDelete.Click If Me.CheckedListBox1.SelectedItems.Count > 0 Then Dim hulldesignaddinxml = Path.Combine(Me.AMinfor.InstallPath, CurModuleName & 模块插件后缀) 'Dim sb As New StringBuilder() Using fs As New FileStream(hulldesignaddinxml, FileMode.Open, FileAccess.ReadWrite) Dim xmldoc As New Xml.XmlDocument() xmldoc.Load(fs) For Each item As Xml.XmlElement In xmldoc.LastChild.ChildNodes If Me.CheckedListBox1.SelectedItems.Contains(item.FirstChild.Value) Then Me.InstalledCurModuleAddins.Remove(item.FirstChild.Value) Me.CheckedListBox1.Items.Remove(item.FirstChild.Value) MsgBox($"删除插件 {item.FirstChild.Value}成功!", MsgBoxStyle.Information + MsgBoxStyle.OkOnly) item.ParentNode.RemoveChild(item) End If Next fs.Close() 'xmldoc.PreserveWhitespace = True xmldoc.Save(hulldesignaddinxml) End Using End If If Me.CheckedListBox2.SelectedItems.Count > 0 Then Dim hulldesignuic = Path.Combine(Me.AMinfor.InstallPath, CurModuleName & 模块自定义菜单后缀) 'Dim sb As New StringBuilder() Using fs As New FileStream(hulldesignuic, FileMode.Open, FileAccess.ReadWrite) Dim xmldoc As New Xml.XmlDocument() xmldoc.Load(fs) For Each item As Xml.XmlElement In xmldoc.LastChild.FirstChild.ChildNodes If Me.CheckedListBox2.SelectedItems.Contains(item.GetAttributeNode("Path").Value) Then Dim curUic = Me.InstalledCurModuleUics.FirstOrDefault(Function(c) c.Dir = item.GetAttributeNode("Path").Value) Me.InstalledCurModuleUics.Remove(curUic) Me.CheckedListBox2.Items.Remove(curUic.Dir) item.ParentNode.RemoveChild(item) MsgBox($"删除菜单组 {curUic.Dir}成功!", MsgBoxStyle.Information + MsgBoxStyle.OkOnly) End If Next fs.Close() 'xmldoc.PreserveWhitespace = True xmldoc.Save(hulldesignuic) End Using 'Me.CheckedListBox2.Items.AddRange(Me.InstalledHullDesignAddins.ToArray()) End If End Sub ''' <summary> ''' 安装插件 ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> Private Sub BtnInstallAddin_Click(sender As Object, e As EventArgs) Handles btnInstall.Click '插入插件的dll的配置 Dim hulldesignaddinxml = Path.Combine(Me.AMinfor.InstallPath, CurModuleName & 模块插件后缀) 'Dim sb As New StringBuilder() Dim addinName = Me.TextBox1.Text.Replace(".dll", "") Using fs As New FileStream(hulldesignaddinxml, FileMode.Open, FileAccess.ReadWrite) Dim xmldocAddin As New Xml.XmlDocument() xmldocAddin.Load(fs) '插入节点 If Me.InstalledCurModuleAddins.Contains(addinName) Then For Each item As Xml.XmlElement In xmldocAddin.LastChild.ChildNodes If item.FirstChild.Value = addinName Then Dim curNode As Xml.XmlElement = item curNode.FirstChild.Value = addinName End If Next Else Dim curNode As Xml.XmlNode = xmldocAddin.CreateElement("string") Dim curNode1 As Xml.XmlNode = xmldocAddin.CreateTextNode(addinName) curNode.AppendChild(curNode1) xmldocAddin.LastChild.AppendChild(curNode) End If fs.Close() 'xmldoc.PreserveWhitespace = True xmldocAddin.Save(hulldesignaddinxml) Me.InstalledCurModuleAddins.Add(addinName) Me.CheckedListBox1.Items.Add(addinName) Me.CheckedListBox1.SetItemChecked(Me.CheckedListBox1.Items.Count - 1, True) MsgBox($"安装插件 {addinName}成功!", MsgBoxStyle.Information + MsgBoxStyle.OkOnly) End Using If Me.AmAddin.UicName <> String.Empty Then Dim xmldocUic As New Xml.XmlDocument() Dim hulldesignuic = Path.Combine(Me.AMinfor.InstallPath, CurModuleName & 模块自定义菜单后缀) Dim addinUicName = Path.ChangeExtension(Me.TextBox1.Text, ".uic") Using fs As New FileStream(hulldesignuic, FileMode.Open, FileAccess.ReadWrite) xmldocUic.Load(fs) '插入节点 If Me.InstalledCurModuleUics.Any(Function(c) c.Dir = addinUicName) Then For Each item As Xml.XmlNode In xmldocUic.LastChild.FirstChild.ChildNodes If item.Attributes.GetNamedItem("Path").Value = addinUicName Then Dim curEle As Xml.XmlElement = item curEle.SetAttribute("Name", Path.GetFileNameWithoutExtension(addinUicName)) curEle.SetAttribute("Path", addinUicName) Exit For End If Next Else Dim curElement As Xml.XmlElement = xmldocUic.CreateElement("CustomizationFile") curElement.SetAttribute("Name", Path.GetFileNameWithoutExtension(addinUicName)) curElement.SetAttribute("Path", addinUicName) xmldocUic.LastChild.FirstChild.AppendChild(curElement) End If fs.Close() 'xmldoc.PreserveWhitespace = True xmldocUic.Save(hulldesignuic) Me.InstalledCurModuleUics.Add(New PDMSAddinUic() With {.Dir = addinUicName, .UicName = Path.GetFileNameWithoutExtension(addinUicName)}) Me.CheckedListBox2.Items.Add(addinUicName) Me.CheckedListBox2.SetItemChecked(Me.CheckedListBox2.Items.Count - 1, True) MsgBox($"安装插件菜单 {addinUicName}成功!", MsgBoxStyle.Information + MsgBoxStyle.OkOnly) End Using End If End Sub Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged If Me.ComboBox1.SelectedIndex <> -1 Then Me.CheckedListBox1.Items.Clear() Me.CheckedListBox2.Items.Clear() Me.CurModuleName = Me.ComboBox1.Text Me.InstalledCurModuleAddins = New List(Of String)() Me.InstalledCurModuleUics = New List(Of PDMSAddinUic)() Me.Text = Me.CurModuleName & " 插件管理器" Me.btnInstall.Text = "给 " & Me.CurModuleName & " 模块安装插件" Me.BtnDelete.Text = "从 " & Me.CurModuleName & " 模块卸载插件" Dim hulldesignaddinxml = Path.Combine(Me.AMinfor.InstallPath, Me.CurModuleName & 模块插件后缀) 'Dim sb As New StringBuilder() Using fs As New FileStream(hulldesignaddinxml, FileMode.Open, FileAccess.Read) Dim xmldoc As New Xml.XmlDocument() xmldoc.Load(fs) For Each item As Xml.XmlElement In xmldoc.LastChild.ChildNodes Me.InstalledCurModuleAddins.Add(item.FirstChild.Value) Next fs.Close() End Using Me.CheckedListBox1.Items.AddRange(Me.InstalledCurModuleAddins.ToArray()) Dim hulldesignuic = Path.Combine(Me.AMinfor.InstallPath, Me.CurModuleName & 模块自定义菜单后缀) Using fs As New FileStream(hulldesignuic, FileMode.Open, FileAccess.Read) Dim xmldoc As New Xml.XmlDocument() xmldoc.Load(fs) For Each item As Xml.XmlElement In xmldoc.LastChild.FirstChild.ChildNodes Dim uic As New PDMSAddinUic With {.UicName = item.GetAttributeNode("Name").Value, .Dir = item.GetAttributeNode("Path").Value} Me.InstalledCurModuleUics.Add(uic) Next fs.Close() End Using Me.CheckedListBox2.Items.AddRange(Me.InstalledCurModuleUics.Select(Function(c As PDMSAddinUic) c.Dir).ToArray()) End If End Sub End Class Public Class AvevaMarinInfor Public Ver As String Public ProductName As String Public ProductVersion As String Public InstallPath As String Public Sub New(regKey As RegistryKey) If regKey Is Nothing Then Throw New ArgumentNullException(NameOf(regKey)) End If Me.Ver = regKey.ToString() Me.ProductVersion = regKey.GetValue("ProductVersion") Me.InstallPath = regKey.GetValue("Path") Me.ProductName = regKey.GetValue("ProductName") End Sub End Class Public Class PDMSAddin Public dllName As String Public UicName As String Public Dir As String Public Sub New(fi As System.IO.FileInfo) If fi Is Nothing Then Throw New ArgumentNullException(NameOf(fi)) End If Dim curDir = fi.Directory Me.Dir = curDir.FullName Me.dllName = fi.Name Dim fls = curDir.GetFiles(IO.Path.ChangeExtension(fi.Name, ".uic")) If fls.Count() = 1 Then Me.UicName = fls.FirstOrDefault().Name End If End Sub End Class Public Structure PDMSAddinUic Public UicName As String Public Dir As String End Structure
标签:
PDMS
, AVEVA MRINE
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具