/// <summary> /// Resolves all wild card specifications if any. /// <para> /// This method is called by <see cref="Compiler" /> during the compilation. However it might be convenient /// to call it before the compilation if any files matching the wild card mask need to be handled in special /// way (e.g. shortcuts created). See <c>WildCard Files</c> example. /// </para><remarks><see cref="ResolveWildCards" /> should be called only after <see cref="T:WixSharp.WixProject.SourceBaseDir" /> is set. /// Otherwise wild card paths may not be resolved correctly.</remarks> /// </summary> /// <param name="ignoreEmptyDirectories">if set to <c>true</c> empty directories are ignored and not added to the project.</param> /// <returns></returns> public Project ResolveWildCards(bool ignoreEmptyDirectories = false) { int iterator = 0; var dirList = new List <Dir>(); var fileList = new List <File>(); dirList.AddRange(Dirs); while (iterator < dirList.Count) { foreach (Files dirItems in dirList[iterator].FileCollections) { foreach (WixEntity item in dirItems.GetAllItems(SourceBaseDir, dirList[iterator])) { if (item is DirFiles) { dirList[iterator].AddDirFileCollection(item as DirFiles); } else if (item is Dir discoveredDir && !dirList[iterator].Dirs.Contains(item)) { WildCardDedup?.Invoke(discoveredDir); dirList[iterator].AddDir(discoveredDir); } } } foreach (Dir dir in dirList[iterator].Dirs) { dirList.Add(dir); } foreach (DirFiles coll in dirList[iterator].DirFileCollections) { dirList[iterator].Files = dirList[iterator].Files.Combine(coll.GetFiles(SourceBaseDir)); } //clear resolved collections dirList[iterator].FileCollections = new Files[0]; dirList[iterator].DirFileCollections = new DirFiles[0]; iterator++; } if (ignoreEmptyDirectories) { var emptyDirs = AllDirs.Where(d => !d.Files.Any() && !d.Dirs.Any()); emptyDirs.ForEach(emptyDir => AllDirs.ForEach(d => { if (d.Dirs.Contains(emptyDir)) { d.Dirs = d.Dirs.Where(x => x != emptyDir).ToArray(); } })); } return(this); }
/// <summary> /// Processes all files/dirs in the top level target directory. /// </summary> /// <returns> /// Success/Failure. /// </returns> /// <param name="path">An existing file system directory.</param> public bool GetFileSystemSnapshot(string path) { List <String> directoryList = new List <String>(); WIN32_FIND_DATAW findData; IntPtr findHandle = INVALID_HANDLE_VALUE; try { path = path.EndsWith(@"\") ? path : path + @"\"; findHandle = FindFirstFileW(path + @"*", out findData); if (findHandle != INVALID_HANDLE_VALUE) { do { // Skip current directory (.) and parent directory (..) symbols if (findData.cFileName != "." && findData.cFileName != "..") { string fullPath = path + findData.cFileName; // Check if this is a directory and not a symbolic link since symbolic links // could lead to repeated files and folders as well as infinite loops bool isDirectory = findData.dwFileAttributes.HasFlag(FileAttributes.Directory); bool isSymbolicLink = findData.dwFileAttributes.HasFlag(FileAttributes.ReparsePoint); if (isDirectory && !isSymbolicLink) { // Process directory //string fullPath = path + findData.cFileName; directoryList.Add(fullPath); // Query file system entry, populate and append to dict FileInformation directoryInformation = PopulateFileInformation(findData, path); AllDirs.TryAdd(directoryInformation.FullPath, directoryInformation); AllFSEntries.TryAdd(directoryInformation.FullPath, directoryInformation); // Increase directory count Interlocked.Increment(ref DirCounter); Console.Write("\rDirs: {0} Files: {1}", DirCounter, FileCounter); } else if (!isDirectory) { // Process file FileInformation fileInformation = PopulateFileInformation(findData, path); AllFiles.TryAdd(fileInformation.FullPath, fileInformation); AllFSEntries.TryAdd(fileInformation.FullPath, fileInformation); // Increase file count Interlocked.Increment(ref FileCounter); Console.Write("\rDirs: {0} Files: {1}", DirCounter, FileCounter); } } } // Process any subdirectories while (FindNextFile(findHandle, out findData)); directoryList.AsParallel().ForAll(x => { if (FindNextFileRecursive(x)) { } }); } } catch (Exception exception) { Console.WriteLine("Caught exception while trying to enumerate a directory..."); Console.WriteLine(exception.ToString()); if (findHandle != INVALID_HANDLE_VALUE) { FindClose(findHandle); } return(false); } if (findHandle != INVALID_HANDLE_VALUE) { FindClose(findHandle); } return(true); }
/// <summary> /// Recursively processes subdirectories and the contained files. /// </summary> /// <returns> /// Success/Failure. /// </returns> /// <param name="path">An existing file system directory.</param> /// <param name="files">List of files to process.</param> /// <param name="directories">List of directories to process.</param> private bool FindNextFileRecursive(string path) { List <String> directoryList = new List <String>(); WIN32_FIND_DATAW findData; IntPtr findHandle = INVALID_HANDLE_VALUE; try { findHandle = FindFirstFileW(path + @"\*", out findData); if (findHandle != INVALID_HANDLE_VALUE) { do { // Skip current directory (.) and parent directory (..) symbols if (findData.cFileName != "." && findData.cFileName != "..") { string fullPath = path + @"\" + findData.cFileName; // Check if this is a directory and not a symbolic link since symbolic links // could lead to repeated files and folders as well as infinite loops. bool isDirectory = findData.dwFileAttributes.HasFlag(FileAttributes.Directory); bool isSymbolicLink = findData.dwFileAttributes.HasFlag(FileAttributes.ReparsePoint); if (isDirectory && !isSymbolicLink) { // Add the directory to the list directoryList.Add(fullPath); FileInformation directoryInformation = PopulateFileInformation(findData, path); AllDirs.TryAdd(directoryInformation.FullPath, directoryInformation); AllFSEntries.TryAdd(directoryInformation.FullPath, directoryInformation); // Increase directory count Interlocked.Increment(ref DirCounter); Console.Write("\rDirs: {0} Files: {1}", DirCounter, FileCounter); if (FindNextFileRecursive(fullPath)) { } } else if (!isDirectory) { // Add the file to the list FileInformation fileInformation = PopulateFileInformation(findData, path); AllFiles.TryAdd(fileInformation.FullPath, fileInformation); AllFSEntries.TryAdd(fileInformation.FullPath, fileInformation); // Increase file count Interlocked.Increment(ref FileCounter); Console.Write("\rDirs: {0} Files: {1}", DirCounter, FileCounter); } } }while (FindNextFile(findHandle, out findData)); } } catch (Exception exception) { Console.WriteLine("Caught exception while trying to enumerate a directory..."); Console.WriteLine(exception.ToString()); if (findHandle != INVALID_HANDLE_VALUE) { FindClose(findHandle); } return(false); } if (findHandle != INVALID_HANDLE_VALUE) { FindClose(findHandle); } return(true); }