C# 使用GetDiskFreeSpaceExA时出现不平衡堆栈错误

C# 使用GetDiskFreeSpaceExA时出现不平衡堆栈错误,c#,vb.net,C#,Vb.net,以下代码(调用proc DiskFreeSpace)抛出一条“不平衡堆栈”错误消息 Private Declare Function GetDiskFreeSpaceEx Lib "kernel32" Alias "GetDiskFreeSpaceExA" (ByVal lpDirectoryName As String, _ ByVal lpFreeBytesAvailableToCaller As Long, _ ByVal l

以下代码(调用proc DiskFreeSpace)抛出一条“不平衡堆栈”错误消息

Private Declare Function GetDiskFreeSpaceEx Lib "kernel32" Alias "GetDiskFreeSpaceExA" (ByVal lpDirectoryName As String, _
                ByVal lpFreeBytesAvailableToCaller As Long, _
                ByVal lpTotalNumberOfBytes As Long, _
                ByVal lpTotalNumberOfFreeBytes As Long) As Long

Friend Shared Function DiskFreeSpace(ByVal sdirDrive As String) As Long
            Dim Status As Long
            Dim TotalBytes As Long
            Dim FreeBytes As Long
            Dim BytesAvailableToCaller As Long

            Status = GetDiskFreeSpaceEx(sdirDrive, BytesAvailableToCaller, TotalBytes, FreeBytes)

            Return FreeBytes

        End Function
这里怎么了

确切的错误消息是:

对PInvoke函数的调用 “测试!XYZ.Test.FN.MyFileSystem::GetDiskFreeSpaceEx' 使堆栈不平衡。这是 很可能是因为那只松鼠 签名与非托管签名不匹配 目标签名。检查 调用约定和参数 PInvoke签名与目标匹配 非托管签名


附加说明:我的函数也需要用于UNC路径(本地和/或网络)。

我认为您的签名问题。试着使用这个():

_
私有共享函数GetDiskFreeSpaceEx(_
ByVal lpDirectoryName作为字符串_
ByRef LPFreeBytes作为ULong提供_
ByRef lpTotalNumberOfBytes作为ULong_
ByRef lpTotalNumberOfFreeBytes作为ULong)作为布尔值
端函数

返回值的差异我认为你的签名有问题。试着使用这个():

_
私有共享函数GetDiskFreeSpaceEx(_
ByVal lpDirectoryName作为字符串_
ByRef LPFreeBytes作为ULong提供_
ByRef lpTotalNumberOfBytes作为ULong_
ByRef lpTotalNumberOfFreeBytes作为ULong)作为布尔值
端函数

返回值的差异

我对这段代码不是很确定,但您也可以使用代码
My.Computer.FileSystem.Drives
并找出可用空间、已用空间和总空间。我觉得使用.NET内置函数比尝试使用Windows DLL调用更容易,因为毕竟.NET应用程序只能在.NET版本与构建应用程序的版本相同或更高的计算机上工作


干杯

我对这段代码不是很确定,但您也可以使用代码My.Computer.FileSystem.Drives,找出可用空间、已用空间和总空间。我觉得使用.NET内置函数比尝试使用Windows DLL调用更容易,因为毕竟.NET应用程序只能在.NET版本与构建应用程序的版本相同或更高的计算机上工作


干杯

谢谢你的回答,但这只适用于当地的汽车;不适用于UNC路径。我宁愿避免直接使用WinAPI,但在这种情况下,我似乎没有选择。是的!我理解!谢谢你让我知道干杯谢谢你的回答,但这只适用于本地驱动器;不适用于UNC路径。我宁愿避免直接使用WinAPI,但在这种情况下,我似乎没有选择。是的!我理解!谢谢你让我知道干杯d此功能应与UNC配合使用。从中导出函数的DLL名称中出现错误,但我已修复此错误。这会引发异常:“无法加载DLL‘coredll.DLL’:找不到指定的模块。(HRESULT中的异常:0x8007007E)”。我正在使用Win7/64。是的,现在它可以工作:)。你能解释一下为什么我的方法不起作用(使用“Declare Function”而不是“DLLImport”属性)?我对有效的解决方案已经很满意了,但只是想知道;)@马克:我认为你的方法不起作用是因为返回值,而不是因为声明。在以前的版本中,返回值是长的(在.NET上为64位),实际上它是作为整数(32位)传递的。而diring封送Pinvoke总是试图从堆栈中读取长值。所以在你们的例子中,pinvoke必须从堆栈中读取额外的32位数据,这是错误的原因。这个函数应该与UNC一起工作。从中导出函数的DLL名称中出现错误,但我已修复此错误。这会引发异常:“无法加载DLL‘coredll.DLL’:找不到指定的模块。(HRESULT中的异常:0x8007007E)”。我正在使用Win7/64。是的,现在它可以工作:)。你能解释一下为什么我的方法不起作用(使用“Declare Function”而不是“DLLImport”属性)?我对有效的解决方案已经很满意了,但只是想知道;)@马克:我认为你的方法不起作用是因为返回值,而不是因为声明。在以前的版本中,返回值是长的(在.NET上为64位),实际上它是作为整数(32位)传递的。而diring封送Pinvoke总是试图从堆栈中读取长值。所以在你们的例子中,pinvoke必须从堆栈中读取额外的32位数据,这就是错误的原因,这段代码甚至不能编译!打开
选项
@康拉德:我同意,但我总是把选项设置为On!它编译没有任何错误。我的错。我没有看到WinAPI函数声明中的第一个参数,并且假设第一个参数的类型是
Long
。由于您将
sdirDrive
作为第一个参数传递,因此无法运行。此代码甚至不应编译!打开
选项
@康拉德:我同意,但我总是把选项设置为On!它编译没有任何错误。我的错。我没有看到WinAPI函数声明中的第一个参数,并且假设第一个参数的类型是
Long
。由于您将
sdirDrive
作为第一个参数传递,因此这无法工作。
<DllImport("Kernel32.dll", EntryPoint:="GetDiskFreeSpaceEx", SetLastError:=True, CharSet:=CharSet.Auto)> _
  Private Shared Function GetDiskFreeSpaceEx( _
   ByVal lpDirectoryName As String, _
   ByRef lpFreeBytesAvailable As ULong, _
   ByRef lpTotalNumberOfBytes As ULong, _
   ByRef lpTotalNumberOfFreeBytes As ULong) As Boolean
  End Function