DWORD OREnumKey(
__in ORHKEY Handle,
__in DWORD dwIndex,
__out PWSTR lpName,
__inout PDWORD lpcName,
__out_opt PWSTR lpClass,
__inout_opt PDWORD lpcClass,
__out_opt PFILETIME lpftLastWriteTime
);
我的代码
[DllImport("offreg.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern uint OREnumKey(IntPtr Handle, IntPtr dwIndex, [MarshalAs(UnmanagedType.LPWStr)]out StringBuilder lpName, ref IntPtr lpcName, [MarshalAs(UnmanagedType.LPWStr)]out StringBuilder lpClass, ref IntPtr lpcClass, out System.Runtime.InteropServices.ComTypes.FILETIME lpftLastWriteTime);
IntPtr myKey = hiveid;
IntPtr dwindex=(IntPtr)0;
StringBuilder lpName=new StringBuilder("",255);
IntPtr lpcName = (IntPtr)0;
StringBuilder lpClass=new StringBuilder("",255);
IntPtr lpcClass = (IntPtr)11;
System.Runtime.InteropServices.ComTypes.FILETIME lpftLastWriteTime;
uint ret3 = OREnumKey(myKey, dwindex, out lpName, ref lpcName, out lpClass, ref lpcClass, out lpftLastWriteTime);
ret3 = ERROR_MORE_DATA 234
问题可能在错误的StringBuilder大小或FILETIME中
第二部我应如何从C#调用PWSTR参数?
[MarshalAs(UnmanagedType.LPWStr)]out StringBuilder lpName
这是正确的吗?
答案 0 :(得分:1)
这是一个相当标准的Windows错误代码,这意味着您调用了一个winapi函数并且没有传递足够大的缓冲区。解决问题的唯一方法是传递更大的缓冲区。
这看起来很像RegQueryKeyEx()的包装器,这使得很可能将错误的数据传递给函数。 lpcName 参数实际上是ref int
,而不是IntPtr。并且您应该传递一个变量来存储您传递的缓冲区的大小,在您的情况下为255。 lpcClass参数同样是borked。这应该解决它:
[DllImport("offreg.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern uint OREnumKey(
IntPtr Handle,
int dwIndex,
StringBuilder lpName,
ref int lpcName,
StringBuilder lpClass,
ref int lpcClass,
out System.Runtime.InteropServices.ComTypes.FILETIME lpftLastWriteTime);
...
StringBuilder lpName=new StringBuilder("",255);
int nameSize = lpName.Capacity;
StringBuilder lpClass=new StringBuilder("",255);
int classSize = lpClass.Capacity;
System.Runtime.InteropServices.ComTypes.FILETIME lpftLastWriteTime;
uint ret3 = OREnumKey(hiveid, 0, lpName, ref nameSize, lpClass, ref classSize, out lpftLastWriteTime);
if (ret3 != 0) throw new Exception("kaboom");
string name = lpName.ToString();
string className = lpClass.ToString();