2010-08-11 55 views
2

我有一個簡單的util,它使用一些不安全的代碼來獲取文件版本信息。當我將其編譯爲混合平臺(vs2008/.net 3.5)並將其部署到64位機器時,出現堆損壞錯誤。如果我重新編譯爲x86,那麼一切正常......不安全的c#代碼導致64位平臺上的堆損壞,除非爲x86平臺構建

這是令人驚訝的,因爲我對.NET通用類型系統的理解。我的不安全代碼使用指向短字的指針和指向字節的指針。不同於CTS,這些常見類型在任何平臺上的尺寸是否相同?什麼我在這裏缺少

using System; 
using System.Reflection; 
using System.Runtime.InteropServices; 


public class Win32Imports 
{ 
    [DllImport("version.dll")] 
    public static extern bool GetFileVersionInfo(string sFileName, 
      int handle, int size, byte[] infoBuffer); 

    [DllImport("version.dll")] 
    public static extern int GetFileVersionInfoSize(string sFileName, 
      out int handle); 

    // The third parameter - "out string pValue" - is automatically 
    // marshaled from ANSI to Unicode: 
    [DllImport("version.dll")] 
    unsafe public static extern bool VerQueryValue(byte[] pBlock, 
      string pSubBlock, out string pValue, out uint len); 

    // This VerQueryValue overload is marked with 'unsafe' because 
    // it uses a short*: 
    [DllImport("version.dll")] 
    unsafe public static extern bool VerQueryValue(byte[] pBlock, 
      string pSubBlock, out short* pValue, out uint len); 
} 

public class FileInformation 
{ 
    // Main is marked with 'unsafe' because it uses pointers: 
    unsafe public static string GetVersionInformation(string path) 
    { 

     // Figure out how much version info there is: 
     int handle = 0; 
     int size = 
       Win32Imports.GetFileVersionInfoSize(path, 
       out handle); 
     if (size == 0) return ""; 

     byte[] buffer = new byte[size]; 
     if (!Win32Imports.GetFileVersionInfo(path, handle, size, buffer)) return ""; 

     // Get the locale info from the version info: 
     short* subBlock = null; 
     uint len = 0;   
     if (!Win32Imports.VerQueryValue(buffer, @"\VarFileInfo\Translation", out subBlock, out len)) return ""; 


     // Get the ProductVersion value for this program: 
     string spv = @"\StringFileInfo\" + subBlock[0].ToString("X4") + subBlock[1].ToString("X4") + @"\ProductVersion"; 
     byte* pVersion = null; 
     string versionInfo; 
     if (!Win32Imports.VerQueryValue(buffer, spv, out versionInfo, out len)) return ""; 
     return versionInfo; 

    } 
} 

感謝 殺手所有的殭屍,等待殭屍Apocolypse ....... -Jonathan

回答

2

有沒有你不能使用FileVersionInfo任何理由管理這個班?我懷疑它可以在32位和64位平臺上正常工作。

+1

是的我可以使用該類型。但我對這個問題的理解不會得到幫助。這不是我的代碼來改變(不在我的組)。 – jonathan 2010-08-11 15:04:35

+0

鏈接被破壞?請嘗試http://msdn.microsoft.com/zh-CN/library/system.diagnostics.fileversioninfo.aspx – crashmstr 2011-05-13 18:36:04

1

也許既然指針在平臺上是64位的,但是你使用的是不安全的,這是不是正確轉換?另請說明你的p/invoke導入是什麼樣的。