/// <summary>Convert the relative path name to the absolute path name on disk.</summary> /// <param name="relPath">The relative path to the file (using wyBuild lingo).</param> /// <returns>The absolute path name.</returns> string FixUpdateDetailsPaths(string relPath) { if (relPath.Length < 4) { return(null); } switch (relPath.Substring(0, 4)) { case "base": return(Path.Combine(ProgramDirectory, relPath.Substring(5))); case "syst": //system (32-bit) return(Path.Combine(SystemFolders.GetSystem32x86(), relPath.Substring(7))); case "64sy": //64system (64-bit) return(Path.Combine(SystemFolders.GetSystem32x64(), relPath.Substring(9))); case "temp": return(Path.Combine(TempDirectory, relPath)); case "appd": //appdata return(Path.Combine(SystemFolders.GetCurrentUserAppData(), relPath.Substring(8))); case "lapp": //lappdata return(Path.Combine(SystemFolders.GetCurrentUserLocalAppData(), relPath.Substring(9))); case "coma": //comappdata return(Path.Combine(SystemFolders.GetCommonAppData(), relPath.Substring(11))); case "comd": //comdesktop return(Path.Combine(SystemFolders.GetCommonDesktop(), relPath.Substring(11))); case "coms": //comstartmenu return(Path.Combine(SystemFolders.GetCommonProgramsStartMenu(), relPath.Substring(13))); case "root": //root windows (e.g. C:\) return(Path.Combine(SystemFolders.GetRootDrive(), relPath.Substring(5))); case "cp86": //cp86 == common program files (x86) return(Path.Combine(SystemFolders.GetCommonProgramFilesx86(), relPath.Substring(5))); case "cp64": //cp64 == common program files (x64) return(Path.Combine(SystemFolders.GetCommonProgramFilesx64(), relPath.Substring(5))); case "curd": // curdesk = current user's desktop return(Path.Combine(SystemFolders.GetCurrentUserDesktop(), relPath.Substring(8))); case "curs": // curstart = current user's start menu return(Path.Combine(SystemFolders.GetCurrentUserProgramsStartMenu(), relPath.Substring(9))); } return(null); }
/// <summary>Gets or creates the cache folder for a GUID.</summary> /// <param name="guid">The GUID.</param> /// <returns>The directory to the cache folder</returns> static string GetCacheFolder(string guid) { string userprofile = SystemFolders.GetUserProfile(); // if getting the userprofile folder fails, then try the app data folder if (string.IsNullOrEmpty(userprofile)) { userprofile = SystemFolders.GetCurrentUserAppData(); } if (string.IsNullOrEmpty(userprofile)) { throw new Exception("Failed to retrieve the user profile folder."); } // C:\Users\USERNAME\wc string temp = Path.Combine(userprofile, "wc"); // if the folder temp folder doesn't exist, create the folder with hidden attributes if (!Directory.Exists(temp)) { Directory.CreateDirectory(temp); File.SetAttributes(temp, FileAttributes.System | FileAttributes.Hidden); } string fullGuidFolder = Path.Combine(temp, guid); // Workaround for the "pyramid of death" bug. // Note: This still doesn't address the root cause of the "pyramid of death" // namely, why aren't the folders being cleaned up on the failure of wyUpdate? // Perhaps it's a crashing bug. Further investigation is needed. We need to look into // possible causes for cached files being left around. This problem was first spotted // when a user's app crashed when they were debugging. It was crashing over and over again if (Directory.Exists(fullGuidFolder)) { string guidFile = Path.Combine(fullGuidFolder, guid); // if the GUID file doesn't already exist then the cache is busted. if (!File.Exists(guidFile)) { // delete every file and folder in the directory because it's an invalid cache string[] obs = Directory.GetDirectories(fullGuidFolder); // remove all directories foreach (var dir in obs) { Directory.Delete(dir, true); } obs = Directory.GetFiles(fullGuidFolder); // remove all the files foreach (var file in obs) { File.Delete(file); } // create the blank GUID file using (File.Create(guidFile)); } return(fullGuidFolder); } // try to create the smallest possible folder name (using the GUID) string closestMatch = null; string[] dirs = Directory.GetDirectories(temp); // loop through the directories - stop at the first partial match this GUID for (int i = 0; i < dirs.Length; i++) { string name = Path.GetFileName(dirs[i]); if (string.IsNullOrEmpty(name) || guid.IndexOf(name) != 0) { continue; } // see if the partial-matching folder contains an empty GUID file if (File.Exists(Path.Combine(dirs[i], guid))) { return(dirs[i]); } closestMatch = name; } // the folder doesn't exist, so we'll create it string guidCacheFolder = Path.Combine(temp, guid.Substring(0, closestMatch == null ? 1 : closestMatch.Length + 1)); Directory.CreateDirectory(guidCacheFolder); // create the blank GUID file using (File.Create(Path.Combine(guidCacheFolder, guid))); return(guidCacheFolder); }
public static void RollbackFiles(string m_TempDirectory, string m_ProgramDirectory) { string backupFolder = Path.Combine(m_TempDirectory, "backup"); // read in the list of files to delete List <string> fileList = new List <string>(), foldersToDelete = new List <string>(), foldersToCreate = new List <string>(); try { ReadRollbackFiles(Path.Combine(backupFolder, "fileList.bak"), fileList, foldersToDelete, foldersToCreate); } catch { return; } //delete the files foreach (string file in fileList) { try { File.SetAttributes(file, FileAttributes.Normal); File.Delete(file); } catch { } } //delete the folders foreach (string folder in foldersToDelete) { //TODO: test rolling back read-only / hidden folders try { Directory.Delete(folder, true); } catch { } } //create the folders foreach (string folder in foldersToCreate) { try { Directory.CreateDirectory(folder); } catch { } } //restore old versions string[] backupFolders = { Path.Combine(backupFolder, "base"), Path.Combine(backupFolder, "system"), Path.Combine(backupFolder, "64system"), Path.Combine(backupFolder, "root"), Path.Combine(backupFolder, "appdata"), Path.Combine(backupFolder, "lappdata"), Path.Combine(backupFolder, "comappdata"), Path.Combine(backupFolder, "comdesktop"), Path.Combine(backupFolder, "comstartmenu"), Path.Combine(backupFolder, "cp86"), Path.Combine(backupFolder, "cp64"), Path.Combine(backupFolder, "curdesk"), Path.Combine(backupFolder, "curstart") }; string[] destFolders = { m_ProgramDirectory, SystemFolders.GetSystem32x86(), SystemFolders.GetSystem32x64(), SystemFolders.GetRootDrive(), SystemFolders.GetCurrentUserAppData(), SystemFolders.GetCurrentUserLocalAppData(), SystemFolders.GetCommonAppData(), SystemFolders.GetCommonDesktop(), SystemFolders.GetCommonProgramsStartMenu(), SystemFolders.GetCommonProgramFilesx86(), SystemFolders.GetCommonProgramFilesx64(), SystemFolders.GetCurrentUserDesktop(), SystemFolders.GetCurrentUserProgramsStartMenu() }; for (int i = 0; i < backupFolders.Length; i++) { // only backup if the back-folder & dest-folder exists (i.e. the 64-bit system32 folder) if (Directory.Exists(backupFolders[i]) && destFolders[i] != null) { RestoreFiles(destFolders[i], backupFolders[i]); } } }
void bw_DoWorkUpdateFiles(object sender, DoWorkEventArgs e) { //check if folders exist, and count files to be moved string backupFolder = Path.Combine(TempDirectory, "backup"); string[] backupFolders = new string[13]; //Note: InstallShortcuts() requires the position in array to remain constant string[] origFolders = { "base", "system", "64system", "root", "appdata", "lappdata", "comappdata", "comdesktop", "comstartmenu", "cp86", "cp64", "curdesk", "curstart" }; string[] destFolders = { ProgramDirectory, SystemFolders.GetSystem32x86(), SystemFolders.GetSystem32x64(), SystemFolders.GetRootDrive(), SystemFolders.GetCurrentUserAppData(), SystemFolders.GetCurrentUserLocalAppData(), SystemFolders.GetCommonAppData(), SystemFolders.GetCommonDesktop(), SystemFolders.GetCommonProgramsStartMenu(), SystemFolders.GetCommonProgramFilesx86(), SystemFolders.GetCommonProgramFilesx64(), SystemFolders.GetCurrentUserDesktop(), SystemFolders.GetCurrentUserProgramsStartMenu() }; List <FileFolder> rollbackList = new List <FileFolder>(); int totalDone = 0; Exception except = null; try { int totalFiles = 0; // count the files and create backup folders for (int i = 0; i < origFolders.Length; i++) { // does orig folder exist? if (!Directory.Exists(Path.Combine(TempDirectory, origFolders[i]))) { continue; } //orig folder exists, set backup & orig folder locations backupFolders[i] = Path.Combine(backupFolder, origFolders[i]); origFolders[i] = Path.Combine(TempDirectory, origFolders[i]); Directory.CreateDirectory(backupFolders[i]); // delete "newer" client, if it will overwrite this client DeleteClientInPath(destFolders[i], origFolders[i]); // count the total files totalFiles += new DirectoryInfo(origFolders[i]).GetFiles("*", SearchOption.AllDirectories).Length; } //run the backup & replace for (int i = 0; i < origFolders.Length; i++) { if (IsCancelled()) { break; } if (backupFolders[i] != null) //if the backup folder exists { UpdateFiles(origFolders[i], destFolders[i], backupFolders[i], rollbackList, ref totalDone, ref totalFiles); } } DeleteFiles(backupFolder, rollbackList); InstallShortcuts(destFolders, backupFolder, rollbackList); } catch (Exception ex) { except = ex; } // write the list of newly created files and folders RollbackUpdate.WriteRollbackFiles(Path.Combine(backupFolder, "fileList.bak"), rollbackList); if (IsCancelled() || except != null) { // rollback files bw.ReportProgress(1, false); RollbackUpdate.RollbackFiles(TempDirectory, ProgramDirectory); // rollback unregged COM RollbackUpdate.RollbackUnregedCOM(TempDirectory); // rollback stopped services RollbackUpdate.RollbackStoppedServices(TempDirectory); bw.ReportProgress(0, new object[] { -1, -1, string.Empty, ProgressStatus.Failure, except }); } else { // backup & replace was successful bw.ReportProgress(0, new object[] { -1, -1, string.Empty, ProgressStatus.Success, null }); } }
public static void RollbackFiles(string m_TempDirectory, string m_ProgramDirectory) { string path = Path.Combine(m_TempDirectory, "backup"); List <string> list = new List <string>(); List <string> list2 = new List <string>(); List <string> list3 = new List <string>(); try { ReadRollbackFiles(Path.Combine(path, "fileList.bak"), list, list2, list3); } catch { return; } foreach (string item in list) { try { File.SetAttributes(item, FileAttributes.Normal); File.Delete(item); } catch { } } foreach (string item2 in list2) { try { Directory.Delete(item2, recursive: true); } catch { } } foreach (string item3 in list3) { try { Directory.CreateDirectory(item3); } catch { } } string[] array = new string[13] { Path.Combine(path, "base"), Path.Combine(path, "system"), Path.Combine(path, "64system"), Path.Combine(path, "root"), Path.Combine(path, "appdata"), Path.Combine(path, "lappdata"), Path.Combine(path, "comappdata"), Path.Combine(path, "comdesktop"), Path.Combine(path, "comstartmenu"), Path.Combine(path, "cp86"), Path.Combine(path, "cp64"), Path.Combine(path, "curdesk"), Path.Combine(path, "curstart") }; string[] array2 = new string[13] { m_ProgramDirectory, SystemFolders.GetSystem32x86(), SystemFolders.GetSystem32x64(), SystemFolders.GetRootDrive(), SystemFolders.GetCurrentUserAppData(), SystemFolders.GetCurrentUserLocalAppData(), SystemFolders.GetCommonAppData(), SystemFolders.GetCommonDesktop(), SystemFolders.GetCommonProgramsStartMenu(), SystemFolders.GetCommonProgramFilesx86(), SystemFolders.GetCommonProgramFilesx64(), SystemFolders.GetCurrentUserDesktop(), SystemFolders.GetCurrentUserProgramsStartMenu() }; for (int i = 0; i < array.Length; i++) { if (Directory.Exists(array[i]) && array2[i] != null) { RestoreFiles(array2[i], array[i]); } } }