2010-10-20 47 views
3

我想枚举未装入直接字母的驱动器,以便我可以获取每个驱动器上的剩余空间。此应用程序必须与Windows XP一起使用,因此Win32_Volume类不可用。使用非托管的FindFirstVolume枚举C#中的.NET的卷#

执行以下代码时,会引发System.ExecutionEngineException。

using System; 
using System.Text; 
using System.Runtime.InteropServices; 
using System.Collections.Generic; 

class Test : IDisposable 
{ 
    public static void Main(string[] args) 
    { 
     try 
     { 
      GetVolumes(); 
     } 
     catch (Exception e) 
     { 
      Console.WriteLine(e.ToString()); 
     } 
    } 
    //HANDLE WINAPI FindFirstVolume(
    // __out LPTSTR lpszVolumeName, 
    // __in DWORD cchBufferLength 
    //); 


    [DllImport("kernel32.dll", EntryPoint = "FindFirstVolume", SetLastError = true, CallingConvention = CallingConvention.StdCall)] 
    public static extern int FindFirstVolume(
     out StringBuilder lpszVolumeName, 
     int cchBufferLength); 


    [DllImport("kernel32.dll", EntryPoint = "FindNextVolume", SetLastError = true, CallingConvention = CallingConvention.StdCall)] 
    public static extern bool FindNextVolume(
     int hFindVolume, 
     out StringBuilder lpszVolumeName, 
     int cchBufferLength); 

    public static List<string> GetVolumes() 
    { 

     const int N = 1024; 
     StringBuilder cVolumeName = new StringBuilder((int)N); 
     List<string> ret = new List<string>(); 
     int volume_handle = FindFirstVolume(out cVolumeName, N); 
     do 
     { 
      ret.Add(cVolumeName.ToString()); 
      Console.WriteLine(cVolumeName.ToString()); 
     } while (FindNextVolume(volume_handle, out cVolumeName, N)); 
     return ret; 
    } 


    void IDisposable.Dispose() 
    { 
     throw new NotImplementedException(); 
    } 

} 

回答

2

从StringBuilder的前删除了:

[DllImport("kernel32.dll", EntryPoint = "FindFirstVolume", SetLastError = true, CallingConvention = CallingConvention.StdCall)] 
public static extern int FindFirstVolume(
    StringBuilder lpszVolumeName, 
    int cchBufferLength); 


[DllImport("kernel32.dll", EntryPoint = "FindNextVolume", SetLastError = true, CallingConvention = CallingConvention.StdCall)] 
public static extern bool FindNextVolume(
    int hFindVolume, 
    StringBuilder lpszVolumeName, 
    int cchBufferLength);