我已经构建了一个可执行shell,它使用MEF加载程序集(MEF部件)并根据加载的功能显示/操作。
我现在想要将此应用程序部署为ClickOnce安装。有没有人有这方面的策略,目前我已经看过2个策略。
部件的构建和安装程序,并将其作为Redistributal组件添加到shell应用程序中 - 这意味着2个安装基本上是焊接在一起,这意味着MEF基本没有意义
在shell中构建一个下载器功能,这再次意味着在开始之前需要知道每个MEF部分,并使MEF毫无意义。
还有其他人知道其他任何方法吗?我可以通过其他方式构建依赖性,因此MEF部件的clickonce安装程序知道应该使用哪个shell吗?
由于
答案 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