在.NET Compact Framework 3.5应用程序中,我在一个相当紧凑的循环中进行版本检查,以便知道是否需要“升级”另一个程序集(在另一个目录中复制一个新副本,然后再次启动它。)
问题是Assembly.LoadFrom(path).GetName().Version
锁定文件并阻止复制。
AssemblyName.GetAssemblyName(path)
是获得此功能的更好方法(感谢this SO answer),因为它不会将程序集永久加载到AppDomain中,因此不会锁定文件,但它不是紧凑框架中没有。
我可以创建一个新的AppDomain
,但不能使用新域的Load
方法,因为Compact Framework不支持这种方法。
作为最后的手段,我认为我会允许程序集实际加载Assembly.Load(byte[])
重载,这会导致紧密循环中的大量内存“泄漏”,因为它们永远不会被卸载。为了解决这个问题,我打算首先对程序集的字节数组进行哈希处理,并检查以前命中的版本缓存。但是,您猜对了,Compact Framework不支持Assembly.Load()
的字节数组重载。
我还考虑过添加AssemblyFileVersions,因为无论如何它们都更容易检查,但这是Compact Framework中不支持的不断增加的内容中的另一件事(感谢this SO answer不必尝试此操作)
请告诉我,我想要做的是什么,所以我不再那么讨厌这个框架了?
答案 0 :(得分:1)
Mono项目中有Mono.Cecil,它会检查程序集而不加载它们。我认为您可以分发并使用它来检查assemblyversion
答案 1 :(得分:1)
我认为你将需要P / Invoke GetFileVersionInfo,GetFileVersionInfoSize和VerQueryValue来获得你想要的东西。 pinvoke.net网站是一个伟大的工具,用于签名和这些事情的例子。他们有GetFileVersionInfo原型,但没有其他原型。如果您需要帮助我,请告诉我,我可以获得可行的签名。
http://pinvoke.net/default.aspx/coredll/GetFileVersionInfo.html
还注意到OpenNETCF库在OpenNETCF.Diagnostics.FileVersionInfo类中实现了这一点。所以你可以下载该库,看看他们是如何做到的。
答案 2 :(得分:1)
您可以使用Mono.Cecil检索此信息,如Firo所提到的,这是一个F#代码段:
open Mono.Cecil
let getAssembly (filename: string) =
AssemblyDefinition.ReadAssembly(filename)
let getVersion (assembly: AssemblyDefinition) =
let versionAttributeTypeName = typeof<AssemblyFileVersionAttribute>.FullName
match assembly.CustomAttributes.FirstOrDefault(fun f ->f.AttributeType.FullName = versionAttributeTypeName) with
| null -> None
| a -> Some (a.ConstructorArguments.First().Value :?> string)
getAssembly @"path to assembly"
|> getVersion
FSI的输出
val getAssembly : filename:string -> AssemblyDefinition
val getVersion : assembly:AssemblyDefinition -> string option
val it : string option = Some "15.2.4.0"