[英]Getting the version of an exe file without loading in .NET Compact Framework
我有一個在.NET Compact Framework 3.5上運行的移動應用程序和在同一平台上運行的更新程序。 當用戶點擊應用程序快捷方式時,更新程序應用程序首先運行並檢查是否有新版本的主應用程序。 是可用的。 為此,我使用Assembly.LoadFrom方法加載主exe程序集並獲取當前版本。 如果找到新版本(通過Web服務),則會下載新文件並替換。 這很好用。 問題是,當它嘗試替換主exe文件時,它會因為“另一個進程使用”樣式異常而失敗(可能是因為它之前已經加載過)。 如何卸載此程序集或如何在不加載它的情況下獲取其版本?
我已經對Assembly類和AppDomain做了一些研究,但.NET CF有一些局限性,所以我無法弄明白。
任何想法?
謝謝。
使用AssemblyName.GetAssemblyName(string)
或FileVersionInfo
的“傳統”方式不起作用,因為.NET CF不支持它們。 要在不使用Assembly.LoadFrom
情況下執行此操作,您需要使用P / Invoke本機獲取文件版本信息。 您可以嘗試此代碼( 未經測試 ):
[DllImport("coredll", EntryPoint = "GetFileVersionInfo", SetLastError = true)]
private static extern bool GetFileVersionInfo(string filename, int handle, int len, IntPtr buffer);
[DllImport("coredll", EntryPoint = "GetFileVersionInfoSize", SetLastError = true)]
private static extern int GetFileVersionInfoSize(string filename, ref int handle);
[DllImport("coredll", EntryPoint = "VerQueryValue", SetLastError = true)]
private static extern bool VerQueryValue(IntPtr buffer, string subblock, ref IntPtr blockbuffer, ref int len);
public static Version GetFileVersionCe(string fileName)
{
int handle = 0;
int length = GetFileVersionInfoSize(fileName, ref handle);
Version v = null;
if (length > 0)
{
IntPtr buffer = System.Runtime.InteropServices.Marshal.AllocHGlobal(length);
if (GetFileVersionInfo(fileName, handle, length, buffer))
{
IntPtr fixedbuffer = IntPtr.Zero;
int fixedlen = 0;
if (VerQueryValue(buffer, "\\", ref fixedbuffer, ref fixedlen))
{
byte[] fixedversioninfo = new byte[fixedlen];
System.Runtime.InteropServices.Marshal.Copy(fixedbuffer, fixedversioninfo, 0, fixedlen);
v = new Version(
BitConverter.ToInt16(fixedversioninfo, 10),
BitConverter.ToInt16(fixedversioninfo, 8),
BitConverter.ToInt16(fixedversioninfo, 14),
BitConverter.ToInt16(fixedversioninfo, 12));
}
}
Marshal.FreeHGlobal(buffer);
}
return v;
}
老帖子,但萬一有人在尋找它。 我的VB(工作)版本。
Public Declare Function GetFileVersionInfo Lib "Coredll" (ByVal filename As String, ByVal handle As Integer, ByVal len As Integer, ByVal buffer As IntPtr) As Boolean
Public Declare Function GetFileVersionInfoSize Lib "Coredll" (ByVal filename As String, ByRef handle As Integer) As Integer
Public Declare Function VerQueryValue Lib "Coredll" (ByVal buffer As IntPtr, ByVal subblock As String, ByRef blockbuffer As IntPtr, ByRef len As Integer) As Boolean
Public Function GetFileVersionCE(ByVal fileName As String) As Version
Dim handle = 0
Dim length = GetFileVersionInfoSize(fileName, handle)
Dim v As Version = Nothing
If length > 0 Then
Dim buffer As IntPtr = Marshal.AllocHGlobal(length)
If (GetFileVersionInfo(fileName, handle, length, buffer)) Then
Dim fixedbuffer As IntPtr = IntPtr.Zero
Dim fixedlen As Integer = 0
If (VerQueryValue(buffer, "\\", fixedbuffer, fixedlen)) Then
Dim fixedversioninfo(fixedlen) As Byte
Marshal.Copy(fixedbuffer, fixedversioninfo, 0, fixedlen)
v = New Version(BitConverter.ToInt16(fixedversioninfo, 10), _
BitConverter.ToInt16(fixedversioninfo, 8), _
BitConverter.ToInt16(fixedversioninfo, 14), _
BitConverter.ToInt16(fixedversioninfo, 12))
End If
End If
Marshal.FreeHGlobal(buffer)
End If
Return v
End Function
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.