/// <summary> /// this procedure makes sure that the latest version of the patch tool is being used; /// the latest available executable and required dlls are copied to the patch tmp directory /// </summary> /// <returns>void</returns> public void CopyLatestPatchProgram(String APatchDirectory) { String remotename; ArrayList PatchExecutableFiles; PatchExecutableFiles = new ArrayList(); string binPath = "openpetraorg" + Path.DirectorySeparatorChar + "bin" + FVersionPostFix + Path.DirectorySeparatorChar; PatchExecutableFiles.Add(binPath + "Ict.Common.dll"); PatchExecutableFiles.Add(binPath + "Ict.Common.IO.dll"); PatchExecutableFiles.Add(binPath + "ICSharpCode.SharpZipLib.dll"); PatchExecutableFiles.Add(binPath + "Ict.Tools.PatchTool.exe"); PatchExecutableFiles.Add(binPath + "Ict.Tools.PatchTool.Library.dll"); PatchExecutableFiles.Add(binPath + "GNU.Gettext.dll"); // copy the PatchTool.exe and required files from the currently installed application to a temp directory foreach (string patchExeFile in PatchExecutableFiles) { if (File.Exists(FBinPath + Path.DirectorySeparatorChar + Path.GetFileName(patchExeFile))) { System.IO.File.Copy(FBinPath + Path.DirectorySeparatorChar + Path.GetFileName(patchExeFile), APatchDirectory + Path.DirectorySeparatorChar + Path.GetFileName(patchExeFile), true); } } // compiling on Linux with Mono, we cannot use the manifest that tells the UAC that running a exe with patch in the name is fine without administrator rights // therefore we rename the file so that the normal user can execute it string newNameUAC = APatchDirectory + Path.DirectorySeparatorChar + "Ict.Tools.Ptchtool.exe"; if (File.Exists(newNameUAC)) { File.Delete(newNameUAC); } File.Move(APatchDirectory + Path.DirectorySeparatorChar + "Ict.Tools.PatchTool.exe", newNameUAC); // check for the latest version of those files in the new patches foreach (string patch in FListOfNewPatches.GetValueList()) { // download the patch file from the remote server if it is not available locally yet // todo: display progress? could do it via the remoting connection? if (FRemotePatchesPath.StartsWith("http://") || FRemotePatchesPath.StartsWith("https://")) { remotename = FRemotePatchesPath + "/" + Path.GetFileName(patch); THTTPUtils.DownloadFile(remotename, patch); } else if (!System.IO.File.Exists(patch) && (FRemotePatchesPath.Length > 0)) { remotename = FRemotePatchesPath + Path.DirectorySeparatorChar + Path.GetFileName(patch); System.IO.File.Copy(remotename, patch); } PackTools.Unzip(APatchDirectory, patch, PatchExecutableFiles, true); } }
/// <summary> /// check whether there is a patch available; if this is a remote version, try to download a patch from the server this will also get the version of the currently installed code, and the list of patches that can be installed, in local /// variables /// </summary> /// <param name="AShowStatus">Set to true to show status messages as a MessageBox /// if there is a problem, or to false to have them returned in /// <paramref name="AStatusMessage" /></param>. /// <param name="AStatusMessage">A Status Message in case there is a problem AND /// <paramref name="AShowStatus" /> is false.</param> public Boolean CheckForRecentPatch(bool AShowStatus, out string AStatusMessage) { string localname; TFileVersionInfo fileStartVersion; TFileVersionInfo filePatchVersion; string directoryListing; string searchPattern; string filesignature; AStatusMessage = ""; FListOfNewPatches = new SortedList(); // first get the version of the currently installed binaries // read from version.txt in the bin directory; it contains the currently installed version in RPM style (e.g. 3.0.0-14) if (!File.Exists(FBinPath + Path.DirectorySeparatorChar + "version.txt")) { throw new Exception(String.Format("Cannot search for new patch, since I cannot find file {0}", FBinPath + Path.DirectorySeparatorChar + "version.txt")); } StreamReader srVersion = new StreamReader(FBinPath + Path.DirectorySeparatorChar + "version.txt"); FCurrentlyInstalledVersion = new TFileVersionInfo(srVersion.ReadLine()); srVersion.Close(); if (FRemotePatchesPath.StartsWith("http://") || FRemotePatchesPath.StartsWith("https://")) { directoryListing = THTTPUtils.ReadWebsite(FRemotePatchesPath); if (directoryListing == null) { if (AShowStatus) { MessageBox.Show(String.Format(StrProblemConnecting, FRemotePatchesPath), StrProblemConnectingTitle); } else { AStatusMessage = String.Format(StrProblemConnecting, FRemotePatchesPath); } return(false); } // find all the files names that match the pattern // eg <a href="Patch2.2.7-2_2.2.8-0.zip"> searchPattern = "<a href=\""; while (directoryListing.IndexOf(searchPattern) != -1) { string filename = directoryListing.Substring( directoryListing.IndexOf(searchPattern) + searchPattern.Length, directoryListing.Substring( directoryListing.IndexOf(searchPattern) + searchPattern.Length).IndexOf('"')); directoryListing = directoryListing.Substring(directoryListing.IndexOf(searchPattern) + searchPattern.Length); // signature e.g: gr1100o.r">gr1100o.r</a> 14-Oct-2008 13:11 153K filesignature = directoryListing.Substring(0, directoryListing.IndexOf("\n")); if (filename.ToLower().StartsWith("patch") && filename.ToLower().EndsWith(".zip")) { filePatchVersion = TPatchFileVersionInfo.GetLatestPatchVersionFromDiffZipName(filename); if ((filePatchVersion.Compare(FCurrentlyInstalledVersion) > 0) && (!System.IO.File.Exists(FPatchesPath + Path.DirectorySeparatorChar + Path.GetFileName(filename)))) { string LocalName = FPatchesPath + Path.DirectorySeparatorChar + Path.GetFileName(filename); FListOfNewPatches.Add(LocalName, LocalName); } } else if (filename.Contains("Setup") && filename.EndsWith(".exe")) { // ignore setup executable } else if (filename.ToLower().EndsWith(".dll") || filename.ToLower().EndsWith(".exe")) { // download .dll/.exe files from the netpatches directory if there is no file with same date already if (System.IO.File.Exists(FPatchesPath + Path.DirectorySeparatorChar + filename + ".signature")) { StreamReader sr = new StreamReader(FPatchesPath + Path.DirectorySeparatorChar + filename + ".signature"); if (sr.ReadLine().Trim() == filesignature.Trim()) { if (System.IO.File.Exists(FPatchesPath + Path.DirectorySeparatorChar + filename + ".old") && !System.IO.File.Exists(FPatchesPath + Path.DirectorySeparatorChar + filename)) { // the file has been renamed by the patch, and needs to be reinstated System.IO.File.Move(FPatchesPath + Path.DirectorySeparatorChar + filename + ".old", FPatchesPath + Path.DirectorySeparatorChar + filename); } filename = "ALREADY_LATEST"; } sr.Close(); } if (filename != "ALREADY_LATEST") { string localFile = FPatchesPath + Path.DirectorySeparatorChar + filename; if (filename.ToLower().EndsWith(".dll") || filename.ToLower().EndsWith(".exe")) { localFile = FBinPath + Path.DirectorySeparatorChar + filename; // make backup copy of .dll/.exe if there does not already one exist; don't overwrite .orig files if (!File.Exists(localFile + ".orig")) { System.IO.File.Move(localFile, localFile + ".orig"); } } THTTPUtils.DownloadFile(FRemotePatchesPath + "/" + filename, localFile); StreamWriter sw = new StreamWriter(FPatchesPath + Path.DirectorySeparatorChar + filename + ".signature"); sw.WriteLine(filesignature); sw.Close(); } } } // todo: remove local .r files if they are not in the net-patches directory // todo: the same for *.dll and *.exe; careful: only create an .orig copy once. // todo: somehow revert to .orig dll/exe file if there is no patched file in net-patches on the server? // todo: patch has to remove dll and exe from net-patches // todo: on the server side as well; check net-patches } else if ((FRemotePatchesPath.Length > 0) && (System.IO.Directory.Exists(FRemotePatchesPath))) { // check if there are newer patches on the remote server string[] files = System.IO.Directory.GetFiles(FRemotePatchesPath, "Patch*.zip"); foreach (string filename in files) { filePatchVersion = TPatchFileVersionInfo.GetLatestPatchVersionFromDiffZipName(filename); if ((filePatchVersion.Compare(FCurrentlyInstalledVersion) > 0) && ((!System.IO.File.Exists(FPatchesPath + Path.DirectorySeparatorChar + Path.GetFileName(filename))))) { localname = FPatchesPath + Path.DirectorySeparatorChar + Path.GetFileName(filename); FListOfNewPatches.Add(localname, localname); } } } // create a list of patches that should be installed string[] patchfiles = System.IO.Directory.GetFiles(FPatchesPath, "Patch*.zip"); foreach (string filename in patchfiles) { fileStartVersion = TPatchFileVersionInfo.GetStartVersionFromDiffZipName(filename); filePatchVersion = TPatchFileVersionInfo.GetLatestPatchVersionFromDiffZipName(filename); if ((fileStartVersion.Compare(FCurrentlyInstalledVersion) >= 0) && (filePatchVersion.Compare(FCurrentlyInstalledVersion) > 0)) { FListOfNewPatches.Add(filename, filename); } } // see if any patches are missing; is there a direct line between FCurrentlyInstalledVersion and FLatestAvailablePatch? FListOfNewPatches = CheckPatchesConsistent(FListOfNewPatches); return(FListOfNewPatches.Count > 0); }