/// <summary> /// AddProgramsInDirectory - Recursive function to search /// into directory tree. /// </summary> /// <param name="strDir">Starting directory</param> /// <returns></returns> private bool AddProgramsInDirectory(string strDir) { Trace.WriteLine("FindPrograms: " + "AddProgramsInDirectory (" + strDir + ")"); // Update status bar through delegate function. strBuffer = "Searching in " + strDir + "..."; itReason = INVOKE_FINDFILES.STATUS_MESSAGE; m_ctlInvokeTarget.Invoke(m_deleCallback); // As we add programs, store directory names. ArrayList alDirectories = new ArrayList(); // Start our search. string strSearch = strDir + "*.*"; IntPtr pfdAllFiles = IntPtr.Zero; // Return pointer. int cFound = 0; // Return count of files. // Call looking for all files in current directory. Rapi.CeFindAllFiles(strSearch, Rapi.FAF.FAF_ATTRIBUTES | Rapi.FAF.FAF_NAME, ref cFound, ref pfdAllFiles); // Loop through all files found. IntPtr pfd = pfdAllFiles; while (cFound > 0) { // // Here is the secret sauce. This function uses a // Win32 pointer to create a .NET object // Rapi.CE_FIND_DATA fd = // Output .NET object (Rapi.CE_FIND_DATA) // Always cast this Marshal.PtrToStructure( // The function pfd, // Input Win32 ptr typeof(Rapi.CE_FIND_DATA)); // Output type string strFileName = fd.cFileName; int iFlag = (int) Rapi.FILE_ATTRIBUTE.FILE_ATTRIBUTE_DIRECTORY; if ((fd.dwFileAttributes & iFlag) == iFlag) { alDirectories.Add(strDir + fd.cFileName); } else { if (strFileName.EndsWith(".EXE") || strFileName.EndsWith(".exe")) { m_cFiles++; strBuffer = strDir + fd.cFileName; itReason = INVOKE_FINDFILES.FINDFILE_NEWFILE; m_ctlInvokeTarget.Invoke(m_deleCallback); } } // Get ready for next loop. pfd = (IntPtr)((int)pfd + Marshal.SizeOf(fd)); cFound--; } // Free memory returned by CeFindAllFiles. Rapi.CeRapiFreeBuffer(pfdAllFiles); if (bThreadContinue && m_bIncludeSubDirs) { foreach (string str in alDirectories) { AddProgramsInDirectory(str + "\\"); } } return(true); }