SIL.FieldWorks.Common.Framework.FwApp.UpdateExternalLinks C# (CSharp) Méthode

UpdateExternalLinks() public méthode

Handle changes to the LinkedFiles root directory for a language project.
This may not be the best place for this method, but I'm not sure there is a "best place".
public UpdateExternalLinks ( string sOldLinkedFilesRootDir ) : bool
sOldLinkedFilesRootDir string The old LinkedFiles root directory.
Résultat bool
		public bool UpdateExternalLinks(string sOldLinkedFilesRootDir)
		{
			ILangProject lp = Cache.LanguageProject;
			string sNewLinkedFilesRootDir = lp.LinkedFilesRootDir;
			if (!FileUtils.PathsAreEqual(sNewLinkedFilesRootDir, sOldLinkedFilesRootDir))
			{
				List<string> rgFilesToMove = new List<string>();
				// TODO: offer to move or copy existing files.
				foreach (ICmFolder cf in lp.MediaOC)
					CollectMovableFilesFromFolder(cf, rgFilesToMove, sOldLinkedFilesRootDir, sNewLinkedFilesRootDir);
				foreach (ICmFolder cf in lp.PicturesOC)
					CollectMovableFilesFromFolder(cf, rgFilesToMove, sOldLinkedFilesRootDir, sNewLinkedFilesRootDir);
				//Get the files which are pointed to by links in TsStrings
				CollectMovableFilesFromFolder(lp.FilePathsInTsStringsOA, rgFilesToMove, sOldLinkedFilesRootDir, sNewLinkedFilesRootDir);

				var hyperlinks = StringServices.GetHyperlinksInFolder(Cache, sOldLinkedFilesRootDir);
				foreach (var linkInfo in hyperlinks)
				{
					if (!rgFilesToMove.Contains(linkInfo.RelativePath) &&
						FileUtils.SimilarFileExists(Path.Combine(sOldLinkedFilesRootDir, linkInfo.RelativePath)) &&
						!FileUtils.SimilarFileExists(Path.Combine(sNewLinkedFilesRootDir, linkInfo.RelativePath)))
					{
						rgFilesToMove.Add(linkInfo.RelativePath);
					}
				}
				if (rgFilesToMove.Count > 0)
				{
					FileLocationChoice action;
					using (MoveOrCopyFilesDlg dlg = new MoveOrCopyFilesDlg()) // REVIEW (Hasso) 2015.08: should this go in MoveOrCopyFilesController?
					{
						dlg.Initialize(rgFilesToMove.Count, sOldLinkedFilesRootDir, sNewLinkedFilesRootDir, this);
						DialogResult res = dlg.ShowDialog();
						Debug.Assert(res == DialogResult.OK);
						if (res != DialogResult.OK)
							return false;	// should never happen!
						action = dlg.Choice;
					}
					if (action == FileLocationChoice.Leave) // Expand path
					{
						NonUndoableUnitOfWorkHelper.Do(Cache.ActionHandlerAccessor,
							() =>
								{
									foreach (ICmFolder cf in lp.MediaOC)
										ExpandToFullPath(cf, sOldLinkedFilesRootDir, sNewLinkedFilesRootDir);
									foreach (ICmFolder cf in lp.PicturesOC)
										ExpandToFullPath(cf, sOldLinkedFilesRootDir, sNewLinkedFilesRootDir);
								});
						// Hyperlinks are always already full paths.
						return false;
					}
					List<string> rgLockedFiles = new List<string>();
					foreach (string sFile in rgFilesToMove)
					{
						string sOldPathname = Path.Combine(sOldLinkedFilesRootDir, sFile);
						string sNewPathname = Path.Combine(sNewLinkedFilesRootDir, sFile);
						string sNewDir = Path.GetDirectoryName(sNewPathname);
						if (!Directory.Exists(sNewDir))
							Directory.CreateDirectory(sNewDir);
						Debug.Assert(FileUtils.TrySimilarFileExists(sOldPathname, out sOldPathname));
						if (FileUtils.TrySimilarFileExists(sNewPathname, out sNewPathname))
							File.Delete(sNewPathname);
						try
						{
							if (action == FileLocationChoice.Move)
							{
								//LT-13343 do copy followed by delete to ensure the file gets put in the new location.
								//If the current FLEX record has a picture displayed the File.Delete will fail.
								File.Copy(sOldPathname, sNewPathname);
								File.Delete(sOldPathname);
							}

							else
								File.Copy(sOldPathname, sNewPathname);
						}
						catch (Exception ex)
						{
							Debug.WriteLine(String.Format("{0}: {1}", ex.Message, sOldPathname));
							rgLockedFiles.Add(sFile);
						}
					}
					NonUndoableUnitOfWorkHelper.DoUsingNewOrCurrentUOW(Cache.ActionHandlerAccessor,
						() => StringServices.FixHyperlinkFolder(hyperlinks, sOldLinkedFilesRootDir, sNewLinkedFilesRootDir));

					// If any files failed to be moved or copied above, try again now that we've
					// opened a new window and had more time elapse (and more demand to reuse
					// memory) since the failure.
					if (rgLockedFiles.Count > 0)
					{
						GC.Collect();	// make sure the window is disposed!
						Thread.Sleep(1000);
						foreach (string sFile in rgLockedFiles)
						{
							string sOldPathname = Path.Combine(sOldLinkedFilesRootDir, sFile);
							string sNewPathname = Path.Combine(sNewLinkedFilesRootDir, sFile);
							try
							{
								if (action == FileLocationChoice.Move)
									FileUtils.Move(sOldPathname, sNewPathname);
								else
									File.Copy(sOldPathname, sNewPathname);
							}
							catch (Exception ex)
							{
								Debug.WriteLine(String.Format("{0}: {1} (SECOND ATTEMPT)", ex.Message, sOldPathname));
							}
						}
					}
					return true;
				}
			}
			return false;
		}

Usage Example

Exemple #1
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Moves the external link directory and files to the new FW 7.0 or later location.
		/// </summary>
		/// <param name="app">The application.</param>
		/// ------------------------------------------------------------------------------------
		private static void MoveExternalLinkDirectoryAndFiles(FwApp app)
		{
			var sLinkedFilesRootDir = app.Cache.LangProject.LinkedFilesRootDir;
			NonUndoableUnitOfWorkHelper.Do(app.Cache.ActionHandlerAccessor, () =>
			{
				app.Cache.LangProject.LinkedFilesRootDir = FdoFileHelper.GetDefaultLinkedFilesDir(
					app.Cache.ProjectId.ProjectFolder);
			});
			app.UpdateExternalLinks(sLinkedFilesRootDir);
		}