部署 MEF 部件

发布于 2024-10-13 09:03:23 字数 391 浏览 5 评论 0原文

我构建了一个可执行 shell,它使用 MEF 加载程序集(MEF 部件)并根据加载的功能进行显示/操作。

我现在想要将此应用程序部署为 ClickOnce 安装。有没有人有这方面的策略,目前我已经看到了两种策略。

  1. 构建和安装部件并将其作为重新分发组件添加到 shell 应用程序 - 这意味着这两个安装基本上焊接在一起,这意味着 MEF 基本上没有意义

  2. 在 shell 中构建一个下载器功能,这再次意味着每个 MEF 部分都需要在我们开始之前就知道,这使得 MEF 毫无意义。

还有其他人知道其他方法吗?我可以以相反的方式构建依赖关系,以便 MEF 部件的 clickonce 安装程序知道它应该使用什么 shell 吗?

谢谢

I have built an executable shell that using MEF loads assemblies (MEF Parts) and displays / acts accordingly to the loaded functionality.

I now want to deploy this application as a ClickOnce install. Does anyone have a strategy for this, at the moment I have seen 2 strategies.

  1. Build and installer for the parts and add it as a Redistributal Component to the shell application - this means that the 2 installations are basically welded together and it means that MEF is basically pointless

  2. Build a downloader function into the shell, this again means that each MEF part needs to be known about before we start, and making MEF pointless.

Does anyone else know of any other approaches ? Can I build the dependancy the other way around, so a clickonce installer for the MEF parts knows what shell it should use ?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

捎一片雪花 2024-10-20 09:03:23

我所做的是使用 Packaging API 并制作一个映射到 shell UI 的自定义文件扩展名。它所做的只是将包解压缩到 ProgramData\MyApp\Extensions 文件夹。然后,当应用程序重新启动时,该部分就会显示出来。

请参阅此博文了解更多信息

           ' Open the Package.
        ' ('using' statement insures that 'package' is
        '  closed and disposed when it goes out of scope.)
        Using package As Package = package.Open(fileName, FileMode.Open, FileAccess.Read)
            tFolder = IO.Path.Combine(tFolder,
                MediaToolz.SharedServices.FileSystem.GetSafeFileName(package.PackageProperties.Title))

            Dim directoryInfo As New DirectoryInfo(tFolder)
            If directoryInfo.Exists Then
                directoryInfo.Delete(True)
            End If
            directoryInfo.Create()

            For Each part In package.GetParts()
                If part.ContentType = Packages.MediaToolzAddinMimeType Then
                    ExtractPart(part, tFolder)
                End If
            Next

            package.Close()
        End Using


