部署MEF部件

时间:2011-01-21 13:41:07

标签: windows-installer clickonce mef

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

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

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

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

  3. 还有其他人知道其他任何方法吗?我可以通过其他方式构建依赖性,因此MEF部件的clickonce安装程序知道应该使用哪个shell吗?

    由于

1 个答案:

答案 0 :(得分:1)

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

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