/// <summary> /// Copy the entry from the opened zipfile to the path specified. /// </summary> internal static void CopyZipEntry(string absoluteDirectoryRoot, IInstallable file) { string absolutePath = Path.Combine(absoluteDirectoryRoot, file.Destination); if (file.IsDirectory) { // Skip if we're not making directories for this install. if (!file.makeDirs) { log.DebugFormat("Skipping {0}, we don't make directories for this path", absolutePath); return; } log.DebugFormat("Making directory {0}", absolutePath); file_transaction.CreateDirectory(absolutePath); } else { log.DebugFormat("Writing file {0}", absolutePath); // Sometimes there are zipfiles that don't contain entries for the // directories their files are in. No, I understand either, but // the result is we have to make sure our directories exist, just in case. if (file.makeDirs) { string directory = Path.GetDirectoryName(absolutePath); file_transaction.CreateDirectory(directory); } // We don't allow for the overwriting of files. See #208. if (File.Exists(absolutePath)) { throw new FileExistsKraken(absolutePath, string.Format("Trying to write {0} but it already exists.", absolutePath)); } // Snapshot whatever was there before. If there's nothing, this will just // remove our file on rollback. We still need this even thought we won't // overwite files, as it ensures deletiion on rollback. file_transaction.Snapshot(absolutePath); try { // It's a file! Prepare the streams using (Stream zipStream = file.stream) using (FileStream writer = File.Create(absolutePath)) { // 4k is the block size on practically every disk and OS. byte[] buffer = new byte[4096]; StreamUtils.Copy(zipStream, writer, buffer); } } catch (DirectoryNotFoundException ex) { throw new DirectoryNotFoundKraken("", ex.Message, ex); } } }
private void InnerInstall(ManifestModuleInfo module, IProgress <ProgressMessage> progress) { var dstModuleDir = Path.Combine(_modulesPath, module.Id); var moduleZipPath = Path.Combine(dstModuleDir, GetModuleZipFileName(module.Id, module.Version.ToString())); if (!Directory.Exists(dstModuleDir)) { _txFileManager.CreateDirectory(dstModuleDir); } //download module archive from web if (Uri.IsWellFormedUriString(module.Ref, UriKind.Absolute)) { var moduleUrl = new Uri(module.Ref); using (var webClient = new WebClient()) { webClient.AddAuthorizationTokenForGitHub(moduleUrl); using (var fileStream = File.OpenWrite(moduleZipPath)) using (var webStream = webClient.OpenRead(moduleUrl)) { Report(progress, ProgressMessageLevel.Info, "Downloading '{0}' ", module.Ref); webStream.CopyTo(fileStream); } } } else if (File.Exists(module.Ref)) { moduleZipPath = module.Ref; } using (var zipStream = File.Open(moduleZipPath, FileMode.Open)) using (var archive = new ZipArchive(zipStream, ZipArchiveMode.Read)) { foreach (var entry in archive.Entries.Where(e => !string.IsNullOrEmpty(e.Name))) { //Report(progress, ProgressMessageLevel.Info, "Extracting '{0}' ", entry.FullName); var filePath = Path.Combine(dstModuleDir, entry.FullName); //Create directory if not exist var directoryPath = Path.GetDirectoryName(filePath); if (!_txFileManager.DirectoryExists(directoryPath)) { _txFileManager.CreateDirectory(directoryPath); } using (var entryStream = entry.Open()) using (var fileStream = File.Create(filePath)) { entryStream.CopyTo(fileStream); } File.SetLastWriteTime(filePath, entry.LastWriteTime.LocalDateTime); } } Report(progress, ProgressMessageLevel.Info, "Successfully installed '{0}'.", module); }
private static void _CopyDirectory(string sourceDirPath, string destDirPath, bool copySubDirs, TxFileManager file_transaction) { DirectoryInfo sourceDir = new DirectoryInfo(sourceDirPath); if (!sourceDir.Exists) { throw new DirectoryNotFoundKraken( sourceDirPath, "Source directory does not exist or could not be found."); } // If the destination directory doesn't exist, create it. if (!Directory.Exists(destDirPath)) { file_transaction.CreateDirectory(destDirPath); } else if (Directory.GetDirectories(destDirPath).Length != 0 || Directory.GetFiles(destDirPath).Length != 0) { throw new PathErrorKraken(destDirPath, "Directory not empty: "); } // Get the files in the directory and copy them to the new location. FileInfo[] files = sourceDir.GetFiles(); foreach (FileInfo file in files) { if (file.Name == "registry.locked") { continue; } else if (file.Name == "playtime.json") { continue; } string temppath = Path.Combine(destDirPath, file.Name); file_transaction.Copy(file.FullName, temppath, false); } // Create all first level subdirectories DirectoryInfo[] dirs = sourceDir.GetDirectories(); foreach (DirectoryInfo subdir in dirs) { string temppath = Path.Combine(destDirPath, subdir.Name); file_transaction.CreateDirectory(temppath); // If copying subdirectories, copy their contents to new location. if (copySubDirs) { _CopyDirectory(subdir.FullName, temppath, copySubDirs, file_transaction); } } }
/// <summary> /// Copy the entry from the opened zipfile to the path specified. /// </summary> internal static void CopyZipEntry(ZipFile zipfile, ZipEntry entry, string fullPath, bool makeDirs) { if (entry.IsDirectory) { // Skip if we're not making directories for this install. if (!makeDirs) { log.DebugFormat("Skipping {0}, we don't make directories for this path", fullPath); return; } log.DebugFormat("Making directory {0}", fullPath); file_transaction.CreateDirectory(fullPath); } else { log.DebugFormat("Writing file {0}", fullPath); // Sometimes there are zipfiles that don't contain entries for the // directories their files are in. No, I understand either, but // the result is we have to make sure our directories exist, just in case. if (makeDirs) { string directory = Path.GetDirectoryName(fullPath); file_transaction.CreateDirectory(directory); } // We don't allow for the overwriting of files. See #208. if (File.Exists(fullPath)) { throw new FileExistsKraken(fullPath, string.Format("Trying to write {0} but it already exists.", fullPath)); } // Snapshot whatever was there before. If there's nothing, this will just // remove our file on rollback. We still need this even thought we won't // overwite files, as it ensures deletiion on rollback. file_transaction.Snapshot(fullPath); // It's a file! Prepare the streams using (Stream zipStream = zipfile.GetInputStream(entry)) using (FileStream writer = File.Create(fullPath)) { // 4k is the block size on practically every disk and OS. byte[] buffer = new byte[4096]; StreamUtils.Copy(zipStream, writer, buffer); } } return; }
/// <summary> /// Create the CKAN directory and any supporting files. /// </summary> private void SetupCkanDirectories(bool scan = true) { log.InfoFormat("Initialising {0}", CkanDir()); // TxFileManager knows if we are in a transaction TxFileManager txFileMgr = new TxFileManager(); if (!Directory.Exists(CkanDir())) { User.RaiseMessage("Setting up CKAN for the first time..."); User.RaiseMessage("Creating {0}", CkanDir()); txFileMgr.CreateDirectory(CkanDir()); if (scan) { User.RaiseMessage("Scanning for installed mods..."); Scan(); } } playTime = TimeLog.Load(TimeLog.GetPath(CkanDir())) ?? new TimeLog(); if (!Directory.Exists(InstallHistoryDir())) { User.RaiseMessage("Creating {0}", InstallHistoryDir()); txFileMgr.CreateDirectory(InstallHistoryDir()); } // Clear any temporary files we find. If the directory // doesn't exist, then no sweat; FilesystemTransaction // will auto-create it as needed. // Create our temporary directories, or clear them if they // already exist. if (Directory.Exists(TempDir())) { var directory = new DirectoryInfo(TempDir()); foreach (FileInfo file in directory.GetFiles()) { txFileMgr.Delete(file.FullName); } foreach (DirectoryInfo subDirectory in directory.GetDirectories()) { txFileMgr.DeleteDirectory(subDirectory.FullName); } } log.InfoFormat("Initialised {0}", CkanDir()); }
public bool MoveFile(string fileInWCard, string fileOutPath) { if (isFileMoved == true) { return(true); } archiveFileName = ""; try { string filePath = GetFile(fileInWCard); if (!string.IsNullOrEmpty(filePath)) { TxFileManager fileMgr = new TxFileManager(); using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions() { IsolationLevel = IsolationLevel.ReadCommitted })) { String fileName = System.IO.Path.GetFileName(filePath); DateTime myDateTime = DateTime.Now; archiveFileName = System.IO.Path.Combine(new string[] { fileOutPath, myDateTime.Year.ToString("0000"), myDateTime.Month.ToString("00"), myDateTime.Day.ToString("00"), fileName }); try { //Create the dir fileMgr.CreateDirectory(System.IO.Path.GetDirectoryName(archiveFileName)); //Move file to archive fileMgr.Move(filePath, archiveFileName); } catch (System.IO.FileNotFoundException ex) { numOfRetried++; SolutionTraceClass.WriteLineInfo(String.Format("'Credit' File ({1}) could not be moved. Exception. Message was->{0}", ex.Message, fileName)); LoggingHelper.LogErrorActivity(String.Format("'Credit' File ({0}) could not be moved.", fileName), ex); archiveFileName = ""; } catch (Exception ex) { numOfRetried++; SolutionTraceClass.WriteLineWarning(String.Format("'Credit' File ({1}) could not be moved. Exception. Message was->{0}", ex.Message, fileName)); LoggingHelper.LogErrorActivity(String.Format("'Credit' File ({0}) could not be moved.", fileName), ex); archiveFileName = ""; } scope.Complete(); isFileMoved = true; } } } catch (Exception ex) { SolutionTraceClass.WriteLineError(String.Format("'Credit' Exception. Message was->{0}", ex.Message)); LoggingHelper.LogErrorActivity(ex); SolutionTraceClass.WriteLineVerbose("End"); return(false); } SolutionTraceClass.WriteLineVerbose("End"); return(!string.IsNullOrEmpty(archiveFileName)); }
/// <summary> /// Copies the source to the destination. /// </summary> /// <remarks> /// If the source is a directory, it is copied recursively. /// </remarks> /// <param name="p_tfmFileManager">The transactional file manager to use to copy the files.</param> /// <param name="p_strSource">The path from which to copy.</param> /// <param name="p_strDestination">The path to which to copy.</param> /// <param name="p_fncCopyCallback"> /// A callback method that notifies the caller when a file has been copied, /// and provides the opportunity to cancel the copy operation. /// </param> /// <returns><lang langref="true" /> if the copy operation wasn't cancelled; <lang langref="false" /> otherwise.</returns> public static bool Copy(TxFileManager p_tfmFileManager, string p_strSource, string p_strDestination, Func <string, bool> p_fncCopyCallback) { if (File.Exists(p_strSource)) { if (!Directory.Exists(Path.GetDirectoryName(p_strDestination))) { p_tfmFileManager.CreateDirectory(Path.GetDirectoryName(p_strDestination)); } p_tfmFileManager.Copy(p_strSource, p_strDestination, true); if ((p_fncCopyCallback != null) && p_fncCopyCallback(p_strSource)) { return(false); } } else if (Directory.Exists(p_strSource)) { if (!Directory.Exists(p_strDestination)) { p_tfmFileManager.CreateDirectory(p_strDestination); } var strFiles = Directory.GetFiles(p_strSource); foreach (var strFile in strFiles) { p_tfmFileManager.Copy(strFile, Path.Combine(p_strDestination, Path.GetFileName(strFile)), true); if ((p_fncCopyCallback != null) && p_fncCopyCallback(strFile)) { return(false); } } var strDirectories = Directory.GetDirectories(p_strSource); foreach (var strDirectory in strDirectories) { if (!Copy(strDirectory, Path.Combine(p_strDestination, Path.GetFileName(strDirectory)), p_fncCopyCallback)) { return(false); } } } return(true); }
/// <summary> /// Create a new fake KSP instance /// </summary> /// <param name="game">The game of the new instance.</param> /// <param name="newName">The name for the new instance.</param> /// <param name="newPath">The location of the new instance.</param> /// <param name="version">The version of the new instance. Should have a build number.</param> /// <param name="dlcs">The IDlcDetector implementations for the DLCs that should be faked and the requested dlc version as a dictionary.</param> /// <exception cref="InstanceNameTakenKraken">Thrown if the instance name is already in use.</exception> /// <exception cref="NotKSPDirKraken">Thrown by AddInstance() if created instance is not valid, e.g. if a write operation didn't complete for whatever reason.</exception> public void FakeInstance(IGame game, string newName, string newPath, GameVersion version, Dictionary <DLC.IDlcDetector, GameVersion> dlcs = null) { TxFileManager fileMgr = new TxFileManager(); using (TransactionScope transaction = CkanTransaction.CreateTransactionScope()) { if (HasInstance(newName)) { throw new InstanceNameTakenKraken(newName); } if (!version.InBuildMap(game)) { throw new BadGameVersionKraken(String.Format("The specified KSP version is not a known version: {0}", version.ToString())); } if (Directory.Exists(newPath) && (Directory.GetFiles(newPath).Length != 0 || Directory.GetDirectories(newPath).Length != 0)) { throw new BadInstallLocationKraken("The specified folder already exists and is not empty."); } log.DebugFormat("Creating folder structure and text files at {0} for KSP version {1}", Path.GetFullPath(newPath), version.ToString()); // Create a KSP root directory, containing a GameData folder, a buildID.txt/buildID64.txt and a readme.txt fileMgr.CreateDirectory(newPath); fileMgr.CreateDirectory(Path.Combine(newPath, "GameData")); fileMgr.CreateDirectory(Path.Combine(newPath, "Ships")); fileMgr.CreateDirectory(Path.Combine(newPath, "Ships", "VAB")); fileMgr.CreateDirectory(Path.Combine(newPath, "Ships", "SPH")); fileMgr.CreateDirectory(Path.Combine(newPath, "Ships", "@thumbs")); fileMgr.CreateDirectory(Path.Combine(newPath, "Ships", "@thumbs", "VAB")); fileMgr.CreateDirectory(Path.Combine(newPath, "Ships", "@thumbs", "SPH")); fileMgr.CreateDirectory(Path.Combine(newPath, "saves")); fileMgr.CreateDirectory(Path.Combine(newPath, "saves", "scenarios")); fileMgr.CreateDirectory(Path.Combine(newPath, "saves", "training")); // Don't write the buildID.txts if we have no build, otherwise it would be -1. if (version.IsBuildDefined) { fileMgr.WriteAllText(Path.Combine(newPath, "buildID.txt"), String.Format("build id = {0}", version.Build)); fileMgr.WriteAllText(Path.Combine(newPath, "buildID64.txt"), String.Format("build id = {0}", version.Build)); } // Create the readme.txt WITHOUT build number. fileMgr.WriteAllText(Path.Combine(newPath, "readme.txt"), String.Format("Version {0}", new GameVersion(version.Major, version.Minor, version.Patch).ToString())); // Create the needed folder structure and the readme.txt for DLCs that should be simulated. if (dlcs != null) { foreach (KeyValuePair <DLC.IDlcDetector, GameVersion> dlc in dlcs) { DLC.IDlcDetector dlcDetector = dlc.Key; GameVersion dlcVersion = dlc.Value; if (!dlcDetector.AllowedOnBaseVersion(version)) { throw new WrongGameVersionKraken( version, String.Format("KSP version {0} or above is needed for {1} DLC.", dlcDetector.ReleaseGameVersion, dlcDetector.IdentifierBaseName )); } string dlcDir = Path.Combine(newPath, dlcDetector.InstallPath()); fileMgr.CreateDirectory(dlcDir); fileMgr.WriteAllText( Path.Combine(dlcDir, "readme.txt"), String.Format("Version {0}", dlcVersion)); } } // Add the new instance to the config GameInstance new_instance = new GameInstance(game, newPath, newName, User, false); AddInstance(new_instance); transaction.Complete(); } }
static void RunStressTest() { Stopwatch sw = new Stopwatch(); sw.Start(); { // Pre-test checks string tempDir; IFileManager fm = new TxFileManager(); using (TransactionScope s1 = new TransactionScope()) { tempDir = (new DirectoryInfo(fm.CreateTempDirectory())).Parent.FullName; Console.WriteLine("Temp path: " + tempDir); } string[] directories = Directory.GetDirectories(tempDir); string[] files = Directory.GetFiles(tempDir); if (directories.Length > 0 || files.Length > 0) { Console.WriteLine(string.Format("ERROR Please ensure temp path {0} has no children before running this test.", tempDir)); return; } } // Start each test in its own thread and repeat for a few interations const int numThreads = 10; const int iterations = 250; const string text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."; long count = 0; IList <Thread> threads = new List <Thread>(); for (int i = 0; i < numThreads; i++) { Thread t = new Thread(() => { IFileManager fm = new TxFileManager(); for (int j = 0; j < iterations; j++) { using (TransactionScope s1 = new TransactionScope()) { TransactionOptions to = new TransactionOptions(); to.Timeout = TimeSpan.FromMinutes(30); long myCount = Interlocked.Increment(ref count); if (myCount % 250 == 0) { Console.WriteLine(myCount + " (" + myCount * 100 / (numThreads * iterations) + " %)"); } string f1 = fm.CreateTempFileName(); string f2 = fm.CreateTempFileName(); string d1 = fm.CreateTempDirectory(); if (i % 100 == 0) { Console.WriteLine(i); } fm.AppendAllText(f1, text); fm.Copy(f1, f2, false); fm.CreateDirectory(d1); fm.Delete(f2); fm.DeleteDirectory(d1); bool b1 = fm.DirectoryExists(d1); bool b2 = fm.FileExists(f1); string f3 = fm.CreateTempFileName(); fm.Move(f1, f3); string f4 = fm.CreateTempFileName(); fm.Snapshot(f4); fm.WriteAllBytes(f4, new byte[] { 64, 65 }); string f5 = fm.CreateTempFileName(); fm.WriteAllText(f5, text); fm.Delete(f1); fm.Delete(f2); fm.Delete(f3); fm.Delete(f4); fm.Delete(f5); fm.DeleteDirectory(d1); s1.Complete(); } } }); threads.Add(t); } foreach (Thread t in threads) { t.Start(); } Console.WriteLine("All threads started."); foreach (Thread t in threads) { t.Join(); } sw.Stop(); Console.WriteLine("All threads joined. Elapsed: {0}.", sw.ElapsedMilliseconds); }
// Moves files from AppData to current folder and vice versa // This is based off of the array below // Index 0 = Current Path // Index 1 = Default Path // Mode 0 = Current path -> Default Path (Turning off) // Mode 1 = Default path -> Current Path (Turning on) private void portibleModeToggle(int mode) { String[,] folderArray = new string[, ] { { Path.Combine(Paths.exeFolder, "config"), Paths.defaultConfigPath }, { Path.Combine(Paths.exeFolder, "Shortcuts"), Paths.defaultShortcutsPath } }; String[,] fileArray = new string[, ] { { Path.Combine(Paths.exeFolder, "Taskbar Groups Background.exe"), Paths.defaultBackgroundPath }, { Path.Combine(Paths.exeFolder, "Settings.xml"), Settings.defaultSettingsPath } }; int int1; int int2; if (mode == 0) { int1 = 0; int2 = 1; } else { int1 = 1; int2 = 0; } try { // Kill off the background process Process[] pname = Process.GetProcessesByName(Path.GetFileNameWithoutExtension("Taskbar Groups Background")); if (pname.Length != 0) { pname[0].Kill(); } IFileManager fm = new TxFileManager(); using (TransactionScope scope1 = new TransactionScope()) { Settings.settingInfo.portableMode = true; Settings.writeXML(); for (int i = 0; i < folderArray.Length / 2; i++) { if (fm.DirectoryExists(folderArray[i, int1])) { // Need to use another method to move from one partition to another Microsoft.VisualBasic.FileIO.FileSystem.MoveDirectory(folderArray[i, int1], folderArray[i, int2]); // Folders may still reside after being moved if (fm.DirectoryExists(folderArray[i, int1]) && !Directory.EnumerateFileSystemEntries(folderArray[i, int1]).Any()) { fm.DeleteDirectory(folderArray[i, int1]); } } else { fm.CreateDirectory(folderArray[i, int2]); } } for (int i = 0; i < fileArray.Length / 2; i++) { if (fm.FileExists(fileArray[i, int1])) { fm.Move(fileArray[i, int1], fileArray[i, int2]); } } if (mode == 0) { Paths.ConfigPath = Paths.defaultConfigPath; Paths.ShortcutsPath = Paths.defaultShortcutsPath; Paths.BackgroundApplication = Paths.defaultBackgroundPath; Settings.settingsPath = Settings.defaultSettingsPath; portabilityButton.Tag = "n"; portabilityButton.Image = Properties.Resources.toggleOff; } else { Paths.ConfigPath = folderArray[0, 0]; Paths.ShortcutsPath = folderArray[1, 0]; Paths.BackgroundApplication = fileArray[0, 0]; Settings.settingsPath = fileArray[1, 0]; portabilityButton.Tag = "y"; portabilityButton.Image = Properties.Resources.toggleOn; } changeAllShortcuts(); scope1.Complete(); MessageBox.Show("File moving done!"); } } catch (IOException e) { MessageBox.Show("The application does not have access to this directory!\r\n\r\nError: " + e.Message); } }