Windows installer 部署MEF部件

Windows installer 部署MEF部件,windows-installer,clickonce,mef,Windows Installer,Clickonce,Mef,我已经构建了一个可执行的shell,它使用MEF加载程序集(MEF部件),并根据加载的功能显示/执行相应的操作 我现在想将此应用程序部署为ClickOnce安装。是否有人对此有策略,目前我已经看到了两种策略 构建和安装这些部件,并将其作为再发行组件添加到shell应用程序中——这意味着这两个安装基本上是焊接在一起的,这意味着MEF基本上没有意义 在shell中构建一个downloader函数,这同样意味着在开始之前需要了解每个MEF部分,并使MEF变得毫无意义 还有谁知道其他方法吗?我能否以另一

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

我现在想将此应用程序部署为ClickOnce安装。是否有人对此有策略,目前我已经看到了两种策略

  • 构建和安装这些部件,并将其作为再发行组件添加到shell应用程序中——这意味着这两个安装基本上是焊接在一起的,这意味着MEF基本上没有意义

  • 在shell中构建一个downloader函数,这同样意味着在开始之前需要了解每个MEF部分,并使MEF变得毫无意义

  • 还有谁知道其他方法吗?我能否以另一种方式构建依赖性,以便MEF部件的clickonce安装程序知道应该使用什么shell

    谢谢

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

    ”打开软件包。
    “(“using”语句确保“package”是
    '在超出范围时关闭并处置。)
    使用package As package=package.Open(文件名,FileMode.Open,FileAccess.Read)
    tFolder=IO.Path.Combine(tFolder,
    MediaToolz.SharedServices.FileSystem.GetSafeFileName(package.PackageProperties.Title))
    Dim directoryInfo作为新的directoryInfo(tFolder)
    如果directoryInfo.存在,则
    directoryInfo.Delete(True)
    如果结束
    directoryInfo.Create()
    对于package.GetParts()中的每个部件
    如果part.ContentType=Packages.MediaToolzAddinMimeType,则
    提取部件(部件,tFolder)
    如果结束
    下一个
    package.Close()
    终端使用
    “-----------------------------提取部分---------------------------
    ''' 
    ''将指定的包部件提取到目标文件夹。
    ''' 
    ''要提取的包装零件。
    ''' 
    ''当前目录的相对路径
    ''到targer文件夹。
    私有共享子提取器部分(ByVal packagePart作为packagePart,ByVal targetDirectory作为字符串)
    '创建具有目标目录完整路径的字符串。
    Dim pathToTarget As String=targetDirectory
    如果pathToTarget.EndsWith(IO.Path.directoryseportorchar)=False,则pathToTarget+=IO.Path.directoryseportorchar
    '从零件Uri中删除前导斜杠,
    '并根据结果创建一个新的Uri
    Dim stringPart As String=packagePart.Uri.ToString().TrimStart(“/”c)
    “我添加这一行是为了去掉内容
    stringPart=IO.Path.GetFileName(stringPart)
    Dim partUri作为新Uri(stringPart,UriKind.Relative)
    '根据包Uri创建零件的完整Uri
    Dim uriFullPartPath作为新Uri(新Uri(pathToTarget,UriKind.Absolute),partUri)
    '根据完整零件路径创建必要的目录
    'Directory.CreateDirectory(Path.GetDirectoryName(uriFullPartPath.LocalPath))
    '使用零件内容创建文件
    将fileStream用作新的fileStream(uriFullPartPath.LocalPath,FileMode.Create)
    CopyStream(packagePart.GetStream(),fileStream)
    使用“关闭并处置文件流”结束。
    端接头
    “------------------------------CopyStream---------------------------
    ''' 
    ''将数据从源流复制到目标流。
    ''' 
    ''要从中复制的源流。
    ''' 
    ''要复制到的目标流。
    私有共享子复制流(ByVal源作为流,ByVal目标作为流)
    常量bufSize为整数=&H1000
    Dim buf(bufSize-1)作为字节
    Dim字节读取为整数=0
    bytesRead=source.Read(buf,0,bufSize)
    当字节读取>0时执行此操作
    target.Write(buf,0,字节读取)
    bytesRead=source.Read(buf,0,bufSize)
    环
    端接头
    
    注意:打包API在windows XP中不可用,它是Net 3.5 sp1或更高版本。我绕过了API windows XP的限制,找到了操作系统,然后在应用程序中手动解压缩(如果是XP)。哇,如果这样做有效,那么它将是一个真正的赢家!我从来没有使用过(或看过)打包API,所以有没有可以看的示例/文档?现在我的答案中有代码示例。请参阅
               ' 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