文件描述缺失字符
FileDescriptora Missing Characters
我正在使用找到的代码 here 直接从 outlook 中拖放 .msg 文件。 FileDescriptorA
class 是这样实现的:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public sealed class FILEDESCRIPTORA
{
public uint dwFlags;
public Guid clsid;
public SIZEL sizel;
public POINTL pointl;
public uint dwFileAttributes;
public System.Runtime.InteropServices.ComTypes.FILETIME ftCreationTime;
public System.Runtime.InteropServices.ComTypes.FILETIME ftLastAccessTime;
public System.Runtime.InteropServices.ComTypes.FILETIME ftLastWriteTime;
public uint nFileSizeHigh;
public uint nFileSizeLow;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string cFileName;
}
获取文件名的代码是:
MemoryStream fgdStream =
(MemoryStream)e.Data.GetData("FileGroupDescriptor");
byte[] fgdBytes = new byte[fgdStream.Length];
fgdStream.Read(fgdBytes, 0, fgdBytes.Length);
fgdStream.Close();
//copy the file group descriptor into unmanaged memory
IntPtr fgdaPtr = Marshal.AllocHGlobal(fgdBytes.Length);
Marshal.Copy(fgdBytes, 0, fgdaPtr, fgdBytes.Length);
int numFiles = Marshal.ReadInt32(fgdaPtr);
string[] fileNames = new string[numFiles];
//get the pointer to the first file descriptor
IntPtr fdPtr = (IntPtr)((int)fgdaPointer + Marshal.SizeOf(fgdaPointer));
//loop for the number of files acording to the file group descriptor
for(int fdIndex = 0;fdIndex < numfiles;fdIndex++)
{
//marshal the pointer to the file descriptor as a FILEDESCRIPTORA struct
object fdObj = Marshal.PtrToStructure(fdPtr,
typeof(NativeMethods.FILEDESCRIPTORA));
NativeMethods.FILEDESCRIPTORA fd = (NativeMethods.FILEDESCRIPTORA)fdObj;
//get file name of file descriptor and put in array
fileNames[fdIndex] = fd.cFileName;
//move the file descriptor pointer to the next file descriptor
fdPtr = (IntPtr)((int)fdPtr + Marshal.SizeOf(fd));
}
这一切都很好,除了返回的文件名总是缺少前几个字符。有谁知道什么会导致 and/or 如何修复它?
在 the codeproject page 的评论中,另一个人提到了同样的问题 - 在这种情况下,数组项的偏移量是从结构的开头计算的,没有考虑前 32/64 位包含数组中的项目数:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public sealed class FILEGROUPDESCRIPTORA
{
public uint cItems;
public FILEDESCRIPTORA[] fgd;
}
IntPtr fileDescriptorPointer = (IntPtr)((long)fileGroupDescriptorWPointer + Marshal.SizeOf(fileGroupDescriptorWPointer) - 4);
fileDescriptorPointer = (IntPtr)((long)fileDescriptorPointer + Marshal.SizeOf(fileDescriptor) - 4);
(long)
64 位支持
- 4
用于获取前 2 个字符 (4 = sizeof(uint))
重复了逻辑(不是代码),所以必须修改两次。
实际上 运行 作为 32 位进程时必须区分代码,因为 -4 移动在这种情况下不起作用:
if (Environment.Is64BitProcess)
{
fileDescriptorPointer = (IntPtr)((long)fileGroupDescriptorAPointer + Marshal.SizeOf(fileGroupDescriptorAPointer)) - 4;
}
else
{
fileDescriptorPointer = (IntPtr)((long)fileGroupDescriptorAPointer + Marshal.SizeOf(fileGroupDescriptorAPointer)) ;
}
我正在使用找到的代码 here 直接从 outlook 中拖放 .msg 文件。 FileDescriptorA
class 是这样实现的:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public sealed class FILEDESCRIPTORA
{
public uint dwFlags;
public Guid clsid;
public SIZEL sizel;
public POINTL pointl;
public uint dwFileAttributes;
public System.Runtime.InteropServices.ComTypes.FILETIME ftCreationTime;
public System.Runtime.InteropServices.ComTypes.FILETIME ftLastAccessTime;
public System.Runtime.InteropServices.ComTypes.FILETIME ftLastWriteTime;
public uint nFileSizeHigh;
public uint nFileSizeLow;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string cFileName;
}
获取文件名的代码是:
MemoryStream fgdStream =
(MemoryStream)e.Data.GetData("FileGroupDescriptor");
byte[] fgdBytes = new byte[fgdStream.Length];
fgdStream.Read(fgdBytes, 0, fgdBytes.Length);
fgdStream.Close();
//copy the file group descriptor into unmanaged memory
IntPtr fgdaPtr = Marshal.AllocHGlobal(fgdBytes.Length);
Marshal.Copy(fgdBytes, 0, fgdaPtr, fgdBytes.Length);
int numFiles = Marshal.ReadInt32(fgdaPtr);
string[] fileNames = new string[numFiles];
//get the pointer to the first file descriptor
IntPtr fdPtr = (IntPtr)((int)fgdaPointer + Marshal.SizeOf(fgdaPointer));
//loop for the number of files acording to the file group descriptor
for(int fdIndex = 0;fdIndex < numfiles;fdIndex++)
{
//marshal the pointer to the file descriptor as a FILEDESCRIPTORA struct
object fdObj = Marshal.PtrToStructure(fdPtr,
typeof(NativeMethods.FILEDESCRIPTORA));
NativeMethods.FILEDESCRIPTORA fd = (NativeMethods.FILEDESCRIPTORA)fdObj;
//get file name of file descriptor and put in array
fileNames[fdIndex] = fd.cFileName;
//move the file descriptor pointer to the next file descriptor
fdPtr = (IntPtr)((int)fdPtr + Marshal.SizeOf(fd));
}
这一切都很好,除了返回的文件名总是缺少前几个字符。有谁知道什么会导致 and/or 如何修复它?
在 the codeproject page 的评论中,另一个人提到了同样的问题 - 在这种情况下,数组项的偏移量是从结构的开头计算的,没有考虑前 32/64 位包含数组中的项目数:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public sealed class FILEGROUPDESCRIPTORA
{
public uint cItems;
public FILEDESCRIPTORA[] fgd;
}
IntPtr fileDescriptorPointer = (IntPtr)((long)fileGroupDescriptorWPointer + Marshal.SizeOf(fileGroupDescriptorWPointer) - 4);
fileDescriptorPointer = (IntPtr)((long)fileDescriptorPointer + Marshal.SizeOf(fileDescriptor) - 4);
(long)
64 位支持
- 4
用于获取前 2 个字符 (4 = sizeof(uint))
重复了逻辑(不是代码),所以必须修改两次。
实际上 运行 作为 32 位进程时必须区分代码,因为 -4 移动在这种情况下不起作用:
if (Environment.Is64BitProcess)
{
fileDescriptorPointer = (IntPtr)((long)fileGroupDescriptorAPointer + Marshal.SizeOf(fileGroupDescriptorAPointer)) - 4;
}
else
{
fileDescriptorPointer = (IntPtr)((long)fileGroupDescriptorAPointer + Marshal.SizeOf(fileGroupDescriptorAPointer)) ;
}