由于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