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

 

posted @ 2022-05-01 15:37  南胜NanSheng  阅读(563)  评论(0编辑  收藏  举报