3

In a .NET Compact Framework 3.5 application I'm doing a version check in a fairly tight loop in order to know whether or not another assembly needs to be "upgraded" (have a new copy in another directory copied over it, then start it up again).

The problem is that Assembly.LoadFrom(path).GetName().Version locks the file and prevents said copying over.

AssemblyName.GetAssemblyName(path) would be a better way to get this (thanks to this SO answer), as it doesn't permanently load the assembly into the AppDomain and thus doesn't lock the file, but it isn't available in the Compact Framework.

I could create a new AppDomain, but can't use the new domain's Load method as that's not supported in the Compact Framework.

As a last resort I thought I'd allow the assembly to actually be loaded with the Assembly.Load(byte[]) overload, which would cause a massive memory "leak" in a tight loop since they're never unloaded. To counter that I intended to first hash the assembly's byte array and check a cache of versions for a previous hit. However, you guessed it, the byte array overload for Assembly.Load() isn't supported in the Compact Framework.

I also considered adding AssemblyFileVersions, since they're easier to check anyway, but that's another thing in the growing heap of things not supported in the Compact Framework (my thanks to this SO answer for not having to try this).

Please, tell me what I'm trying to do is possible so I stop hating this framework so much?

Community
  • 1
  • 1
phloopy
  • 5,563
  • 4
  • 26
  • 37
  • What did the native file version (in the answer at your last link) return? – ctacke May 27 '11 at 03:55
  • Didn't try it, as you can't even set the File Version in the assembly. The [attribute isn't supported](http://msdn.microsoft.com/en-us/library/system.reflection.assemblyfileversionattribute(v=VS.90).aspx). – phloopy May 27 '11 at 17:07
  • I know that attribute isn't supported - I was curious if maybe the compiler simply set it to the AssemblyVersion during the build process (basically meaning that it's there, just not settable apart from the AssemblyVersion) – ctacke May 27 '11 at 17:49
  • The [`FileVersionInfo`](http://msdn.microsoft.com/en-us/library/system.diagnostics.fileversioninfo(v=VS.90).aspx) class isn't in the Compact Framework, so if it does set it automatically there's still no way to check it. – phloopy May 27 '11 at 19:20
  • The last link in your question points to a [SO question] (http://stackoverflow.com/questions/3812966/getting-file-version-info-in-the-compact-framework) where the answers points to a [blog article](http://blog.opennetcf.com/ctacke/2010/09/28/GettingNativeFileInfoInTheCompactFramework.aspx) that shows how to query the native file version info – ctacke May 27 '11 at 19:44
  • I did see that, but it's scary both in length and in raw memory access. I was hoping I was missing something incredibly obvious. :/ – phloopy May 27 '11 at 22:41

3 Answers3

1

you can retrieve this information using Mono.Cecil as Firo mentionned, here is a F# code snippet:

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

the output from FSI

val getAssembly : filename:string -> AssemblyDefinition
val getVersion : assembly:AssemblyDefinition -> string option
val it : string option = Some "15.2.4.0"
smoothdeveloper
  • 1,972
  • 18
  • 19
1

there is Mono.Cecil from the Mono project which does inspect assemblies without loading them. I think you can distribute and use to check the assemblyversion

Firo
  • 30,626
  • 4
  • 55
  • 94
  • Interesting prospect. The project has [little to no official documentation](http://stackoverflow.com/questions/1513319/mono-cecil-documentation-and-tutorials/1610581#1610581) so it might require groking the [source](https://github.com/jbevain/cecil). I didn't see anything that jumped out as exposing the version information, but it might be in the `CustomAttributes` collection of the [AssemblyDefinition class](https://github.com/jbevain/cecil/blob/master/Mono.Cecil/AssemblyDefinition.cs). I'll give it a try when time allows and report back. Thanks for the response. – phloopy Oct 19 '11 at 17:33
  • As far as distribution rights I don't see anywhere that explicitly says what license the project as a whole uses, but it appears that the individual source files contain the [MIT license](http://en.wikipedia.org/wiki/MIT_License) verbiage. As long as it doesn't use code somewhere in it with a more restrictive license it should be fine to distribute. – phloopy Oct 19 '11 at 17:38
  • 1
    http://svn.apache.org/repos/asf/incubator/lucene.net/trunk/lib/Gallio.3.2.750/licenses/Mono.Cecil.license.html this is what i found as licence, and this answer http://www.mail-archive.com/mono-cecil@googlegroups.com/msg01218.html – Firo Oct 20 '11 at 08:19
1

I think you are going to have to P/Invoke GetFileVersionInfo, GetFileVersionInfoSize, and VerQueryValue to get what your want. The pinvoke.net site is a great tool for signatures and examples on such things. They have GetFileVersionInfo prototyped, but not the others. Let me know if you need help with them and I can probably get the signatures that will work.

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

Also noticed the OpenNETCF library has this implemented in the OpenNETCF.Diagnostics.FileVersionInfo class. So you can download that library and see how they did it.

Damon8or
  • 527
  • 2
  • 11
  • I seem to recall having gotten to the File Version somehow after receiving no response here and seeing that it was always 0.0.0.0. However, I did not attempt either of the things you mention. We already use OpenNETCF in the project, so I'll definitely give at least that one a go and get back to you. We've since worked around the problem, but I'm curious to see if it's possible. Thanks for your response. – phloopy Oct 19 '11 at 17:25
  • Try the Product Version property. – Damon8or Oct 20 '11 at 13:32
  • Whoa, just noticed this was asked back in May. Somehow it bubbled up to the top of my RSS reader. – Damon8or Oct 20 '11 at 18:37
  • I wondered how it got on somebody's radar ;) Thanks for bumping it anyway, there are now some good answers I have to try when I get back on that project. – phloopy Oct 21 '11 at 21:23