그물에있는 모든 샘플 코드는 열거 인터페이스 Next()
호출의 첫 번째 인수로 1을 전달하는 습관에 의문을 제기하지 않습니다. 그러나 문서에서는 하나의 호출에서 하나 이상의 항목을 얻을 수 있다고 분명히 약속합니다. 이 코드 조각에서 볼 수 있듯이 이렇게하면 폴더의 파일 계산 프로세스가 상당히 빨라집니다 (실제로는 근본적으로 비슷한 WPD 인터페이스가 그렇게 작동합니다).다음> 1로 쉘을 열거하십시오.
string FolderPath = @"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\<Phone-USB-ID>\Internal storage\Pictures\Test";
SHCreateItemFromParsingName(FolderPath, IntPtr.Zero, typeof(IShellItem).GUID, out IShellItem item);
item.BindToHandler(IntPtr.Zero, BHID_SFObject, typeof(IShellFolder).GUID, out IShellFolder folder);
folder.EnumObjects(IntPtr.Zero, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, out IEnumIDList list);
uint count = 0;
try {
do {
//var ObjectIDs = new ObjectIDLargeArray();
//var pidl = Marshal.AllocHGlobal(Marshal.SizeOf(ObjectIDs));
//Marshal.StructureToPtr(ObjectIDs, pidl, true);
//var pidl = Marshal.AllocCoTaskMem(100 * IntPtr.Size);
int hr = list.Next(100, out var pidl, out uint fetched); // <<<<<
if (hr == 0)
count += fetched;
if (fetched == 0)
break;
//Marshal.FreeHGlobal(pidl);
Marshal.FreeCoTaskMem(pidl);
}
while (true);
}
catch (Exception e) {
Console.WriteLine(e);
}
[StructLayout(LayoutKind.Sequential)]
internal class ObjectIDLargeArray {
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
public IntPtr[] IDs;
}
문서 및 웹에서 사용이 호출자가 반환 된 ID에 대한 버퍼를 할당 할 수 있지만, 코드에서 볼 수 있듯이이 있는지 여부에 대해 완전히 명확하지 않다, 나는 모든 방법 모두 특정 배열을 시도 및 할당 된 메모리 블록을 포함한다. 2와 3과 같은 매우 작은 값의 경우 쉘은 fetched
에 쓰레기를 반환 할 수 있습니다. 더 큰 경우에는 액세스 위반 예외입니다.
중요성의 관점에서 말하자면, 새로 연결된 전화로 이전의 캐싱이 없었기 때문에 500 장의 사진 폴더에있는 파일 수를 계산하는 데 약 15 초 밖에 걸리지 않았습니다. 두 번째는 이미 3에서 4까지 캐시 된 데이터입니다. 말할 필요도없이 두 번째 파일도 단순한 파일 수에는 용납되지 않지만 15 초는 절대 바보입니다. WPD의 평범하지 않은 속도이지만 100 단계 카운트, 최대 100ms. 새로운 C# 7.2 기능
질문에 대한 답을 모르겠지만 기능에 'out'매개 변수로 전달되는 로컬 변수에 아무 것도 지정하지 않아도됩니다. –
음, khhm, 너 어디서 그런거야? -- 바로 이거 야. 당신의 경우, pidl이 미리 정의되어 있다면 거기에는 유형이 없습니다. 그래서 MSDN 문서가 완벽하다는 것을 절대적으로 확실하게 확신 할 수 없다고 말한 것입니다. –
doc에서는 celt 요소의 배열을 할당해야하지만 배열 만 할당해야한다고 명시되어 있습니다. 배열의 항목은 null 일 수도 있고 아닐 수도 있지만 반환 할 때 할당되거나 할당되지 않습니다. 따라서 가져온 문자열을 반복하여 하나씩 해제해야합니다. 또한, 인터페이스 구현자가 celt> 1을 지원할지라도 그것이 반드시해야한다는 것을 의미하지는 않는다. 그렇지 않으면, 당신은 10을 요구할 것이고, 1을 가져 오거나 (또는 0) –