获取程序集的版本而不在.NET Compact Framework中加载它

时间:2011-05-27 02:32:44

标签: .net compact-framework assemblies version

在.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不必尝试此操作)

请告诉我,我想要做的是什么,所以我不再那么讨厌这个框架了?

3 个答案:

答案 0 :(得分:1)

我认为你将需要P / Invoke GetFileVersionInfo,GetFileVersionInfoSize和VerQueryValue来获得你想要的东西。 pinvoke.net网站是一个伟大的工具,用于签名和这些事情的例子。他们有GetFileVersionInfo原型,但没有其他原型。如果您需要帮助我,请告诉我,我可以获得可行的签名。

http://pinvoke.net/default.aspx/coredll/GetFileVersionInfo.html

还注意到OpenNETCF库在OpenNETCF.Diagnostics.FileVersionInfo类中实现了这一点。所以你可以下载该库,看看他们是如何做到的。

答案 1 :(得分:1)

Mono项目中有Mono.Cecil,它会检查程序集而不加载它们。我认为您可以分发并使用它来检查assemblyversion

答案 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"