'  --------------------------- ExtractPart ---------------------------
''' <summary>
'''   Extracts a specified package part to a target folder.</summary>
''' <param name="packagePart">
'''   The package part to extract.</param>
''' <param name="targetDirectory">
'''   The relative path from the 'current' directory
'''   to the targer folder.</param>
Private Shared Sub ExtractPart(ByVal packagePart As PackagePart, ByVal targetDirectory As String)
    ' Create a string with the full path to the target directory.
    Dim pathToTarget As String = targetDirectory
    If pathToTarget.EndsWith(IO.Path.DirectorySeparatorChar) = False Then pathToTarget += IO.Path.DirectorySeparatorChar
    ' Remove leading slash from the Part Uri,
    '   and make a new Uri from the result
    Dim stringPart As String = packagePart.Uri.ToString().TrimStart("/"c)
    ' I added this line to take off the content pat
    stringPart = IO.Path.GetFileName(stringPart)

    Dim partUri As New Uri(stringPart, UriKind.Relative)

    ' Create a full Uri to the Part based on the Package Uri
    Dim uriFullPartPath As New Uri(New Uri(pathToTarget, UriKind.Absolute), partUri)

    ' Create the necessary Directories based on the Full Part Path
    'Directory.CreateDirectory(Path.GetDirectoryName(uriFullPartPath.LocalPath))

    ' Create the file with the Part content
    Using fileStream As New FileStream(uriFullPartPath.LocalPath, FileMode.Create)
        CopyStream(packagePart.GetStream(), fileStream)
    End Using 'Close & dispose fileStream.
End Sub

'  --------------------------- CopyStream ---------------------------
''' <summary>
'''   Copies data from a source stream to a target stream.</summary>
''' <param name="source">
'''   The source stream to copy from.</param>
''' <param name="target">
'''   The destination stream to copy to.</param>
Private Shared Sub CopyStream(ByVal source As Stream, ByVal target As Stream)
    Const bufSize As Integer = &H1000
    Dim buf(bufSize - 1) As Byte
    Dim bytesRead As Integer = 0
    bytesRead = source.Read(buf, 0, bufSize)
    Do While bytesRead > 0
        target.Write(buf, 0, bytesRead)
        bytesRead = source.Read(buf, 0, bufSize)
    Loop
End Sub

What I did was use the Packaging API and make a custom file extension that is mapped to the shell UI. All it does is unzip the package to the ProgramData\MyApp\Extensions folder. Then when the app is restarted, the part shows up.

See this blog post for more info

           ' Open the Package.
        ' ('using' statement insures that 'package' is
        '  closed and disposed when it goes out of scope.)
        Using package As Package = package.Open(fileName, FileMode.Open, FileAccess.Read)
            tFolder = IO.Path.Combine(tFolder,
                MediaToolz.SharedServices.FileSystem.GetSafeFileName(package.PackageProperties.Title))

            Dim directoryInfo As New DirectoryInfo(tFolder)
            If directoryInfo.Exists Then
                directoryInfo.Delete(True)
            End If
            directoryInfo.Create()

            For Each part In package.GetParts()
                If part.ContentType = Packages.MediaToolzAddinMimeType Then
                    ExtractPart(part, tFolder)
                End If
            Next

            package.Close()
        End Using


'  --------------------------- ExtractPart ---------------------------
''' <summary>
'''   Extracts a specified package part to a target folder.</summary>
''' <param name="packagePart">
'''   The package part to extract.</param>
''' <param name="targetDirectory">
'''   The relative path from the 'current' directory
'''   to the targer folder.</param>
Private Shared Sub ExtractPart(ByVal packagePart As PackagePart, ByVal targetDirectory As String)
    ' Create a string with the full path to the target directory.
    Dim pathToTarget As String = targetDirectory
    If pathToTarget.EndsWith(IO.Path.DirectorySeparatorChar) = False Then pathToTarget += IO.Path.DirectorySeparatorChar
    ' Remove leading slash from the Part Uri,
    '   and make a new Uri from the result
    Dim stringPart As String = packagePart.Uri.ToString().TrimStart("/"c)
    ' I added this line to take off the content pat
    stringPart = IO.Path.GetFileName(stringPart)

    Dim partUri As New Uri(stringPart, UriKind.Relative)

    ' Create a full Uri to the Part based on the Package Uri
    Dim uriFullPartPath As New Uri(New Uri(pathToTarget, UriKind.Absolute), partUri)

    ' Create the necessary Directories based on the Full Part Path
    'Directory.CreateDirectory(Path.GetDirectoryName(uriFullPartPath.LocalPath))

    ' Create the file with the Part content
    Using fileStream As New FileStream(uriFullPartPath.LocalPath, FileMode.Create)
        CopyStream(packagePart.GetStream(), fileStream)
    End Using 'Close & dispose fileStream.
End Sub

'  --------------------------- CopyStream ---------------------------
''' <summary>
'''   Copies data from a source stream to a target stream.</summary>
''' <param name="source">
'''   The source stream to copy from.</param>
''' <param name="target">
'''   The destination stream to copy to.</param>
Private Shared Sub CopyStream(ByVal source As Stream, ByVal target As Stream)
    Const bufSize As Integer = &H1000
    Dim buf(bufSize - 1) As Byte
    Dim bytesRead As Integer = 0
    bytesRead = source.Read(buf, 0, bufSize)
    Do While bytesRead > 0
        target.Write(buf, 0, bytesRead)
        bytesRead = source.Read(buf, 0, bufSize)
    Loop
End Sub
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文