本文介绍了PInvoke FbwfFindFirst-FbwfCacheDetail问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为 FbwfFindFirst ,并在结构 FbwfCacheDetail .

I'm trying to create a PInvoke for FbwfFindFirst and am struggling with the struct FbwfCacheDetail.

简而言之,我不确定如何编组WCHAR fileName[1];,因为它是一个可变长度数组且非空终止.

In short, I'm not sure how to marshal WCHAR fileName[1]; seeing as it's a variable length array and a non-null terminated.

任何帮助都将受到欢迎

推荐答案

Simon Mourier的回答是99%正确,并且使用常规API肯定可以,但是似乎该特定API并不遵循常规规则" ",无论可能是什么;).因此,我需要修改几件事,这对我有用:

Simon Mourier's answer is 99% correct, and with normal APIs it would have definitely worked, but it appears as if this particular API doesn't follow "normal rules", whatever that might be ;). As such, I needed to modify a couple things and this is what worked for me:

const int ERROR_INSUFFICIENT_BUFFER = 122;
const int ERROR_MORE_DATA = 234;

var volume = "C:";
var fileName = string.Empty;
var size = 0;

while (true)
{
    var ptr = Marshal.AllocHGlobal(size); // FbwfFindFirst fails if given IntPtr.Zero - regardless of what the value of size is.

    try
    {
        var result = FbwfFindFirst(volume, ptr, ref size);

        // Despite documentation saying otherwise, it can return either of these
        if (result == ERROR_MORE_DATA || result == ERROR_INSUFFICIENT_BUFFER)
        {
            continue;
        }

        if (result != 0)
        {
            throw new Exception($"Failed with {result}");
        }

        // get the easy part 
        var detail = (FbwfCacheDetail) Marshal.PtrToStructure(ptr, typeof(FbwfCacheDetail));

        // compute filename offset and get the string
        // file name length is in bytes, per documentation
        fileName = Marshal.PtrToStringUni(ptr + Marshal.OffsetOf(typeof(FbwfCacheDetail), "fileName").ToInt32(), detail.fileNameLength / 2);
        break;
    }
    finally
    {
        Marshal.FreeHGlobal(ptr);
    }
}

编辑

忘记说FbwfFindFirst的拼音需要如下,否则它将返回ERROR_INVALID_PARAMETER:

Forgot to say that the pinvoke for FbwfFindFirst needs to be as follows, else it will return ERROR_INVALID_PARAMETER:

[DllImport("fbwflib.dll")]
public static extern uint FbwfFindFirst(
    [MarshalAs(UnmanagedType.LPWStr)]    
    string volume,
    IntPtr cacheDetail,
    ref int size
);

这篇关于PInvoke FbwfFindFirst-FbwfCacheDetail问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-31 19:52