private bool isPackageFilesInUse(string tapDir, List <string> packagePaths, Func <string, bool> exclude = null) { foreach (string packageFileName in packagePaths) { foreach (string file in PluginInstaller.FilesInPackage(packageFileName)) { string fullPath = Path.Combine(tapDir, file); string filename = Path.GetFileName(file); if (exclude != null && exclude(filename)) { continue; } if (IsFileLocked(new FileInfo(fullPath))) { return(true); } } } return(false); }
private void waitForPackageFilesFree(string tapDir, List <string> PackagePaths) { // ignore tap.exe as it is not meant to be overwritten. bool exclude(string filename) => filename.ToLower() == "tap" || filename.ToLower() == "tap.exe"; List <FileInfo> filesInUse = new List <FileInfo>(); foreach (string packageFileName in PackagePaths) { foreach (string file in PluginInstaller.FilesInPackage(packageFileName)) { string fullPath = Path.Combine(tapDir, file); string filename = Path.GetFileName(file); if (exclude(filename)) { continue; } if (IsFileLocked(new FileInfo(fullPath))) { filesInUse.Add(new FileInfo(fullPath)); } } } // Check if the files that are in use are used by any other package var packages = PackagePaths.Select(p => p.EndsWith("TapPackage") ? PackageDef.FromPackage(p) : PackageDef.FromXml(p)); var remainingInstalledPlugins = new Installation(tapDir).GetPackages().Where(i => packages.Any(p => p.Name == i.Name) == false); var filesToRemain = remainingInstalledPlugins.SelectMany(p => p.Files).Select(f => f.RelativeDestinationPath).Distinct(StringComparer.InvariantCultureIgnoreCase); filesInUse = filesInUse.Where(f => filesToRemain.Contains(f.Name, StringComparer.InvariantCultureIgnoreCase) == false).ToList(); if (filesInUse.Count > 0) { log.Info("Following files cannot be modified because they are in use:"); foreach (var file in filesInUse) { log.Info("- " + file.FullName); var loaded_asm = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(x => x.IsDynamic == false && x.Location == file.FullName); if (loaded_asm != null) { throw new InvalidOperationException($"The file '{file.FullName}' is being used by this process."); } } var allProcesses = Process.GetProcesses().Where(p => p.ProcessName.ToLowerInvariant().Contains("opentap") && p.ProcessName.ToLowerInvariant().Contains("vshost") == false && p.ProcessName != Assembly.GetExecutingAssembly().GetName().Name).ToArray(); if (allProcesses.Any()) { // The file could be locked by someone other than OpenTAP processes. We should not assume it's OpenTAP holding the file. log.Warning(Environment.NewLine + "To continue, try closing applications that could be using the files."); foreach (var process in allProcesses) { log.Warning("- " + process.ProcessName); } } log.Warning(Environment.NewLine + "Waiting for files to become unlocked..."); while (isPackageFilesInUse(tapDir, PackagePaths, exclude)) { if (cancellationToken.IsCancellationRequested) { return; } if (!isTapRunning()) { OnError(new IOException("One or more plugin files are in use. View log for more information.")); } Thread.Sleep(300); } } }