C# Pinvoke 无效的文件句柄
C# Pinvoke invalid file handle
我在使用 kernal32 Pinvoke 函数时遇到问题,因为它们一直抛出 INVALID_FILE_HANDLE。程序读取当前硬盘的第一个扇区。我看不出下面的代码有什么问题。
class Program
{
const uint GENERIC_READ = 0x80000000;
const uint FILE_SHARE_READ = 0x00000001;
const uint OPEN_EXISTING = 0x00000003;
const uint FILE_FLAG_DELETE_ON_CLOSE = 0x04000000;
[DllImport("kernel32.dll", SetLastError = true)]
public static extern SafeFileHandle CreateFile(string Disk, uint Access, uint ShareMode, IntPtr SecurityAttributes, uint CreationDisposition, uint Flags, IntPtr TemplateFile);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern uint SetFilePointer([In] SafeFileHandle Handle, [In] int DistanceToMove, [Out] out int DistanceToMoveHigh, [In] int MoveMethod);
[DllImport("kernel32.dll", SetLastError = true)]
unsafe public static extern int ReadFile(SafeFileHandle Handle, [Out] byte[] Buffer, int NumberOfBytesToRead, out int NumberOfBytesRead, IntPtr Overlapped);
unsafe public static void Main(string[] args)
{
string Drive = @"\.\C";
int SectorSize = 512;
int Sector = 0;
int BytesRead, DistanceToMoveHigh;
byte[] Buffer = new byte[SectorSize];
SafeFileHandle Handle = CreateFile(Drive, GENERIC_READ, FILE_SHARE_READ, IntPtr.Zero, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, IntPtr.Zero);
SetFilePointer(Handle, Sector * SectorSize, out DistanceToMoveHigh, 0);
ReadFile(Handle, Buffer, SectorSize, out BytesRead, IntPtr.Zero);
Console.WriteLine(Marshal.GetLastWin32Error()); // It gives 6 which translates to an INVALID_FILE_HANDLE error
Console.ReadKey();
}
}
您对 CreateFile
的呼叫失败。当然,您无法知道这一点,因为您省略了任何错误检查。阅读文档。您调用的所有三个函数的错误都由 return 值表示。你忽略了。
您对 CreateFile
return 的通话 INVALID_HANDLE_VALUE
。你需要为此进行测试。当你遇到那个,只有那个时候,调用GetLastWin32Error
。可能 ERROR_ACCESS_DENIED
会被 return 编辑。
- 传递
FILE_FLAG_DELETE_ON_CLOSE
是错误的。删除该标志。
- 我认为共享标志必须是
FILE_SHARE_READ | FILE_SHARE_WRITE
。
- 文件名必须是
@"\.\C:"
并带有尾随冒号。
- 并且您将需要执行提升的进程。
你用错了GetLastWin32Error
。
这里失败的方法是CreateFile
和它returns一个INVALID_HANDLE_VALUE
(说明它失败了)。要确定哪里出了问题,您必须在 CreateFile
.
之后直接调用 GetLastWin32Error
当您在尝试读取后调用它时,错误当然是 ERROR_INVALID_HANDLE (6)
,因为您将无效句柄传递给 ReadFile
。
如果您在失败 CreateFile
之后直接调用 GetLastWin32Error
,您会得到错误 2:
The system cannot find the file specified.
那是因为驱动名少了一个:
string Drive = @"\.\C:"; // <- add colon :
我尝试使用该驱动器名称,但随后收到错误 32:
The process cannot access the file because it is being used by another process.
我一直在想办法解决这个问题...
我在使用 kernal32 Pinvoke 函数时遇到问题,因为它们一直抛出 INVALID_FILE_HANDLE。程序读取当前硬盘的第一个扇区。我看不出下面的代码有什么问题。
class Program
{
const uint GENERIC_READ = 0x80000000;
const uint FILE_SHARE_READ = 0x00000001;
const uint OPEN_EXISTING = 0x00000003;
const uint FILE_FLAG_DELETE_ON_CLOSE = 0x04000000;
[DllImport("kernel32.dll", SetLastError = true)]
public static extern SafeFileHandle CreateFile(string Disk, uint Access, uint ShareMode, IntPtr SecurityAttributes, uint CreationDisposition, uint Flags, IntPtr TemplateFile);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern uint SetFilePointer([In] SafeFileHandle Handle, [In] int DistanceToMove, [Out] out int DistanceToMoveHigh, [In] int MoveMethod);
[DllImport("kernel32.dll", SetLastError = true)]
unsafe public static extern int ReadFile(SafeFileHandle Handle, [Out] byte[] Buffer, int NumberOfBytesToRead, out int NumberOfBytesRead, IntPtr Overlapped);
unsafe public static void Main(string[] args)
{
string Drive = @"\.\C";
int SectorSize = 512;
int Sector = 0;
int BytesRead, DistanceToMoveHigh;
byte[] Buffer = new byte[SectorSize];
SafeFileHandle Handle = CreateFile(Drive, GENERIC_READ, FILE_SHARE_READ, IntPtr.Zero, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, IntPtr.Zero);
SetFilePointer(Handle, Sector * SectorSize, out DistanceToMoveHigh, 0);
ReadFile(Handle, Buffer, SectorSize, out BytesRead, IntPtr.Zero);
Console.WriteLine(Marshal.GetLastWin32Error()); // It gives 6 which translates to an INVALID_FILE_HANDLE error
Console.ReadKey();
}
}
您对 CreateFile
的呼叫失败。当然,您无法知道这一点,因为您省略了任何错误检查。阅读文档。您调用的所有三个函数的错误都由 return 值表示。你忽略了。
您对 CreateFile
return 的通话 INVALID_HANDLE_VALUE
。你需要为此进行测试。当你遇到那个,只有那个时候,调用GetLastWin32Error
。可能 ERROR_ACCESS_DENIED
会被 return 编辑。
- 传递
FILE_FLAG_DELETE_ON_CLOSE
是错误的。删除该标志。 - 我认为共享标志必须是
FILE_SHARE_READ | FILE_SHARE_WRITE
。 - 文件名必须是
@"\.\C:"
并带有尾随冒号。 - 并且您将需要执行提升的进程。
你用错了GetLastWin32Error
。
这里失败的方法是CreateFile
和它returns一个INVALID_HANDLE_VALUE
(说明它失败了)。要确定哪里出了问题,您必须在 CreateFile
.
之后直接调用 GetLastWin32Error
当您在尝试读取后调用它时,错误当然是 ERROR_INVALID_HANDLE (6)
,因为您将无效句柄传递给 ReadFile
。
如果您在失败 CreateFile
之后直接调用 GetLastWin32Error
,您会得到错误 2:
The system cannot find the file specified.
那是因为驱动名少了一个:
string Drive = @"\.\C:"; // <- add colon :
我尝试使用该驱动器名称,但随后收到错误 32:
The process cannot access the file because it is being used by another process.
我一直在想办法解决这个问题...