public static string CreateEmptyFile(this ITempFilesManager tempFiles) { string fname = tempFiles.GenerateNewName(); File.Create(fname).Close(); return(fname); }
public static bool?TestParsing( string sampleLog, IAlertPopup alerts, ITempFilesManager tempFilesManager, IObjectFactory objectsFactory, XmlNode formatRoot, string formatSpecificNodeName ) { if (sampleLog == "") { alerts.ShowPopup("", "Provide sample log first", AlertFlags.Ok | AlertFlags.WarningIcon); return(null); } string tmpLog = tempFilesManager.GenerateNewName(); try { XDocument clonedFormatXmlDocument = XDocument.Parse(formatRoot.OuterXml); UserDefinedFactoryParams createParams; createParams.Entry = null; createParams.RootNode = clonedFormatXmlDocument.Element("format"); createParams.FormatSpecificNode = createParams.RootNode.Element(formatSpecificNodeName); createParams.FactoryRegistry = null; createParams.TempFilesManager = tempFilesManager; // Temporary sample file is always written in Unicode wo BOM: we don't test encoding detection, // we test regexps correctness. using (var w = new StreamWriter(tmpLog, false, new UnicodeEncoding(false, false))) w.Write(sampleLog); ChangeEncodingToUnicode(createParams); var cp = ConnectionParamsUtils.CreateFileBasedConnectionParamsFromFileName(tmpLog); ILogProviderFactory f; if (formatSpecificNodeName == "regular-grammar") { f = new RegularGrammar.UserDefinedFormatFactory(createParams); } else if (formatSpecificNodeName == "xml") { f = new XmlFormat.UserDefinedFormatFactory(createParams); } else { return(null); } using (f as IDisposable) using (var interaction = objectsFactory.CreateTestDialog()) { return(interaction.ShowDialog(f, cp)); } } finally { File.Delete(tmpLog); } }
void ShowTextInTextViewer(string text) { var tempFileName = tempFilesManager.GenerateNewName() + ".txt"; using (var w = new StreamWriter(tempFileName)) w.Write(text); shellOpen.OpenInTextEditor(tempFileName); }
static string GetTempInstallationDir(string installationDir, ITempFilesManager tempFiles) { string tempInstallationDir = Path.Combine( tempFiles.GenerateNewName(), "pending-logjoint-update"); return(tempInstallationDir); }
async void IViewControlHandler.ExecuteAction(string actionId, ClickFlags flags) { switch (actionId) { case "show": if (lazyOutputForm != null) { lazyOutputForm().Show(); } break; case "action": if (!await this.postprocessorsManager.RunPostprocessors(postprocessorsManager.GetPostprocessorOutputsByPostprocessorId(postprocessorKind))) { return; } if (lazyOutputForm != null) { var outputs = postprocessorsManager.GetPostprocessorOutputsByPostprocessorId(postprocessorKind); if (outputs.Any(x => x.OutputStatus == LogSourcePostprocessorOutput.Status.Finished)) { lazyOutputForm().Show(); } } break; case "report": { var outputs = postprocessorsManager.GetPostprocessorOutputsByPostprocessorId(postprocessorKind); var summaries = outputs .Select(output => output.LastRunSummary) .Where(summary => summary != null) .OrderBy(summary => summary.HasErrors ? 0 : summary.HasWarnings ? 1 : 2); var text = new StringBuilder(); foreach (var summary in summaries) { text.Append(summary.Report ?? ""); text.AppendLine(); text.AppendLine(); } if (text.Length > 0) { var fname = Path.ChangeExtension(tempFiles.GenerateNewName(), ".txt"); File.WriteAllText(fname, text.ToString()); shellOpen.OpenInTextEditor(fname); } } break; } }
private async Task LoadArchivedStorageEntries(string entriesArchiveUrl, CancellationToken cancellation) { var entriesArchiveFileName = tempFilesManager.GenerateNewName(); using (var entriesArchiveStream = new FileStream(entriesArchiveFileName, FileMode.CreateNew)) { await backendAccess.GetEntriesArchive(entriesArchiveUrl, entriesArchiveStream, cancellation); } var sectionContentTempFileName = tempFilesManager.GenerateNewName(); var entries = new Dictionary <string, IStorageEntry>(); using (var zipFile = new ZipFile(entriesArchiveFileName)) { foreach (var zipEntry in zipFile.OfType <ZipEntry>().Where(e => e != null)) { if (zipEntry.IsDirectory) { continue; } var storageEntryId = Path.GetDirectoryName(zipEntry.Name); var sectionId = Path.GetFileName(zipEntry.Name); using (var sectionContentStream = new FileStream(sectionContentTempFileName, FileMode.Create, FileAccess.ReadWrite, FileShare.None, 4096, FileOptions.DeleteOnClose)) { using (var inputStream = zipFile.GetInputStream(zipEntry)) IOUtils.CopyStreamWithProgress(inputStream, sectionContentStream, _ => { }, CancellationToken.None); sectionContentStream.Position = 0; IStorageEntry storageEntry; if (!entries.TryGetValue(storageEntryId, out storageEntry)) { entries.Add(storageEntryId, storageEntry = storageManager.GetEntryById(storageEntryId)); } await storageEntry.LoadSectionFromSnapshot(sectionId, sectionContentStream, cancellation); } } } }
public static async Task SerializePostprocessorOutput( Task <ILogPartToken> logPartToken, ILogPartTokenFactories logPartTokenFactories, IEnumerableAsync <M.Event[]> events, Task <ISameNodeDetectionToken> sameNodeDetectionTokenTask, ISameNodeDetectionTokenFactories nodeDetectionTokenFactories, Func <object, TextLogEventTrigger> triggersConverter, string contentsEtagAttr, Func <Task <Stream> > openOutputStream, ITempFilesManager tempFiles, CancellationToken cancellation ) { events = events ?? new List <M.Event[]>().ToAsync(); logPartToken = logPartToken ?? Task.FromResult <ILogPartToken>(null); sameNodeDetectionTokenTask = sameNodeDetectionTokenTask ?? Task.FromResult <ISameNodeDetectionToken>(null); var eventsTmpFile = tempFiles.GenerateNewName(); Func <Task <Stream> > openTempFile(string fileName) => () => Task.FromResult <Stream>(new FileStream(fileName, FileMode.OpenOrCreate)); var serializeMessagingEvents = events.SerializePostprocessorOutput <M.Event, M.EventsSerializer, M.IEventsVisitor>( triggerSerializer => new M.EventsSerializer(triggerSerializer), null, logPartTokenFactories, triggersConverter, null, messagingEventsElementName, openTempFile(eventsTmpFile), tempFiles, cancellation ); await Task.WhenAll(serializeMessagingEvents, logPartToken, sameNodeDetectionTokenTask); using (var outputWriter = XmlWriter.Create(await openOutputStream(), new XmlWriterSettings() { Indent = true, Async = true, CloseOutput = true })) using (var messagingEventsReader = XmlReader.Create(eventsTmpFile)) { outputWriter.WriteStartElement("root"); new PostprocessorOutputETag(contentsEtagAttr).Write(outputWriter); logPartTokenFactories.SafeWriteTo(await logPartToken, outputWriter); nodeDetectionTokenFactories.SafeWriteTo(await sameNodeDetectionTokenTask, outputWriter); messagingEventsReader.ReadToFollowing(messagingEventsElementName); await outputWriter.WriteNodeAsync(messagingEventsReader, false); outputWriter.WriteEndElement(); // root } File.Delete(eventsTmpFile); }
static string GetTempInstallationDir(string installationDir, ITempFilesManager tempFiles) { if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { string tempInstallationDir = Path.Combine( tempFiles.GenerateNewName(), "pending-logjoint-update"); return(tempInstallationDir); } else { // On windows: download update to a folder next to installation dir. // This ensures almost 100% that temp folder and installation dir are on the same HDD partition // which ensures speed and success of moving the temp folder in place of installation dir. var localUpdateCheckId = Guid.NewGuid().GetHashCode(); string tempInstallationDir = Path.GetFullPath(string.Format(@"{0}\..\pending-logjoint-update-{1:x}", installationDir, localUpdateCheckId)); return(tempInstallationDir); } }
public static async Task <IPendingUpdate> Create( IFactory factory, ITempFilesManager tempFiles, ITraceSourceFactory traceSourceFactory, MultiInstance.IInstancesCounter mutualExecutionCounter, IReadOnlyList <Extensibility.IPluginInfo> requiredPlugins, string managedAssembliesPath, string updateLogFileName, CancellationToken cancellation ) { LJTraceSource trace = traceSourceFactory.CreateTraceSource("AutoUpdater", $"pupd-{Interlocked.Increment(ref pendingUpdateIdx)}"); string installationDir = Path.GetFullPath( Path.Combine(managedAssembliesPath, Constants.installationPathRootRelativeToManagedAssembliesLocation)); string tempInstallationDir = GetTempInstallationDir(installationDir, tempFiles); async Task <(string tempZipFile, DownloadUpdateResult result)> Download(IUpdateDownloader updateDownloader, string name) { var tempFileName = tempFiles.GenerateNewName(); using (var tempFileStream = new FileStream(tempFileName, FileMode.Create, FileAccess.Write)) { trace.Info("downloading update for '{0}' to '{1}'", name, tempFileName); var downloadResult = await updateDownloader.DownloadUpdate(null, tempFileStream, cancellation); cancellation.ThrowIfCancellationRequested(); if (downloadResult.Status == DownloadUpdateResult.StatusCode.Failure) { throw new Exception($"Failed to download update for {name}: {downloadResult.ErrorMessage}"); } return(tempFileName, downloadResult); } } var downloadResults = await Task.WhenAll( new[] { Download(factory.CreateAppUpdateDownloader(), "app") } .Union(requiredPlugins.Select(plugin => Download(factory.CreatePluginUpdateDownloader(plugin), plugin.Name))) ); void UnzipDownloadedUpdate(string zipFileName, string targetDir) { using (var fs = new FileStream(zipFileName, FileMode.Open)) using (var zipFile = new ZipArchive(fs, ZipArchiveMode.Read)) { try { zipFile.ExtractToDirectory(targetDir); } catch (UnauthorizedAccessException e) { throw new BadInstallationDirException(e); } } cancellation.ThrowIfCancellationRequested(); } trace.Info("unzipping downloaded update to {0}", tempInstallationDir); UnzipDownloadedUpdate(downloadResults[0].tempZipFile, tempInstallationDir); var newUpdateInfoPath = Path.Combine(tempInstallationDir, Constants.managedAssembliesLocationRelativeToInstallationRoot, Constants.updateInfoFileName); new UpdateInfoFileContent(downloadResults[0].result.ETag, DateTime.UtcNow, null).Write(newUpdateInfoPath); UpdatePermissions(tempInstallationDir); trace.Info("starting updater"); async Task <(Process process, string autoRestartFlagFileName)> StartUpdater() { var tempUpdaterExePath = tempFiles.GenerateNewName() + ".lj.updater.exe"; string updaterExePath; string programToStart; string firstArg; string autoRestartCommandLine; string autoRestartIPCKey; string restartFlagFileName; if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { updaterExePath = Path.Combine(installationDir, Constants.managedAssembliesLocationRelativeToInstallationRoot, "logjoint.updater.exe"); var monoPath = @"/Library/Frameworks/Mono.framework/Versions/Current/bin/mono"; programToStart = monoPath; firstArg = string.Format("\"{0}\" ", tempUpdaterExePath); restartFlagFileName = tempFiles.GenerateNewName() + ".autorestart"; autoRestartIPCKey = restartFlagFileName; autoRestartCommandLine = Path.GetFullPath(Path.Combine(installationDir, "..")); } else { updaterExePath = Path.Combine(installationDir, "updater", "logjoint.updater.exe"); programToStart = tempUpdaterExePath; firstArg = ""; autoRestartIPCKey = Constants.startAfterUpdateEventName; autoRestartCommandLine = Path.Combine(installationDir, "logjoint.exe"); restartFlagFileName = null; } File.Copy(updaterExePath, tempUpdaterExePath); trace.Info("updater executable copied to '{0}'", tempUpdaterExePath); trace.Info("this update's log is '{0}'", updateLogFileName); var updaterExeProcessParams = new ProcessStartInfo() { UseShellExecute = false, FileName = programToStart, Arguments = string.Format("{0}\"{1}\" \"{2}\" \"{3}\" \"{4}\" \"{5}\" \"{6}\"", firstArg, installationDir, tempInstallationDir, mutualExecutionCounter.MutualExecutionKey, updateLogFileName, autoRestartIPCKey, autoRestartCommandLine ), WorkingDirectory = Path.GetDirectoryName(tempUpdaterExePath) }; trace.Info("starting updater executable '{0}' with args '{1}'", updaterExeProcessParams.FileName, updaterExeProcessParams.Arguments); Environment.SetEnvironmentVariable("MONO_ENV_OPTIONS", ""); // todo var process = Process.Start(updaterExeProcessParams); // wait a bit to catch and log immediate updater's failure for (int i = 0; i < 10 && !cancellation.IsCancellationRequested; ++i) { if (process.HasExited && process.ExitCode != 0) { trace.Error("updater process exited abnormally with code {0}", process.ExitCode); break; } await Task.Delay(100); } return(process, restartFlagFileName); } var(updater, autoRestartFlagFileName) = await StartUpdater(); var key = factory.CreateUpdateKey( downloadResults[0].result.ETag, ImmutableDictionary.CreateRange( downloadResults.Skip(1).Select(r => r.result.ETag).Zip(requiredPlugins, (etag, plugin) => new KeyValuePair <string, string>(plugin.Id, etag)) ) ); var pluginsFolder = Path.Combine(tempInstallationDir, Constants.managedAssembliesLocationRelativeToInstallationRoot, "Plugins"); if (Directory.Exists(pluginsFolder)) { Directory.Delete(pluginsFolder, true); } Directory.CreateDirectory(pluginsFolder); var pluginFormats = new HashSet <string>(); foreach (var plugin in downloadResults.Skip(1).Zip(requiredPlugins, (downloadResult, plugin) => (plugin, downloadResult))) { var pluginFolder = Path.Combine(pluginsFolder, plugin.plugin.Id); UnzipDownloadedUpdate(plugin.downloadResult.tempZipFile, pluginFolder); new UpdateInfoFileContent(plugin.downloadResult.result.ETag, plugin.downloadResult.result.LastModifiedUtc, null).Write( Path.Combine(pluginFolder, Constants.updateInfoFileName)); try { Extensibility.IPluginManifest manifest = new Extensibility.PluginManifest(pluginFolder); pluginFormats.UnionWith(manifest.Files .Where(f => f.Type == Extensibility.PluginFileType.FormatDefinition) .Select(f => Path.GetFileName(f.AbsolulePath).ToLower())); } catch (Extensibility.BadManifestException) { continue; } } CopyCustomFormats( managedAssembliesPath, Path.Combine(tempInstallationDir, Constants.managedAssembliesLocationRelativeToInstallationRoot), pluginFormats, // Temporary measure: plugin formats used to be copied to root Formats folder. Ignore them on update. trace ); return(new PendingUpdate(tempInstallationDir, key, trace, updater, autoRestartFlagFileName)); }
private async Task StartUpdater(string installationDir, string tempInstallationDir, ITempFilesManager tempFiles, MultiInstance.IInstancesCounter mutualExecutionCounter, CancellationToken cancel) { var tempUpdaterExePath = tempFiles.GenerateNewName() + ".lj.updater.exe"; string updaterExePath; string programToStart; string firstArg; string autoRestartCommandLine; string autoRestartIPCKey; #if MONOMAC updaterExePath = Path.Combine(installationDir, managedAssembliesLocationRelativeToInstallationRoot, "logjoint.updater.exe"); var monoPath = @"/Library/Frameworks/Mono.framework/Versions/Current/bin/mono"; programToStart = monoPath; firstArg = string.Format("\"{0}\" ", tempUpdaterExePath); autoRestartIPCKey = autoRestartFlagFileName = tempFiles.GenerateNewName() + ".autorestart"; autoRestartCommandLine = Path.GetFullPath(Path.Combine(installationDir, "..")); #else updaterExePath = Path.Combine(installationDir, "updater", "logjoint.updater.exe"); programToStart = tempUpdaterExePath; firstArg = ""; autoRestartIPCKey = startAfterUpdateEventName; autoRestartCommandLine = Path.Combine(installationDir, "logjoint.exe"); #endif File.Copy(updaterExePath, tempUpdaterExePath); trace.Info("updater executable copied to '{0}'", tempUpdaterExePath); var updateLogFileName = ComposeUpdateLogFileName(); trace.Info("this update's log is '{0}'", updateLogFileName); var updaterExeProcessParams = new ProcessStartInfo() { UseShellExecute = false, FileName = programToStart, Arguments = string.Format("{0}\"{1}\" \"{2}\" \"{3}\" \"{4}\" \"{5}\" \"{6}\"", firstArg, installationDir, tempInstallationDir, mutualExecutionCounter.MutualExecutionKey, updateLogFileName, autoRestartIPCKey, autoRestartCommandLine ), WorkingDirectory = Path.GetDirectoryName(tempUpdaterExePath) }; trace.Info("starting updater executable '{0}' with args '{1}'", updaterExeProcessParams.FileName, updaterExeProcessParams.Arguments); Environment.SetEnvironmentVariable("MONO_ENV_OPTIONS", ""); // todo using (var process = Process.Start(updaterExeProcessParams)) { // wait a bit to catch and log immediate updater's failure for (int i = 0; i < 10 && !cancel.IsCancellationRequested; ++i) { if (process.HasExited && process.ExitCode != 0) { trace.Error("updater process exited abnormally with code {0}", process.ExitCode); break; } await Task.Delay(100); } } }
public static async Task SerializePostprocessorOutput <Evt, Serializer, EvtVisitor>( this IEnumerableAsync <Evt[]> events, Func <Action <object, XElement>, Serializer> serializerFactory, Task <ILogPartToken> rotatedLogPartToken, ILogPartTokenFactories rotatedLogPartFactories, Func <object, TextLogEventTrigger> triggersConverter, string contentsEtagAttr, string rootElementName, string outputFileName, ITempFilesManager tempFiles, CancellationToken cancellation ) where Evt : IVisitable <EvtVisitor> where Serializer : class, IEventsSerializer, EvtVisitor { rotatedLogPartToken = rotatedLogPartToken ?? Task.FromResult <ILogPartToken>(null); var sortKeyAttr = XName.Get("__key"); var chunks = new List <string>(); Serializer serializer = null; Action resetSerializer = () => { if (serializer?.Output?.Count > 0) { string chunkFileName = tempFiles.GenerateNewName(); chunks.Add(chunkFileName); using (var writer = XmlWriter.Create(chunkFileName, new XmlWriterSettings() { OmitXmlDeclaration = true, ConformanceLevel = ConformanceLevel.Fragment })) { foreach (var e in serializer.Output.OrderBy(e => e.Attribute(sortKeyAttr).Value)) { e.WriteTo(writer); } } } serializer = serializerFactory((trigger, elt) => { triggersConverter(trigger).Save(elt); elt.SetAttributeValue(sortKeyAttr, ((IOrderedTrigger)trigger).Index.ToString("x8")); }); }; resetSerializer(); await events.ForEach(batch => { foreach (var e in batch) { e.Visit(serializer); if (serializer.Output.Count >= 8 * 1024) { resetSerializer(); } } return(Task.FromResult(!cancellation.IsCancellationRequested)); }); resetSerializer(); if (cancellation.IsCancellationRequested) { return; } using (var outputWriter = XmlWriter.Create(outputFileName, new XmlWriterSettings() { Indent = true })) { outputWriter.WriteStartElement(rootElementName); new PostprocessorOutputETag(contentsEtagAttr).Write(outputWriter); rotatedLogPartFactories.SafeWriteTo(await rotatedLogPartToken, outputWriter); var readersSettings = new XmlReaderSettings() { ConformanceLevel = ConformanceLevel.Fragment }; var readers = chunks.Select(chunkFileName => XmlReader.Create(chunkFileName, readersSettings)).ToList(); try { var q = new VCSKicksCollection.PriorityQueue <KeyValuePair <XmlReader, XElement> >(Comparer <KeyValuePair <XmlReader, XElement> > .Create((item1, item2) => { return(string.CompareOrdinal(item1.Value.Attribute(sortKeyAttr).Value, item2.Value.Attribute(sortKeyAttr).Value)); })); Action <XmlReader> enqueueReader = reader => { if (!reader.EOF) { if (reader.MoveToContent() != XmlNodeType.Element) { throw new InvalidOperationException("bad chunk"); } q.Enqueue(new KeyValuePair <XmlReader, XElement>(reader, (XElement)XNode.ReadFrom(reader))); } }; readers.ForEach(enqueueReader); while (q.Count > 0) { var item = q.Dequeue(); item.Value.Attribute(sortKeyAttr).Remove(); item.Value.WriteTo(outputWriter); enqueueReader(item.Key); } } finally { readers.ForEach(r => r.Dispose()); chunks.ForEach(chunkFileName => tempFiles.DeleteIfTemporary(chunkFileName)); } outputWriter.WriteEndElement(); // end of root node } }
public static async Task SerializePostprocessorOutput( IEnumerableAsync <M.Event[]> events, IEnumerableAsync <TLBlock.Event[]> timelineComments, IEnumerableAsync <SIBlock.Event[]> stateInspectorComments, Task <ILogPartToken> logPartToken, ILogPartTokenFactories logPartTokenFactories, Func <object, TextLogEventTrigger> triggersConverter, string contentsEtagAttr, string outputFileName, ITempFilesManager tempFiles, CancellationToken cancellation ) { events = events ?? new List <M.Event[]>().ToAsync(); timelineComments = timelineComments ?? new List <TLBlock.Event[]>().ToAsync(); stateInspectorComments = stateInspectorComments ?? new List <SIBlock.Event[]>().ToAsync(); logPartToken = logPartToken ?? Task.FromResult <ILogPartToken>(null); var eventsTmpFile = tempFiles.GenerateNewName(); var timelineCommentsTmpFile = tempFiles.GenerateNewName(); var stateInsectorCommentsTmpFile = tempFiles.GenerateNewName(); var serializeMessagingEvents = events.SerializePostprocessorOutput <M.Event, M.EventsSerializer, M.IEventsVisitor>( triggerSerializer => new M.EventsSerializer(triggerSerializer), null, logPartTokenFactories, triggersConverter, null, messagingEventsElementName, eventsTmpFile, tempFiles, cancellation ); var serializeTimelineComments = timelineComments.SerializePostprocessorOutput <TLBlock.Event, TLBlock.EventsSerializer, TLBlock.IEventsVisitor>( triggerSerializer => new TLBlock.EventsSerializer(triggerSerializer), null, logPartTokenFactories, triggersConverter, null, timelineCommentsElementName, timelineCommentsTmpFile, tempFiles, cancellation ); var serializeStateInspectorComments = stateInspectorComments.SerializePostprocessorOutput <SIBlock.Event, SIBlock.EventsSerializer, SIBlock.IEventsVisitor>( triggerSerializer => new SIBlock.EventsSerializer(triggerSerializer), null, logPartTokenFactories, triggersConverter, null, stateCommentsElementName, stateInsectorCommentsTmpFile, tempFiles, cancellation ); await Task.WhenAll(serializeMessagingEvents, serializeTimelineComments, serializeStateInspectorComments, logPartToken); using (var outputWriter = XmlWriter.Create(outputFileName, new XmlWriterSettings() { Indent = true, Async = true })) using (var messagingEventsReader = XmlReader.Create(eventsTmpFile)) using (var timelineCommentsReader = XmlReader.Create(timelineCommentsTmpFile)) using (var stateInspectorCommentsReader = XmlReader.Create(stateInsectorCommentsTmpFile)) { outputWriter.WriteStartElement("root"); new PostprocessorOutputETag(contentsEtagAttr).Write(outputWriter); logPartTokenFactories.SafeWriteTo(await logPartToken, outputWriter); messagingEventsReader.ReadToFollowing(messagingEventsElementName); await outputWriter.WriteNodeAsync(messagingEventsReader, false); timelineCommentsReader.ReadToFollowing(timelineCommentsElementName); await outputWriter.WriteNodeAsync(timelineCommentsReader, false); stateInspectorCommentsReader.ReadToFollowing(stateCommentsElementName); await outputWriter.WriteNodeAsync(stateInspectorCommentsReader, false); outputWriter.WriteEndElement(); // root } File.Delete(eventsTmpFile); File.Delete(timelineCommentsTmpFile); File.Delete(stateInsectorCommentsTmpFile); }