我试图在C#中使用Coredll.dll来检索已挂载商店的数据。
以下是我应该模仿本地库中结构的结构(STORAGEDEVICEINFO,STORAGEINFO)
[StructLayout(LayoutKind.Sequential)]
public unsafe struct STORAGEDEVICEINFO
{
public DWORD cbSize;
public fixed System.UInt16 szProfile[32];
public DWORD dwDeviceClass;
public DWORD dwDeviceType;
public DWORD dwDeviceFlags;
}
[StructLayout(LayoutKind.Sequential)]
public unsafe struct STOREINFO
{
public DWORD cbSize;
public fixed System.UInt16 szDeviceName[8];
public fixed System.UInt16 szStoreName[32];
public DWORD dwDeviceClass;
public DWORD dwDeviceType;
public STORAGEDEVICEINFO sdi;
public DWORD dwDeviceFlags;
public SECTORNUM snNumSectors;
public DWORD dwBytesPerSector;
public SECTORNUM snFreeSectors;
public SECTORNUM snBiggestPartCreatable;
public DWORD ftCreated; /* ? */
public DWORD ftLastModified;
public DWORD dwAttributes;
public DWORD dwPartitionCount;
public DWORD dwMountCount;
}
这是我的FindStoreInfo调用(HANDLE
只是IntPtr
):
[DllImport("Coredll.dll", SetLastError = true)]
public static extern HANDLE FindFirstStore(STOREINFO *info/*PSTOREINFO pStoreInfo*/);
函数调用时没有错误但是它没有改变info
。除了cbSize之外,它将它留作空白结构(但是从sizeof调用更改)。这就是我所说的。
STOREINFO info;
info.cbSize = (uint)Marshal.SizeOf(typeof(STOREINFO));
Store.StorageManager.FindFirstStore(&info);
调用GetLastError返回0x57,即" ERROR_INVALID_PARAMETER"。我不确定为什么要退货,因为我所寻找的只是指针。
答案 0 :(得分:2)
看起来你的cbSize
可能是错的。尝试改变
public fixed char szProfile[32];
至public fixed System.UInt16 szProfile[32];
此外,FILETIME
是两个DWORD结构,而不是一个DWORD。
答案 1 :(得分:2)
我知道这是一个老问题,但也许可以帮助其他人:
以下结构对我有用,请注意编组:
[StructLayout(LayoutKind.Sequential)]
public unsafe struct STORAGEDEVICEINFO
{
public DWORD cbSize;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string szProfile;
public DWORD dwDeviceClass;
public DWORD dwDeviceType;
public DWORD dwDeviceFlags;
}
[StructLayout(LayoutKind.Sequential)]
public unsafe struct STOREINFO
{
public DWORD cbSize;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
public string szDeviceName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string szStoreName;
public DWORD dwDeviceClass;
public DWORD dwDeviceType;
public STORAGEDEVICEINFO sdi;
public DWORD dwDeviceFlags;
public SECTORNUM snNumSectors;
public DWORD dwBytesPerSector;
public SECTORNUM snFreeSectors;
public SECTORNUM snBiggestPartCreatable;
public FILETIME ftCreated;
public FILETIME ftLastModified;
public DWORD dwAttributes;
public DWORD dwPartitionCount;
public DWORD dwMountCount;
}
[StructLayout(LayoutKind.Sequential)]
public unsafe struct PARTINFO
{
public DWORD cbSize;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string szPartitionName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string szFileSys;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
public string szVolumeName;
public SECTORNUM snNumSectors;
public FILETIME ftCreated;
public FILETIME ftLastModified;
public DWORD dwAttributes;
public BYTE bPartType;
}
我还了解到,您可以通过引用P / Invoke调用来传递结构:
[DllImport("Coredll.dll", SetLastError = true)]
public static extern HANDLE FindFirstStore(ref STOREINFO storeInfo);
[DllImport("Coredll.dll", SetLastError = true)]
public static extern bool FindNextStore(HANDLE hSearch, ref STOREINFO storeInfo);
通话:
STOREINFO si = new STOREINFO();
HANDLE hSearch = INVALID_HANDLE_VALUE;
si.cbSize = (uint)Marshal.SizeOf(typeof(STOREINFO));
// enumerate first store
hSearch = StorageManager.FindFirstStore(ref si);