使用非托管FindFirstVolume在C#中使用.NET枚举卷

时间:2010-10-20 18:52:51

标签: c# .net unmanaged winapi

我正在尝试枚举没有直接字母的驱动器,这样我就可以获得每个驱动器上的剩余空间。此应用程序必须与Windows XP一起使用,因此Win32_Volume类不可用。

执行以下代码时,抛出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();
    }

}

1 个答案:

答案 0 :(得分: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 );