<Feat>: Add universal NLog diagnostics and improve AppDiagnostic UI

Cause:

- Live diagnostics required logging from multiple applications without blocking TBF.
- Shared nlog.config files caused configuration conflicts.
- The original viewer lacked configurable colors and practical log controls.
- Inconsistent diagnostic deployment caused log transfer failures and locked shared DLLs during builds.

Solution:

1. Added universal diagnostic transport
   - Added AppDiagnostic.Logging with an NLog target and named-pipe communication.
   - Added background buffering and automatic reconnection.
   - Registered the diagnostic connector programmatically.

2. Separated diagnostic window lifecycle
   - Run AppDiagnostic as an independent process.
   - Activate the existing window on repeated launches.
   - Keep TBF running when the diagnostic window closes.

3. Corrected diagnostic deployment
   - Copy the complete diagnostic output into a dedicated AppDiagnostic subdirectory during build.
   - Overwrite existing deployment files to prevent inconsistent versions.
   - Validate and launch the executable from that subdirectory with an explicit working directory.

4. Improved the log viewer
   - Added configurable substring colors with a palette and live preview.
   - Added text, level and application filters.
   - Added line wrapping, clipboard actions and log export.
   - Added Pause/Resume, Refresh, Clear, auto-scroll and Always on top.
   - Added connection and log counters.
   - Persist color rules between sessions.

5. Removed legacy dependencies
   - Replaced LiveLogCache with structured diagnostic storage.
   - Removed AppDiagnostic dependencies on log4net and SharedComponents.

Validation:

- Confirmed successful log transfer when launching AppDiagnostic from TBF.
This commit is contained in:
2026-09-10 17:45:29 +02:00
parent 1c6f9af2bb
commit 8c77df207a
60 changed files with 2803 additions and 900 deletions
@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net472</TargetFramework>
<LangVersion>7.3</LangVersion>
<RootNamespace>AppDiagnostic.Logging</RootNamespace>
<AssemblyName>AppDiagnostic.Logging</AssemblyName>
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
<ProjectGuid>{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}</ProjectGuid>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NLog" Version="5.2.2" />
<Reference Include="System.Runtime.Serialization" />
</ItemGroup>
</Project>
@@ -0,0 +1,41 @@
using NLog;
using NLog.Config;
using NLog.Layouts;
namespace AppDiagnostic.Logging
{
public static class AppDiagnosticConnector
{
private static readonly object syncRoot = new object();
public static void Register()
{
lock (syncRoot)
{
LoggingConfiguration configuration = LogManager.Configuration ?? new LoggingConfiguration();
NLog.Targets.Target existingTarget = configuration.FindTargetByName("appDiagnostic");
if (existingTarget != null)
{
return;
}
var target = new AppDiagnosticTarget
{
Name = "appDiagnostic",
PipeName = DiagnosticProtocol.DefaultPipeName,
QueueLimit = DiagnosticProtocol.DefaultQueueLimit,
ReconnectDelayMilliseconds = DiagnosticProtocol.DefaultReconnectDelayMilliseconds,
ConnectTimeoutMilliseconds = DiagnosticProtocol.DefaultConnectTimeoutMilliseconds,
Layout = new SimpleLayout("${message}")
};
configuration.AddTarget(target.Name, target);
configuration.AddRule(LogLevel.Trace, LogLevel.Fatal, target, "*");
LogManager.Configuration = configuration;
LogManager.ReconfigExistingLoggers();
}
}
}
}
@@ -0,0 +1,233 @@
using NLog;
using NLog.Targets;
using System;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.IO;
using System.IO.Pipes;
using System.Threading;
using System.Threading.Tasks;
namespace AppDiagnostic.Logging
{
[Target("AppDiagnostic")]
public sealed class AppDiagnosticTarget : TargetWithLayout
{
private readonly object connectionLock = new object();
private readonly string applicationName;
private readonly int processId;
private BlockingCollection<DiagnosticLogEntry> queue;
private CancellationTokenSource cancellation;
private Task senderTask;
private NamedPipeClientStream pipeClient;
public AppDiagnosticTarget()
{
using (Process process = Process.GetCurrentProcess())
{
applicationName = process.ProcessName;
processId = process.Id;
}
PipeName = DiagnosticProtocol.DefaultPipeName;
QueueLimit = DiagnosticProtocol.DefaultQueueLimit;
ReconnectDelayMilliseconds =
DiagnosticProtocol.DefaultReconnectDelayMilliseconds;
ConnectTimeoutMilliseconds =
DiagnosticProtocol.DefaultConnectTimeoutMilliseconds;
}
public string PipeName { get; set; }
public int QueueLimit { get; set; }
public int ReconnectDelayMilliseconds { get; set; }
public int ConnectTimeoutMilliseconds { get; set; }
protected override void InitializeTarget()
{
base.InitializeTarget();
int queueLimit = QueueLimit > 0
? QueueLimit
: DiagnosticProtocol.DefaultQueueLimit;
queue = new BlockingCollection<DiagnosticLogEntry>(queueLimit);
cancellation = new CancellationTokenSource();
senderTask = Task.Factory.StartNew(
ProcessQueue,
cancellation.Token,
TaskCreationOptions.LongRunning,
TaskScheduler.Default);
}
protected override void Write(LogEventInfo logEvent)
{
if (logEvent == null || queue == null || queue.IsAddingCompleted)
{
return;
}
var entry = new DiagnosticLogEntry
{
TimestampUtc = logEvent.TimeStamp.ToUniversalTime(),
MachineName = Environment.MachineName,
ApplicationName = applicationName,
ProcessId = processId,
LoggerName = logEvent.LoggerName ?? string.Empty,
Level = logEvent.Level?.Name ?? string.Empty,
Message = Layout != null
? Layout.Render(logEvent)
: logEvent.FormattedMessage,
Exception = logEvent.Exception?.ToString() ?? string.Empty
};
try
{
queue.TryAdd(entry);
}
catch (ObjectDisposedException)
{
// A concurrent NLog shutdown may dispose the queue.
}
catch (InvalidOperationException)
{
// A concurrent NLog shutdown may complete the queue.
}
}
protected override void CloseTarget()
{
BlockingCollection<DiagnosticLogEntry> currentQueue = queue;
CancellationTokenSource currentCancellation = cancellation;
if (currentQueue != null)
{
currentQueue.CompleteAdding();
}
if (currentCancellation != null)
{
currentCancellation.Cancel();
}
CloseConnection();
try
{
senderTask?.Wait(2000);
}
catch (AggregateException)
{
// Cancellation during application shutdown is expected.
}
currentQueue?.Dispose();
currentCancellation?.Dispose();
queue = null;
cancellation = null;
senderTask = null;
base.CloseTarget();
}
private void ProcessQueue()
{
CancellationToken token = cancellation.Token;
try
{
foreach (DiagnosticLogEntry entry in
queue.GetConsumingEnumerable(token))
{
SendWhenConnected(entry, token);
}
}
catch (OperationCanceledException)
{
// Target shutdown is expected to cancel the sender.
}
}
private void SendWhenConnected(
DiagnosticLogEntry entry,
CancellationToken token)
{
while (!token.IsCancellationRequested)
{
try
{
EnsureConnected();
DiagnosticMessageSerializer.WriteFramed(pipeClient, entry);
return;
}
catch (Exception exception) when (
exception is IOException ||
exception is TimeoutException ||
exception is InvalidOperationException)
{
CloseConnection();
int delay = ReconnectDelayMilliseconds > 0
? ReconnectDelayMilliseconds
: DiagnosticProtocol.DefaultReconnectDelayMilliseconds;
if (token.WaitHandle.WaitOne(delay))
{
return;
}
}
}
}
private void EnsureConnected()
{
lock (connectionLock)
{
if (pipeClient != null && pipeClient.IsConnected)
{
return;
}
CloseConnectionWithoutLock();
pipeClient = new NamedPipeClientStream(
".",
string.IsNullOrWhiteSpace(PipeName)
? DiagnosticProtocol.DefaultPipeName
: PipeName,
PipeDirection.Out,
PipeOptions.Asynchronous);
int timeout = ConnectTimeoutMilliseconds > 0
? ConnectTimeoutMilliseconds
: DiagnosticProtocol.DefaultConnectTimeoutMilliseconds;
pipeClient.Connect(timeout);
}
}
private void CloseConnection()
{
lock (connectionLock)
{
CloseConnectionWithoutLock();
}
}
private void CloseConnectionWithoutLock()
{
if (pipeClient == null)
{
return;
}
pipeClient.Dispose();
pipeClient = null;
}
}
}
@@ -0,0 +1,33 @@
using System;
using System.Runtime.Serialization;
namespace AppDiagnostic.Logging
{
[DataContract]
public sealed class DiagnosticLogEntry
{
[DataMember(Order = 1)]
public DateTime TimestampUtc { get; set; }
[DataMember(Order = 2)]
public string MachineName { get; set; }
[DataMember(Order = 3)]
public string ApplicationName { get; set; }
[DataMember(Order = 4)]
public int ProcessId { get; set; }
[DataMember(Order = 5)]
public string LoggerName { get; set; }
[DataMember(Order = 6)]
public string Level { get; set; }
[DataMember(Order = 7)]
public string Message { get; set; }
[DataMember(Order = 8)]
public string Exception { get; set; }
}
}
@@ -0,0 +1,113 @@
using System;
using System.IO;
using System.Runtime.Serialization.Json;
namespace AppDiagnostic.Logging
{
public static class DiagnosticMessageSerializer
{
private static readonly DataContractJsonSerializer Serializer =
new DataContractJsonSerializer(typeof(DiagnosticLogEntry));
private static readonly object SerializerLock = new object();
public static byte[] Serialize(DiagnosticLogEntry entry)
{
if (entry == null)
{
throw new ArgumentNullException(nameof(entry));
}
using (var stream = new MemoryStream())
{
lock (SerializerLock)
{
Serializer.WriteObject(stream, entry);
}
return stream.ToArray();
}
}
public static DiagnosticLogEntry Deserialize(byte[] payload)
{
if (payload == null)
{
throw new ArgumentNullException(nameof(payload));
}
if (payload.Length == 0 ||
payload.Length > DiagnosticProtocol.MaximumMessageSize)
{
throw new InvalidDataException("Invalid diagnostic message size.");
}
using (var stream = new MemoryStream(payload, false))
{
lock (SerializerLock)
{
return (DiagnosticLogEntry)Serializer.ReadObject(stream);
}
}
}
public static void WriteFramed(Stream stream, DiagnosticLogEntry entry)
{
if (stream == null)
{
throw new ArgumentNullException(nameof(stream));
}
byte[] payload = Serialize(entry);
if (payload.Length > DiagnosticProtocol.MaximumMessageSize)
{
throw new InvalidDataException("Diagnostic message is too large.");
}
byte[] length = BitConverter.GetBytes(payload.Length);
stream.Write(length, 0, length.Length);
stream.Write(payload, 0, payload.Length);
stream.Flush();
}
public static DiagnosticLogEntry ReadFramed(Stream stream)
{
if (stream == null)
{
throw new ArgumentNullException(nameof(stream));
}
byte[] lengthBuffer = ReadExactly(stream, sizeof(int));
int payloadLength = BitConverter.ToInt32(lengthBuffer, 0);
if (payloadLength <= 0 ||
payloadLength > DiagnosticProtocol.MaximumMessageSize)
{
throw new InvalidDataException("Invalid diagnostic message size.");
}
return Deserialize(ReadExactly(stream, payloadLength));
}
private static byte[] ReadExactly(Stream stream, int count)
{
byte[] buffer = new byte[count];
int offset = 0;
while (offset < count)
{
int bytesRead = stream.Read(buffer, offset, count - offset);
if (bytesRead == 0)
{
throw new EndOfStreamException();
}
offset += bytesRead;
}
return buffer;
}
}
}
@@ -0,0 +1,11 @@
namespace AppDiagnostic.Logging
{
public static class DiagnosticProtocol
{
public const string DefaultPipeName = "Sensus.AppDiagnostic.LogPipe";
public const int MaximumMessageSize = 1024 * 1024;
public const int DefaultQueueLimit = 10000;
public const int DefaultReconnectDelayMilliseconds = 500;
public const int DefaultConnectTimeoutMilliseconds = 250;
}
}
+37
View File
@@ -0,0 +1,37 @@
# AppDiagnostic.Logging
Reusable NLog target for sending structured diagnostic events from multiple
.NET Framework processes to `AppDiagnostic.exe` through a local named pipe.
## Producer integration
Reference this project from the producer application and add the extension and
target to its NLog configuration:
```xml
<extensions>
<add assembly="AppDiagnostic.Logging" />
</extensions>
<targets>
<target name="appDiagnostic"
xsi:type="AppDiagnostic"
layout="${message}" />
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="appDiagnostic" />
</rules>
```
The target writes to a bounded background queue. Producer threads are not
blocked while the diagnostic viewer is unavailable. Queued messages are sent
after the viewer becomes available; new messages are discarded when the queue
limit is reached.
The receiver can read messages with:
```csharp
DiagnosticLogEntry entry =
DiagnosticMessageSerializer.ReadFramed(namedPipeServerStream);
```
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,65 @@
{
"format": 1,
"restore": {
"C:\\Sensus_projects\\New\\LocalBranch_start_at_6.3.2026\\tbf-local\\tbf\\AppDiagnostic.Logging\\AppDiagnostic.Logging.csproj": {}
},
"projects": {
"C:\\Sensus_projects\\New\\LocalBranch_start_at_6.3.2026\\tbf-local\\tbf\\AppDiagnostic.Logging\\AppDiagnostic.Logging.csproj": {
"version": "1.0.0",
"restore": {
"projectUniqueName": "C:\\Sensus_projects\\New\\LocalBranch_start_at_6.3.2026\\tbf-local\\tbf\\AppDiagnostic.Logging\\AppDiagnostic.Logging.csproj",
"projectName": "AppDiagnostic.Logging",
"projectPath": "C:\\Sensus_projects\\New\\LocalBranch_start_at_6.3.2026\\tbf-local\\tbf\\AppDiagnostic.Logging\\AppDiagnostic.Logging.csproj",
"packagesPath": "C:\\Users\\MFRNIAK\\.nuget\\packages\\",
"outputPath": "C:\\Sensus_projects\\New\\LocalBranch_start_at_6.3.2026\\tbf-local\\tbf\\AppDiagnostic.Logging\\obj\\",
"projectStyle": "PackageReference",
"fallbackFolders": [
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages"
],
"configFilePaths": [
"C:\\Users\\MFRNIAK\\AppData\\Roaming\\NuGet\\NuGet.Config",
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config",
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
],
"originalTargetFrameworks": [
"net472"
],
"sources": {
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
"https://api.nuget.org/v3/index.json": {}
},
"frameworks": {
"net472": {
"framework": "net472",
"targetAlias": "net472",
"projectReferences": {}
}
},
"warningProperties": {
"warnAsError": [
"NU1605"
]
},
"restoreAuditProperties": {
"enableAudit": "true",
"auditLevel": "low",
"auditMode": "direct"
},
"SdkAnalysisLevel": "10.0.300"
},
"frameworks": {
"net472": {
"framework": "net472",
"targetAlias": "net472",
"dependencies": {
"NLog": {
"target": "Package",
"version": "[5.2.2, )"
}
},
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.303\\RuntimeIdentifierGraph.json"
}
}
}
}
}
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot>
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\MFRNIAK\.nuget\packages\;C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages</NuGetPackageFolders>
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">7.0.0</NuGetToolVersion>
</PropertyGroup>
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<SourceRoot Include="C:\Users\MFRNIAK\.nuget\packages\" />
<SourceRoot Include="C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages\" />
</ItemGroup>
</Project>
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" />
@@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
@@ -0,0 +1,23 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("AppDiagnostic.Logging")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+1c6f9af2bb6c7dd588e6f0dab0a2836e409c1f93")]
[assembly: System.Reflection.AssemblyProductAttribute("AppDiagnostic.Logging")]
[assembly: System.Reflection.AssemblyTitleAttribute("AppDiagnostic.Logging")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
// Generated by the MSBuild WriteCodeFragment class.
@@ -0,0 +1 @@
328a35425ad6c5261737a98c855c6d7f7d872650a791c2ad21ac4020a96108d0
@@ -0,0 +1,8 @@
is_global = true
build_property.RootNamespace = AppDiagnostic.Logging
build_property.ProjectDir = C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\
build_property.EnableComHosting =
build_property.EnableGeneratedComInterfaceComImportInterop =
build_property.CsWinRTUseWindowsUIXamlProjections = false
build_property.EffectiveAnalysisLevelStyle =
build_property.EnableCodeStyleSeverity =
@@ -0,0 +1 @@
551ba94934db30a277a1a9cec2dacbe03f8393107e5d0b2436695f9bd62bd569
@@ -0,0 +1,11 @@
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\bin\Debug\net472\AppDiagnostic.Logging.dll
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\bin\Debug\net472\AppDiagnostic.Logging.pdb
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\bin\Debug\net472\NLog.dll
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Debug\net472\AppDiagnostic.Logging.csproj.AssemblyReference.cache
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Debug\net472\AppDiagnostic.Logging.GeneratedMSBuildEditorConfig.editorconfig
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Debug\net472\AppDiagnostic.Logging.AssemblyInfoInputs.cache
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Debug\net472\AppDiagnostic.Logging.AssemblyInfo.cs
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Debug\net472\AppDiagnostic.Logging.csproj.CoreCompileInputs.cache
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Debug\net472\AppDiagn.CFEA7AC0.Up2Date
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Debug\net472\AppDiagnostic.Logging.dll
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Debug\net472\AppDiagnostic.Logging.pdb
@@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
@@ -0,0 +1,23 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("AppDiagnostic.Logging")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Release")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+086bb55595ffea5be7adb163ca4c6489903ed67c")]
[assembly: System.Reflection.AssemblyProductAttribute("AppDiagnostic.Logging")]
[assembly: System.Reflection.AssemblyTitleAttribute("AppDiagnostic.Logging")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
// Generated by the MSBuild WriteCodeFragment class.
@@ -0,0 +1 @@
aad509aee7434678bd40a99ea120dafb7aa8b4f050f239aae2fbef41167a7201
@@ -0,0 +1,8 @@
is_global = true
build_property.RootNamespace = AppDiagnostic.Logging
build_property.ProjectDir = C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\
build_property.EnableComHosting =
build_property.EnableGeneratedComInterfaceComImportInterop =
build_property.CsWinRTUseWindowsUIXamlProjections = false
build_property.EffectiveAnalysisLevelStyle =
build_property.EnableCodeStyleSeverity =
@@ -0,0 +1 @@
53dfa6175dfb762da95c667a45dfe918166697a8741b3f7c14601d1f62b1886d
@@ -0,0 +1,11 @@
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\bin\Release\net472\AppDiagnostic.Logging.dll
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\bin\Release\net472\AppDiagnostic.Logging.pdb
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\bin\Release\net472\NLog.dll
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Release\net472\AppDiagnostic.Logging.csproj.AssemblyReference.cache
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Release\net472\AppDiagnostic.Logging.GeneratedMSBuildEditorConfig.editorconfig
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Release\net472\AppDiagnostic.Logging.AssemblyInfoInputs.cache
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Release\net472\AppDiagnostic.Logging.AssemblyInfo.cs
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Release\net472\AppDiagnostic.Logging.csproj.CoreCompileInputs.cache
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Release\net472\AppDiagn.CFEA7AC0.Up2Date
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Release\net472\AppDiagnostic.Logging.dll
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Release\net472\AppDiagnostic.Logging.pdb
@@ -0,0 +1,119 @@
{
"version": 4,
"targets": {
"net472": {
"NLog/5.2.2": {
"type": "package",
"frameworkAssemblies": [
"System",
"System.Configuration",
"System.Core",
"System.IO.Compression",
"System.Xml"
],
"compile": {
"lib/net46/NLog.dll": {
"related": ".xml"
}
},
"runtime": {
"lib/net46/NLog.dll": {
"related": ".xml"
}
}
}
}
},
"libraries": {
"NLog/5.2.2": {
"sha512": "r6Q9740g29gTwmTWlsgdIFm0mhNsfNZmbvWKX/Fxmi8X89ZrpUowHM2T2X1lP7RVpND+ef+XnfKL5g6Q1iNGXA==",
"type": "package",
"path": "nlog/5.2.2",
"files": [
".nupkg.metadata",
".signature.p7s",
"N.png",
"lib/net35/NLog.dll",
"lib/net35/NLog.xml",
"lib/net45/NLog.dll",
"lib/net45/NLog.xml",
"lib/net46/NLog.dll",
"lib/net46/NLog.xml",
"lib/netstandard1.3/NLog.dll",
"lib/netstandard1.3/NLog.xml",
"lib/netstandard1.5/NLog.dll",
"lib/netstandard1.5/NLog.xml",
"lib/netstandard2.0/NLog.dll",
"lib/netstandard2.0/NLog.xml",
"nlog.5.2.2.nupkg.sha512",
"nlog.nuspec"
]
}
},
"projectFileDependencyGroups": {
"net472": [
"NLog >= 5.2.2"
]
},
"packageFolders": {
"C:\\Users\\MFRNIAK\\.nuget\\packages\\": {},
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages": {}
},
"project": {
"version": "1.0.0",
"restore": {
"projectUniqueName": "C:\\Sensus_projects\\New\\LocalBranch_start_at_6.3.2026\\tbf-local\\tbf\\AppDiagnostic.Logging\\AppDiagnostic.Logging.csproj",
"projectName": "AppDiagnostic.Logging",
"projectPath": "C:\\Sensus_projects\\New\\LocalBranch_start_at_6.3.2026\\tbf-local\\tbf\\AppDiagnostic.Logging\\AppDiagnostic.Logging.csproj",
"packagesPath": "C:\\Users\\MFRNIAK\\.nuget\\packages\\",
"outputPath": "C:\\Sensus_projects\\New\\LocalBranch_start_at_6.3.2026\\tbf-local\\tbf\\AppDiagnostic.Logging\\obj\\",
"projectStyle": "PackageReference",
"fallbackFolders": [
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages"
],
"configFilePaths": [
"C:\\Users\\MFRNIAK\\AppData\\Roaming\\NuGet\\NuGet.Config",
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config",
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
],
"originalTargetFrameworks": [
"net472"
],
"sources": {
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
"https://api.nuget.org/v3/index.json": {}
},
"frameworks": {
"net472": {
"framework": "net472",
"targetAlias": "net472",
"projectReferences": {}
}
},
"warningProperties": {
"warnAsError": [
"NU1605"
]
},
"restoreAuditProperties": {
"enableAudit": "true",
"auditLevel": "low",
"auditMode": "direct"
},
"SdkAnalysisLevel": "10.0.300"
},
"frameworks": {
"net472": {
"framework": "net472",
"targetAlias": "net472",
"dependencies": {
"NLog": {
"target": "Package",
"version": "[5.2.2, )"
}
},
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.303\\RuntimeIdentifierGraph.json"
}
}
}
}
@@ -0,0 +1,10 @@
{
"version": 2,
"dgSpecHash": "ezwKOPZAAXU=",
"success": true,
"projectFilePath": "C:\\Sensus_projects\\New\\LocalBranch_start_at_6.3.2026\\tbf-local\\tbf\\AppDiagnostic.Logging\\AppDiagnostic.Logging.csproj",
"expectedPackageFiles": [
"C:\\Users\\MFRNIAK\\.nuget\\packages\\nlog\\5.2.2\\nlog.5.2.2.nupkg.sha512"
],
"logs": []
}
-13
View File
@@ -3,17 +3,4 @@
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
<log4net>
<appender name="LogCacheAppender" type="Namespace.LogCacheAppender, AssemblyName">
<param name="Cache" value="YourCacheInstance" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n" />
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="LogCacheAppender" />
</root>
</log4net>
</configuration>
+11 -12
View File
@@ -33,9 +33,6 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="log4net, Version=3.0.3.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<HintPath>..\packages\log4net.3.0.3\lib\net462\log4net.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
@@ -51,12 +48,15 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="BufferedListView.cs">
<SubType>Component</SubType>
<Compile Include="ColorRuleEditorForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="DiagApi.cs" />
<Compile Include="LogAdapter.cs" />
<Compile Include="LogFilter.cs" />
<Compile Include="DiagnosticLogFormatter.cs" />
<Compile Include="DiagnosticLogStore.cs" />
<Compile Include="DiagnosticPipeServer.cs" />
<Compile Include="LogColorizer.cs" />
<Compile Include="LogColorRule.cs" />
<Compile Include="LogColorRuleRepository.cs" />
<Compile Include="MainForm.cs">
<SubType>Form</SubType>
</Compile>
@@ -78,7 +78,6 @@
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
@@ -93,9 +92,9 @@
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SharedComponents\SharedComponents.csproj">
<Project>{8f942729-f454-4c99-ba6c-746962065ae3}</Project>
<Name>SharedComponents</Name>
<ProjectReference Include="..\AppDiagnostic.Logging\AppDiagnostic.Logging.csproj">
<Project>{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}</Project>
<Name>AppDiagnostic.Logging</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
+319
View File
@@ -0,0 +1,319 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
namespace AppDiagnostic
{
public sealed class ColorRuleEditorForm : Form
{
private readonly List<LogColorRule> rules;
private readonly ListBox ruleList = new ListBox();
private readonly TextBox patternTextBox = new TextBox();
private readonly CheckBox enabledCheckBox = new CheckBox();
private readonly CheckBox boldCheckBox = new CheckBox();
private readonly CheckBox backgroundCheckBox = new CheckBox();
private readonly Button foregroundButton = new Button();
private readonly Button backgroundButton = new Button();
private readonly RichTextBox previewBox = new RichTextBox();
private readonly Font previewBoldFont;
private bool loadingRule;
public ColorRuleEditorForm(IEnumerable<LogColorRule> sourceRules)
{
rules = sourceRules.Select(rule => rule.Clone()).ToList();
InitializeWindow();
previewBoldFont = new Font(previewBox.Font, FontStyle.Bold);
RefreshRuleList(0);
RefreshPreview();
}
public List<LogColorRule> Rules => rules.Select(rule => rule.Clone()).ToList();
protected override void Dispose(bool disposing)
{
if (disposing)
{
previewBoldFont.Dispose();
}
base.Dispose(disposing);
}
private void InitializeWindow()
{
Text = "Log color rules";
Icon = Properties.Resources.TBF_icon;
StartPosition = FormStartPosition.CenterParent;
MinimumSize = new Size(760, 500);
ClientSize = new Size(860, 560);
var root = new TableLayoutPanel { Dock = DockStyle.Fill, ColumnCount = 1, RowCount = 3, Padding = new Padding(10) };
root.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
root.RowStyles.Add(new RowStyle(SizeType.Absolute, 145F));
root.RowStyles.Add(new RowStyle(SizeType.Absolute, 42F));
var split = new SplitContainer { Dock = DockStyle.Fill, SplitterDistance = 280 };
split.Panel1.Padding = new Padding(0, 0, 8, 0);
split.Panel2.Padding = new Padding(8, 0, 0, 0);
ruleList.Dock = DockStyle.Fill;
ruleList.IntegralHeight = false;
ruleList.SelectedIndexChanged += RuleList_SelectedIndexChanged;
var listButtons = new FlowLayoutPanel { Dock = DockStyle.Bottom, Height = 36, FlowDirection = FlowDirection.LeftToRight };
listButtons.Controls.Add(CreateButton("Add", AddRule_Click));
listButtons.Controls.Add(CreateButton("Delete", DeleteRule_Click));
listButtons.Controls.Add(CreateButton("Up", MoveUp_Click));
listButtons.Controls.Add(CreateButton("Down", MoveDown_Click));
split.Panel1.Controls.Add(ruleList);
split.Panel1.Controls.Add(listButtons);
var editor = new TableLayoutPanel { Dock = DockStyle.Top, AutoSize = true, ColumnCount = 2, Padding = new Padding(4) };
editor.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 120F));
editor.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
enabledCheckBox.Text = "Rule enabled";
enabledCheckBox.AutoSize = true;
enabledCheckBox.CheckedChanged += EditorValueChanged;
AddEditorRow(editor, "State", enabledCheckBox);
patternTextBox.Dock = DockStyle.Fill;
patternTextBox.TextChanged += EditorValueChanged;
AddEditorRow(editor, "Substring", patternTextBox);
foregroundButton.Text = "Choose text color...";
foregroundButton.AutoSize = true;
foregroundButton.Click += ForegroundButton_Click;
AddEditorRow(editor, "Text color", foregroundButton);
var backgroundPanel = new FlowLayoutPanel { Dock = DockStyle.Fill, AutoSize = true };
backgroundCheckBox.Text = "Use background";
backgroundCheckBox.AutoSize = true;
backgroundCheckBox.CheckedChanged += EditorValueChanged;
backgroundButton.Text = "Choose...";
backgroundButton.AutoSize = true;
backgroundButton.Click += BackgroundButton_Click;
backgroundPanel.Controls.Add(backgroundCheckBox);
backgroundPanel.Controls.Add(backgroundButton);
AddEditorRow(editor, "Background", backgroundPanel);
boldCheckBox.Text = "Bold text";
boldCheckBox.AutoSize = true;
boldCheckBox.CheckedChanged += EditorValueChanged;
AddEditorRow(editor, "Font", boldCheckBox);
var resetButton = CreateButton("Restore default rules", RestoreDefaults_Click);
resetButton.AutoSize = true;
AddEditorRow(editor, string.Empty, resetButton);
split.Panel2.Controls.Add(editor);
previewBox.Dock = DockStyle.Fill;
previewBox.ReadOnly = true;
previewBox.WordWrap = true;
previewBox.Font = new Font("Consolas", 9F);
previewBox.Text = "2026-09-10 14:25:31.042|DEBUG|TBF[14280]|TBF.UI.MainWnd|Device configuration loaded.\n2026-09-10 14:25:31.384|INFO |TBF[14280]|TBF.Rig.StateMachine|Test bench started.\n2026-09-10 14:25:32.018|WARN |TBF[14280]|TBF.Device|Pressure is approaching the limit.\n2026-09-10 14:25:32.611|ERROR|TBF[14280]|TBF.Device|Communication failed.";
var previewGroup = new GroupBox { Text = "Live preview", Dock = DockStyle.Fill, Padding = new Padding(8) };
previewGroup.Controls.Add(previewBox);
var footer = new FlowLayoutPanel { Dock = DockStyle.Fill, FlowDirection = FlowDirection.RightToLeft, Padding = new Padding(0, 8, 0, 0) };
var okButton = new Button { Text = "OK", DialogResult = DialogResult.OK, AutoSize = true };
var cancelButton = new Button { Text = "Cancel", DialogResult = DialogResult.Cancel, AutoSize = true };
footer.Controls.Add(okButton);
footer.Controls.Add(cancelButton);
AcceptButton = okButton;
CancelButton = cancelButton;
root.Controls.Add(split, 0, 0);
root.Controls.Add(previewGroup, 0, 1);
root.Controls.Add(footer, 0, 2);
Controls.Add(root);
}
private static Button CreateButton(string text, EventHandler clickHandler)
{
var button = new Button { Text = text, AutoSize = true };
button.Click += clickHandler;
return button;
}
private static void AddEditorRow(TableLayoutPanel panel, string labelText, Control control)
{
int row = panel.RowCount++;
panel.RowStyles.Add(new RowStyle(SizeType.AutoSize));
var label = new Label { Text = labelText, AutoSize = true, Anchor = AnchorStyles.Left, Margin = new Padding(3, 8, 3, 3) };
control.Margin = new Padding(3, 5, 3, 5);
panel.Controls.Add(label, 0, row);
panel.Controls.Add(control, 1, row);
}
private void RefreshRuleList(int selectedIndex)
{
ruleList.BeginUpdate();
ruleList.Items.Clear();
foreach (LogColorRule rule in rules)
{
ruleList.Items.Add(rule);
}
ruleList.EndUpdate();
if (rules.Count > 0)
{
ruleList.SelectedIndex = Math.Max(0, Math.Min(selectedIndex, rules.Count - 1));
}
}
private void RuleList_SelectedIndexChanged(object sender, EventArgs e)
{
LogColorRule rule = ruleList.SelectedItem as LogColorRule;
if (rule == null)
{
return;
}
loadingRule = true;
enabledCheckBox.Checked = rule.Enabled;
patternTextBox.Text = rule.Pattern;
foregroundButton.BackColor = rule.ForeColor;
backgroundCheckBox.Checked = rule.UseBackColor;
backgroundButton.Enabled = rule.UseBackColor;
backgroundButton.BackColor = rule.UseBackColor ? rule.BackColor : SystemColors.Control;
boldCheckBox.Checked = rule.Bold;
loadingRule = false;
}
private void EditorValueChanged(object sender, EventArgs e)
{
if (loadingRule)
{
return;
}
LogColorRule rule = ruleList.SelectedItem as LogColorRule;
if (rule == null)
{
return;
}
rule.Enabled = enabledCheckBox.Checked;
rule.Pattern = patternTextBox.Text;
rule.UseBackColor = backgroundCheckBox.Checked;
rule.Bold = boldCheckBox.Checked;
backgroundButton.Enabled = rule.UseBackColor;
int index = ruleList.SelectedIndex;
RefreshRuleList(index);
RefreshPreview();
}
private void ForegroundButton_Click(object sender, EventArgs e)
{
LogColorRule rule = ruleList.SelectedItem as LogColorRule;
if (rule == null)
{
return;
}
using (var dialog = new ColorDialog { Color = rule.ForeColor, FullOpen = true })
{
if (dialog.ShowDialog(this) != DialogResult.OK)
{
return;
}
rule.ForeColorArgb = dialog.Color.ToArgb();
foregroundButton.BackColor = dialog.Color;
RefreshPreview();
}
}
private void BackgroundButton_Click(object sender, EventArgs e)
{
LogColorRule rule = ruleList.SelectedItem as LogColorRule;
if (rule == null)
{
return;
}
Color initialColor = rule.UseBackColor ? rule.BackColor : SystemColors.Window;
using (var dialog = new ColorDialog { Color = initialColor, FullOpen = true })
{
if (dialog.ShowDialog(this) != DialogResult.OK)
{
return;
}
rule.BackColorArgb = dialog.Color.ToArgb();
rule.UseBackColor = true;
backgroundCheckBox.Checked = true;
backgroundButton.BackColor = dialog.Color;
RefreshPreview();
}
}
private void AddRule_Click(object sender, EventArgs e)
{
rules.Add(new LogColorRule { Pattern = "NEW SUBSTRING", ForeColorArgb = Color.MediumPurple.ToArgb() });
RefreshRuleList(rules.Count - 1);
patternTextBox.Focus();
patternTextBox.SelectAll();
}
private void DeleteRule_Click(object sender, EventArgs e)
{
int index = ruleList.SelectedIndex;
if (index < 0)
{
return;
}
rules.RemoveAt(index);
RefreshRuleList(Math.Min(index, rules.Count - 1));
RefreshPreview();
}
private void MoveUp_Click(object sender, EventArgs e)
{
MoveSelectedRule(-1);
}
private void MoveDown_Click(object sender, EventArgs e)
{
MoveSelectedRule(1);
}
private void MoveSelectedRule(int offset)
{
int index = ruleList.SelectedIndex;
int newIndex = index + offset;
if (index < 0 || newIndex < 0 || newIndex >= rules.Count)
{
return;
}
LogColorRule rule = rules[index];
rules.RemoveAt(index);
rules.Insert(newIndex, rule);
RefreshRuleList(newIndex);
RefreshPreview();
}
private void RestoreDefaults_Click(object sender, EventArgs e)
{
rules.Clear();
rules.AddRange(LogColorRule.CreateDefaults());
RefreshRuleList(0);
RefreshPreview();
}
private void RefreshPreview()
{
int selectionStart = previewBox.SelectionStart;
int selectionLength = previewBox.SelectionLength;
string text = previewBox.Text;
LogColorizer.Apply(previewBox, 0, text.Length, text, rules, previewBox.Font, previewBoldFont);
previewBox.Select(Math.Min(selectionStart, previewBox.TextLength), Math.Min(selectionLength, Math.Max(0, previewBox.TextLength - selectionStart)));
}
}
}
+24
View File
@@ -0,0 +1,24 @@
using AppDiagnostic.Logging;
using System;
namespace AppDiagnostic
{
public static class DiagnosticLogFormatter
{
public static string Format(DiagnosticLogEntry entry)
{
if (entry == null)
{
return string.Empty;
}
string level = (entry.Level ?? string.Empty).ToUpperInvariant().PadRight(5);
string application = string.IsNullOrWhiteSpace(entry.ApplicationName) ? "Unknown" : entry.ApplicationName;
string logger = entry.LoggerName ?? string.Empty;
string message = entry.Message ?? string.Empty;
string exception = string.IsNullOrWhiteSpace(entry.Exception) ? string.Empty : Environment.NewLine + entry.Exception;
return $"{entry.TimestampUtc.ToLocalTime():yyyy-MM-dd HH:mm:ss.fff}|{level}|{application}[{entry.ProcessId}]|{logger}|{message}{exception}";
}
}
}
+82
View File
@@ -0,0 +1,82 @@
using AppDiagnostic.Logging;
using System.Collections.Generic;
using System.Linq;
namespace AppDiagnostic
{
public sealed class DiagnosticLogStore
{
private const int MaximumLogCount = 10000;
private static readonly DiagnosticLogStore instance = new DiagnosticLogStore();
private readonly object syncRoot = new object();
private readonly List<DiagnosticLogEntry> entries = new List<DiagnosticLogEntry>();
private long totalReceived;
private long version;
private DiagnosticLogStore()
{
}
public static DiagnosticLogStore Instance => instance;
public long TotalReceived
{
get
{
lock (syncRoot)
{
return totalReceived;
}
}
}
public long Version
{
get
{
lock (syncRoot)
{
return version;
}
}
}
public void Add(DiagnosticLogEntry entry)
{
if (entry == null)
{
return;
}
lock (syncRoot)
{
entries.Add(entry);
totalReceived++;
version++;
int excessCount = entries.Count - MaximumLogCount;
if (excessCount > 0)
{
entries.RemoveRange(0, excessCount);
}
}
}
public List<DiagnosticLogEntry> GetSnapshot()
{
lock (syncRoot)
{
return entries.ToList();
}
}
public void Clear()
{
lock (syncRoot)
{
entries.Clear();
version++;
}
}
}
}
+164
View File
@@ -0,0 +1,164 @@
using AppDiagnostic.Logging;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Pipes;
using System.Threading;
using System.Threading.Tasks;
namespace AppDiagnostic
{
public sealed class DiagnosticPipeServer : IDisposable
{
private readonly Action<DiagnosticLogEntry> messageReceived;
private readonly CancellationTokenSource cancellation = new CancellationTokenSource();
private readonly object syncRoot = new object();
private readonly List<NamedPipeServerStream> connectedClients = new List<NamedPipeServerStream>();
private NamedPipeServerStream waitingServer;
private Task serverTask;
public DiagnosticPipeServer(Action<DiagnosticLogEntry> messageReceived)
{
this.messageReceived = messageReceived ?? throw new ArgumentNullException(nameof(messageReceived));
}
public int ConnectedClientCount
{
get
{
lock (syncRoot)
{
return connectedClients.Count;
}
}
}
public void Start()
{
if (serverTask != null)
{
return;
}
serverTask = Task.Run((Action)AcceptConnections);
}
private void AcceptConnections()
{
while (!cancellation.IsCancellationRequested)
{
NamedPipeServerStream server = null;
try
{
server = new NamedPipeServerStream(DiagnosticProtocol.DefaultPipeName, PipeDirection.In, NamedPipeServerStream.MaxAllowedServerInstances, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);
lock (syncRoot)
{
waitingServer = server;
}
server.WaitForConnection();
lock (syncRoot)
{
waitingServer = null;
connectedClients.Add(server);
}
NamedPipeServerStream connectedServer = server;
server = null;
Task.Run(() => ReadClient(connectedServer));
}
catch (ObjectDisposedException)
{
if (!cancellation.IsCancellationRequested)
{
throw;
}
}
catch (IOException)
{
if (!cancellation.IsCancellationRequested)
{
Thread.Sleep(250);
}
}
finally
{
lock (syncRoot)
{
if (ReferenceEquals(waitingServer, server))
{
waitingServer = null;
}
}
server?.Dispose();
}
}
}
private void ReadClient(NamedPipeServerStream client)
{
try
{
while (client.IsConnected && !cancellation.IsCancellationRequested)
{
DiagnosticLogEntry entry = DiagnosticMessageSerializer.ReadFramed(client);
messageReceived(entry);
}
}
catch (EndOfStreamException)
{
// The producer application was closed.
}
catch (IOException)
{
// The producer application disconnected.
}
catch (ObjectDisposedException)
{
// The diagnostic application is shutting down.
}
finally
{
lock (syncRoot)
{
connectedClients.Remove(client);
}
client.Dispose();
}
}
public void Dispose()
{
cancellation.Cancel();
lock (syncRoot)
{
waitingServer?.Dispose();
waitingServer = null;
foreach (NamedPipeServerStream client in connectedClients.ToArray())
{
client.Dispose();
}
connectedClients.Clear();
}
try
{
serverTask?.Wait(2000);
}
catch (AggregateException)
{
// Cancellation during shutdown is expected.
}
cancellation.Dispose();
}
}
}
+65
View File
@@ -0,0 +1,65 @@
using System;
using System.Collections.Generic;
using System.Drawing;
namespace AppDiagnostic
{
[Serializable]
public sealed class LogColorRule
{
public bool Enabled { get; set; } = true;
public string Pattern { get; set; } = string.Empty;
public int ForeColorArgb { get; set; } = Color.Black.ToArgb();
public int BackColorArgb { get; set; }
public bool UseBackColor { get; set; }
public bool Bold { get; set; }
public Color ForeColor => Color.FromArgb(ForeColorArgb);
public Color BackColor => Color.FromArgb(BackColorArgb);
public LogColorRule Clone()
{
return new LogColorRule
{
Enabled = Enabled,
Pattern = Pattern,
ForeColorArgb = ForeColorArgb,
BackColorArgb = BackColorArgb,
UseBackColor = UseBackColor,
Bold = Bold
};
}
public override string ToString()
{
string state = Enabled ? string.Empty : "[disabled] ";
return state + Pattern;
}
public static List<LogColorRule> CreateDefaults()
{
return new List<LogColorRule>
{
Create("|TRACE|", Color.DimGray, false),
Create("|DEBUG|", Color.RoyalBlue, false),
Create("|INFO |", Color.ForestGreen, false),
Create("|WARN |", Color.DarkOrange, true),
Create("|ERROR|", Color.Crimson, true),
Create("|FATAL|", Color.White, true, Color.DarkRed)
};
}
private static LogColorRule Create(string pattern, Color foreground, bool bold, Color? background = null)
{
return new LogColorRule
{
Enabled = true,
Pattern = pattern,
ForeColorArgb = foreground.ToArgb(),
BackColorArgb = background?.ToArgb() ?? Color.Empty.ToArgb(),
UseBackColor = background.HasValue,
Bold = bold
};
}
}
}
+46
View File
@@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;
namespace AppDiagnostic
{
public static class LogColorRuleRepository
{
private static readonly string settingsFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Sensus", "AppDiagnostic");
private static readonly string settingsPath = Path.Combine(settingsFolder, "color-rules.xml");
public static List<LogColorRule> Load()
{
try
{
if (!File.Exists(settingsPath))
{
return LogColorRule.CreateDefaults();
}
var serializer = new XmlSerializer(typeof(List<LogColorRule>));
using (FileStream stream = File.OpenRead(settingsPath))
{
var rules = serializer.Deserialize(stream) as List<LogColorRule>;
return rules == null || rules.Count == 0 ? LogColorRule.CreateDefaults() : rules;
}
}
catch
{
return LogColorRule.CreateDefaults();
}
}
public static void Save(IEnumerable<LogColorRule> rules)
{
Directory.CreateDirectory(settingsFolder);
var serializer = new XmlSerializer(typeof(List<LogColorRule>));
using (FileStream stream = File.Create(settingsPath))
{
serializer.Serialize(stream, new List<LogColorRule>(rules));
}
}
}
}
+47
View File
@@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
namespace AppDiagnostic
{
public static class LogColorizer
{
public static void Apply(RichTextBox target, int startIndex, int length, string text, IEnumerable<LogColorRule> rules, Font regularFont, Font boldFont)
{
if (target == null || length <= 0)
{
return;
}
target.Select(startIndex, length);
target.SelectionColor = target.ForeColor;
target.SelectionBackColor = target.BackColor;
target.SelectionFont = regularFont;
foreach (LogColorRule rule in rules)
{
if (rule == null || !rule.Enabled || string.IsNullOrEmpty(rule.Pattern))
{
continue;
}
int searchIndex = 0;
while (searchIndex < text.Length)
{
int matchIndex = text.IndexOf(rule.Pattern, searchIndex, StringComparison.OrdinalIgnoreCase);
if (matchIndex < 0)
{
break;
}
target.Select(startIndex + matchIndex, rule.Pattern.Length);
target.SelectionColor = rule.ForeColor;
target.SelectionBackColor = rule.UseBackColor ? rule.BackColor : target.BackColor;
target.SelectionFont = rule.Bold ? boldFont : regularFont;
searchIndex = matchIndex + rule.Pattern.Length;
}
}
}
}
}
+245 -214
View File
@@ -1,278 +1,309 @@
using System.Windows.Forms;
namespace AppDiagnostic
{
partial class MainForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
private System.Windows.Forms.ToolStrip mainToolStrip;
private System.Windows.Forms.ToolStripButton pauseButton;
private System.Windows.Forms.ToolStripButton refreshButton;
private System.Windows.Forms.ToolStripButton clearButton;
private System.Windows.Forms.ToolStripButton saveButton;
private System.Windows.Forms.ToolStripButton copyButton;
private System.Windows.Forms.ToolStripButton copyAllButton;
private System.Windows.Forms.ToolStripButton wrapButton;
private System.Windows.Forms.ToolStripButton autoScrollButton;
private System.Windows.Forms.ToolStripButton alwaysOnTopButton;
private System.Windows.Forms.ToolStripButton colorRulesButton;
private System.Windows.Forms.ToolStripButton closeButton;
private System.Windows.Forms.TableLayoutPanel filterPanel;
private System.Windows.Forms.Label filterLabel;
private System.Windows.Forms.TextBox filterTextBox;
private System.Windows.Forms.Label levelLabel;
private System.Windows.Forms.ComboBox levelComboBox;
private System.Windows.Forms.Label applicationLabel;
private System.Windows.Forms.ComboBox applicationComboBox;
private System.Windows.Forms.Button applyFilterButton;
private System.Windows.Forms.Button clearFilterButton;
private System.Windows.Forms.RichTextBox logView;
private System.Windows.Forms.StatusStrip statusStrip;
private System.Windows.Forms.ToolStripStatusLabel receiverStatusLabel;
private System.Windows.Forms.ToolStripStatusLabel statusSpacer;
private System.Windows.Forms.ToolStripStatusLabel countStatusLabel;
private System.Windows.Forms.ContextMenuStrip logContextMenu;
private System.Windows.Forms.ToolStripMenuItem copySelectionMenuItem;
private System.Windows.Forms.ToolStripMenuItem copyLineMenuItem;
private System.Windows.Forms.ToolStripMenuItem copyAllMenuItem;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
if (disposing && components != null)
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
//private BufferedListView memoListView;
private System.Windows.Forms.ColumnHeader columnHeaderTime;
private System.Windows.Forms.ColumnHeader columnHeaderMessage;
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.columnHeaderTime = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeaderMessage = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.panel1 = new System.Windows.Forms.Panel();
this.refreshMemoButton = new System.Windows.Forms.Button();
this.button6 = new System.Windows.Forms.Button();
this.button7 = new System.Windows.Forms.Button();
this.filterManagementPanel = new System.Windows.Forms.Panel();
this.button5 = new System.Windows.Forms.Button();
this.filterButton = new System.Windows.Forms.Button();
this.components = new System.ComponentModel.Container();
this.mainToolStrip = new System.Windows.Forms.ToolStrip();
this.pauseButton = new System.Windows.Forms.ToolStripButton();
this.refreshButton = new System.Windows.Forms.ToolStripButton();
this.clearButton = new System.Windows.Forms.ToolStripButton();
this.saveButton = new System.Windows.Forms.ToolStripButton();
this.copyButton = new System.Windows.Forms.ToolStripButton();
this.copyAllButton = new System.Windows.Forms.ToolStripButton();
this.wrapButton = new System.Windows.Forms.ToolStripButton();
this.autoScrollButton = new System.Windows.Forms.ToolStripButton();
this.alwaysOnTopButton = new System.Windows.Forms.ToolStripButton();
this.colorRulesButton = new System.Windows.Forms.ToolStripButton();
this.closeButton = new System.Windows.Forms.ToolStripButton();
this.filterPanel = new System.Windows.Forms.TableLayoutPanel();
this.filterLabel = new System.Windows.Forms.Label();
this.filterTextBox = new System.Windows.Forms.TextBox();
this.label2 = new System.Windows.Forms.Label();
this.wndControlPanel = new System.Windows.Forms.Panel();
this.button2 = new System.Windows.Forms.Button();
this.flowControlsPanel = new System.Windows.Forms.Panel();
this.runButton = new System.Windows.Forms.Button();
this.stopButton = new System.Windows.Forms.Button();
this.label1 = new System.Windows.Forms.Label();
this.memoListView = new BufferedListView();
this.panel1.SuspendLayout();
this.filterManagementPanel.SuspendLayout();
this.wndControlPanel.SuspendLayout();
this.flowControlsPanel.SuspendLayout();
this.levelLabel = new System.Windows.Forms.Label();
this.levelComboBox = new System.Windows.Forms.ComboBox();
this.applicationLabel = new System.Windows.Forms.Label();
this.applicationComboBox = new System.Windows.Forms.ComboBox();
this.applyFilterButton = new System.Windows.Forms.Button();
this.clearFilterButton = new System.Windows.Forms.Button();
this.logContextMenu = new System.Windows.Forms.ContextMenuStrip(this.components);
this.copySelectionMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.copyLineMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.copyAllMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.logView = new System.Windows.Forms.RichTextBox();
this.statusStrip = new System.Windows.Forms.StatusStrip();
this.receiverStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
this.statusSpacer = new System.Windows.Forms.ToolStripStatusLabel();
this.countStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
this.mainToolStrip.SuspendLayout();
this.filterPanel.SuspendLayout();
this.logContextMenu.SuspendLayout();
this.statusStrip.SuspendLayout();
this.SuspendLayout();
//
// columnHeaderTime
// mainToolStrip
//
this.columnHeaderTime.Text = "Time";
this.columnHeaderTime.Width = 150;
this.mainToolStrip.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden;
this.mainToolStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.pauseButton,
this.refreshButton,
this.clearButton,
this.saveButton,
new System.Windows.Forms.ToolStripSeparator(),
this.copyButton,
this.copyAllButton,
new System.Windows.Forms.ToolStripSeparator(),
this.wrapButton,
this.autoScrollButton,
this.alwaysOnTopButton,
this.colorRulesButton,
this.closeButton});
this.mainToolStrip.Location = new System.Drawing.Point(0, 0);
this.mainToolStrip.Name = "mainToolStrip";
this.mainToolStrip.Padding = new System.Windows.Forms.Padding(6, 3, 6, 3);
this.mainToolStrip.Size = new System.Drawing.Size(1184, 31);
this.mainToolStrip.TabIndex = 0;
//
// columnHeaderMessage
// pauseButton
//
this.columnHeaderMessage.Text = "Message";
this.columnHeaderMessage.Width = 350;
this.pauseButton.CheckOnClick = true;
this.pauseButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
this.pauseButton.Text = "Pause";
this.pauseButton.ToolTipText = "Pause screen updates while continuing to receive logs";
this.pauseButton.Click += new System.EventHandler(this.pauseButton_Click);
//
// panel1
// refreshButton
//
this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.panel1.Controls.Add(this.refreshMemoButton);
this.panel1.Controls.Add(this.button6);
this.panel1.Controls.Add(this.button7);
this.panel1.Location = new System.Drawing.Point(189, 356);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(283, 26);
this.panel1.TabIndex = 16;
this.refreshButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
this.refreshButton.Text = "Refresh";
this.refreshButton.Click += new System.EventHandler(this.refreshButton_Click);
//
// refreshMemoButton
// clearButton
//
this.refreshMemoButton.Location = new System.Drawing.Point(108, 0);
this.refreshMemoButton.Name = "refreshMemoButton";
this.refreshMemoButton.Size = new System.Drawing.Size(84, 26);
this.refreshMemoButton.TabIndex = 17;
this.refreshMemoButton.Text = "Refresh memo";
this.refreshMemoButton.UseVisualStyleBackColor = true;
this.refreshMemoButton.Click += new System.EventHandler(this.refreshMemoButton_Click);
this.clearButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
this.clearButton.Text = "Clear";
this.clearButton.Click += new System.EventHandler(this.clearButton_Click);
//
// button6
// saveButton
//
this.button6.Location = new System.Drawing.Point(0, 0);
this.button6.Name = "button6";
this.button6.Size = new System.Drawing.Size(102, 26);
this.button6.TabIndex = 4;
this.button6.Text = "Clean diag cache";
this.button6.UseVisualStyleBackColor = true;
this.button6.Click += new System.EventHandler(this.button6_Click);
this.saveButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
this.saveButton.Text = "Save...";
this.saveButton.Click += new System.EventHandler(this.saveButton_Click);
//
// button7
// copyButton
//
this.button7.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.button7.Location = new System.Drawing.Point(198, 0);
this.button7.Name = "button7";
this.button7.Size = new System.Drawing.Size(72, 26);
this.button7.TabIndex = 5;
this.button7.Text = "Save logs";
this.button7.UseVisualStyleBackColor = true;
this.button7.Click += new System.EventHandler(this.button7_Click);
this.copyButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
this.copyButton.Text = "Copy";
this.copyButton.ToolTipText = "Copy selected text or the current log line";
this.copyButton.Click += new System.EventHandler(this.copyButton_Click);
//
// filterManagementPanel
// copyAllButton
//
this.filterManagementPanel.Controls.Add(this.button5);
this.filterManagementPanel.Controls.Add(this.filterButton);
this.filterManagementPanel.Controls.Add(this.filterTextBox);
this.filterManagementPanel.Controls.Add(this.label2);
this.filterManagementPanel.Location = new System.Drawing.Point(127, 6);
this.filterManagementPanel.Name = "filterManagementPanel";
this.filterManagementPanel.Size = new System.Drawing.Size(393, 26);
this.filterManagementPanel.TabIndex = 15;
this.copyAllButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
this.copyAllButton.Text = "Copy all";
this.copyAllButton.Click += new System.EventHandler(this.copyAllButton_Click);
//
// button5
// wrapButton
//
this.button5.Enabled = false;
this.button5.Location = new System.Drawing.Point(294, 4);
this.button5.Name = "button5";
this.button5.Size = new System.Drawing.Size(81, 20);
this.button5.TabIndex = 11;
this.button5.Text = "Add new filter";
this.button5.UseVisualStyleBackColor = true;
this.wrapButton.Checked = true;
this.wrapButton.CheckOnClick = true;
this.wrapButton.CheckState = System.Windows.Forms.CheckState.Checked;
this.wrapButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
this.wrapButton.Text = "Wrap lines";
this.wrapButton.Click += new System.EventHandler(this.wrapButton_Click);
//
// filterButton
// autoScrollButton
//
this.filterButton.Location = new System.Drawing.Point(225, 4);
this.filterButton.Name = "filterButton";
this.filterButton.Size = new System.Drawing.Size(64, 20);
this.filterButton.TabIndex = 10;
this.filterButton.Text = "Set filter";
this.filterButton.UseVisualStyleBackColor = true;
this.filterButton.Click += new System.EventHandler(this.filterButton_Click_1);
this.autoScrollButton.Checked = true;
this.autoScrollButton.CheckOnClick = true;
this.autoScrollButton.CheckState = System.Windows.Forms.CheckState.Checked;
this.autoScrollButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
this.autoScrollButton.Text = "Auto-scroll";
//
// filterTextBox
// alwaysOnTopButton
//
this.filterTextBox.Location = new System.Drawing.Point(33, 4);
this.filterTextBox.Name = "filterTextBox";
this.filterTextBox.Size = new System.Drawing.Size(187, 20);
this.filterTextBox.TabIndex = 7;
this.alwaysOnTopButton.CheckOnClick = true;
this.alwaysOnTopButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
this.alwaysOnTopButton.Text = "Always on top";
this.alwaysOnTopButton.Click += new System.EventHandler(this.alwaysOnTopButton_Click);
//
// label2
// colorRulesButton
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(3, 8);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(29, 13);
this.label2.TabIndex = 6;
this.label2.Text = "Filter";
this.colorRulesButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
this.colorRulesButton.Text = "Color rules...";
this.colorRulesButton.Click += new System.EventHandler(this.colorRulesButton_Click);
//
// wndControlPanel
// closeButton
//
this.wndControlPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.wndControlPanel.Controls.Add(this.button2);
this.wndControlPanel.Location = new System.Drawing.Point(831, 356);
this.wndControlPanel.Name = "wndControlPanel";
this.wndControlPanel.Size = new System.Drawing.Size(70, 26);
this.wndControlPanel.TabIndex = 14;
this.closeButton.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right;
this.closeButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
this.closeButton.Text = "Close";
this.closeButton.Click += new System.EventHandler(this.closeButton_Click);
//
// button2
// filterPanel
//
this.button2.Location = new System.Drawing.Point(3, 0);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(64, 26);
this.button2.TabIndex = 2;
this.button2.Text = "Close";
this.button2.UseVisualStyleBackColor = true;
this.button2.Click += new System.EventHandler(this.button2_Click);
this.filterPanel.ColumnCount = 8;
this.filterPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 42F));
this.filterPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.filterPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 42F));
this.filterPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 105F));
this.filterPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 72F));
this.filterPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 180F));
this.filterPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 66F));
this.filterPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 66F));
this.filterPanel.Controls.Add(this.filterLabel, 0, 0);
this.filterPanel.Controls.Add(this.filterTextBox, 1, 0);
this.filterPanel.Controls.Add(this.levelLabel, 2, 0);
this.filterPanel.Controls.Add(this.levelComboBox, 3, 0);
this.filterPanel.Controls.Add(this.applicationLabel, 4, 0);
this.filterPanel.Controls.Add(this.applicationComboBox, 5, 0);
this.filterPanel.Controls.Add(this.applyFilterButton, 6, 0);
this.filterPanel.Controls.Add(this.clearFilterButton, 7, 0);
this.filterPanel.Dock = System.Windows.Forms.DockStyle.Top;
this.filterPanel.Location = new System.Drawing.Point(0, 31);
this.filterPanel.Name = "filterPanel";
this.filterPanel.Padding = new System.Windows.Forms.Padding(6, 5, 6, 5);
this.filterPanel.RowCount = 1;
this.filterPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.filterPanel.Size = new System.Drawing.Size(1184, 38);
this.filterPanel.TabIndex = 1;
//
// flowControlsPanel
// filter controls
//
this.flowControlsPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.flowControlsPanel.Controls.Add(this.runButton);
this.flowControlsPanel.Controls.Add(this.stopButton);
this.flowControlsPanel.Location = new System.Drawing.Point(12, 356);
this.flowControlsPanel.Name = "flowControlsPanel";
this.flowControlsPanel.Size = new System.Drawing.Size(133, 26);
this.flowControlsPanel.TabIndex = 13;
this.filterLabel.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.filterLabel.AutoSize = true;
this.filterLabel.Text = "Filter";
this.filterTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.filterTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.filterTextBox_KeyDown);
this.levelLabel.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.levelLabel.AutoSize = true;
this.levelLabel.Text = "Level";
this.levelComboBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.levelComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.levelComboBox.SelectedIndexChanged += new System.EventHandler(this.filterValueChanged);
this.applicationLabel.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.applicationLabel.AutoSize = true;
this.applicationLabel.Text = "Application";
this.applicationComboBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.applicationComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.applicationComboBox.SelectedIndexChanged += new System.EventHandler(this.filterValueChanged);
this.applyFilterButton.Dock = System.Windows.Forms.DockStyle.Fill;
this.applyFilterButton.Text = "Apply";
this.applyFilterButton.Click += new System.EventHandler(this.applyFilterButton_Click);
this.clearFilterButton.Dock = System.Windows.Forms.DockStyle.Fill;
this.clearFilterButton.Text = "Reset";
this.clearFilterButton.Click += new System.EventHandler(this.clearFilterButton_Click);
//
// runButton
// logContextMenu
//
this.runButton.Enabled = false;
this.runButton.Location = new System.Drawing.Point(0, 0);
this.runButton.Name = "runButton";
this.runButton.Size = new System.Drawing.Size(64, 26);
this.runButton.TabIndex = 4;
this.runButton.Text = "Run";
this.runButton.UseVisualStyleBackColor = true;
this.runButton.Click += new System.EventHandler(this.runButton_Click);
this.logContextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.copySelectionMenuItem,
this.copyLineMenuItem,
this.copyAllMenuItem});
this.copySelectionMenuItem.Text = "Copy selection";
this.copySelectionMenuItem.Click += new System.EventHandler(this.copySelectionMenuItem_Click);
this.copyLineMenuItem.Text = "Copy current line";
this.copyLineMenuItem.Click += new System.EventHandler(this.copyLineMenuItem_Click);
this.copyAllMenuItem.Text = "Copy all visible logs";
this.copyAllMenuItem.Click += new System.EventHandler(this.copyAllButton_Click);
//
// stopButton
// logView
//
this.stopButton.Location = new System.Drawing.Point(69, 0);
this.stopButton.Name = "stopButton";
this.stopButton.Size = new System.Drawing.Size(64, 26);
this.stopButton.TabIndex = 5;
this.stopButton.Text = "Stop";
this.stopButton.UseVisualStyleBackColor = true;
this.stopButton.Click += new System.EventHandler(this.stopButton_Click);
this.logView.BackColor = System.Drawing.SystemColors.Window;
this.logView.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.logView.ContextMenuStrip = this.logContextMenu;
this.logView.DetectUrls = false;
this.logView.Dock = System.Windows.Forms.DockStyle.Fill;
this.logView.Font = new System.Drawing.Font("Consolas", 9F);
this.logView.HideSelection = false;
this.logView.Location = new System.Drawing.Point(0, 69);
this.logView.Name = "logView";
this.logView.ReadOnly = true;
this.logView.Size = new System.Drawing.Size(1184, 554);
this.logView.TabIndex = 2;
this.logView.Text = "";
this.logView.WordWrap = true;
//
// label1
// statusStrip
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(12, 19);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(76, 13);
this.label1.TabIndex = 12;
this.label1.Text = "Flow of events";
//
// memoListView
//
this.memoListView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.memoListView.FullRowSelect = true;
this.memoListView.GridLines = true;
this.memoListView.HideSelection = false;
this.memoListView.Location = new System.Drawing.Point(12, 38);
this.memoListView.Name = "memoListView";
this.memoListView.Size = new System.Drawing.Size(889, 312);
this.memoListView.TabIndex = 0;
this.memoListView.UseCompatibleStateImageBehavior = false;
this.memoListView.View = System.Windows.Forms.View.Details;
this.memoListView.DoubleClick += new System.EventHandler(this.MemoListView_DoubleClick);
this.statusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.receiverStatusLabel,
this.statusSpacer,
this.countStatusLabel});
this.statusStrip.Location = new System.Drawing.Point(0, 623);
this.statusStrip.Name = "statusStrip";
this.statusStrip.Size = new System.Drawing.Size(1184, 22);
this.statusStrip.TabIndex = 3;
this.receiverStatusLabel.Text = "Listening";
this.statusSpacer.Spring = true;
this.countStatusLabel.Text = "Received: 0 | Visible: 0";
//
// MainForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(913, 388);
this.Controls.Add(this.memoListView);
this.Controls.Add(this.panel1);
this.Controls.Add(this.filterManagementPanel);
this.Controls.Add(this.wndControlPanel);
this.Controls.Add(this.flowControlsPanel);
this.Controls.Add(this.label1);
this.ClientSize = new System.Drawing.Size(1184, 645);
this.Controls.Add(this.logView);
this.Controls.Add(this.filterPanel);
this.Controls.Add(this.mainToolStrip);
this.Controls.Add(this.statusStrip);
this.KeyPreview = true;
this.MinimumSize = new System.Drawing.Size(860, 480);
this.Name = "MainForm";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Application live diagnostic";
this.panel1.ResumeLayout(false);
this.filterManagementPanel.ResumeLayout(false);
this.filterManagementPanel.PerformLayout();
this.wndControlPanel.ResumeLayout(false);
this.flowControlsPanel.ResumeLayout(false);
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.MainForm_KeyDown);
this.mainToolStrip.ResumeLayout(false);
this.mainToolStrip.PerformLayout();
this.filterPanel.ResumeLayout(false);
this.filterPanel.PerformLayout();
this.logContextMenu.ResumeLayout(false);
this.statusStrip.ResumeLayout(false);
this.statusStrip.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Button button6;
private System.Windows.Forms.Button button7;
private System.Windows.Forms.Panel filterManagementPanel;
private System.Windows.Forms.Button button5;
private System.Windows.Forms.Button filterButton;
private System.Windows.Forms.TextBox filterTextBox;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Panel wndControlPanel;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.Panel flowControlsPanel;
private System.Windows.Forms.Button runButton;
private System.Windows.Forms.Button stopButton;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Button refreshMemoButton;
private BufferedListView memoListView;
}
}
+392 -214
View File
@@ -1,267 +1,445 @@
using log4net.Config;
using log4net;
using AppDiagnostic.Logging;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using log4net.Appender;
using SharedComponents;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using System.IO; // Pre File.WriteAllLines a prácu so súbormi
using System.Linq;
namespace AppDiagnostic
{
public partial class MainForm : Form
{
private bool stopUpdate = false; // Premenná na zastavenie aktualizácie
private int lastDisplayedLogIndex = 0;
private bool autoScrollEnabled = true; // Automatický posun, predvolene povolený
private MainForm appDiagnosticForm;
private Timer refreshTimer;
private LogAdapter _logAdapter; // Pre LogAdapter
private LogFilter _logFilter; // LogFilter objekt pre filtráciu
private readonly Func<int> connectedClientCountProvider;
private readonly Func<bool> activationRequestProvider;
private readonly Timer refreshTimer;
private readonly Font regularLogFont;
private readonly Font boldLogFont;
private List<LogColorRule> colorRules;
private long lastRenderedVersion = -1;
private int observedEntryCount;
private int visibleEntryCount;
private bool loadingFilters;
public MainForm()
public MainForm() : this(null, null)
{
this.Icon = Properties.Resources.TBF_icon;
}
public MainForm(Func<int> connectedClientCountProvider, Func<bool> activationRequestProvider)
{
this.connectedClientCountProvider = connectedClientCountProvider;
this.activationRequestProvider = activationRequestProvider;
InitializeComponent();
Icon = Properties.Resources.TBF_icon;
// Inicializujeme LogAdapter a priradíme ho k memoListView
_logAdapter = new LogAdapter(memoListView);
regularLogFont = new Font(logView.Font, FontStyle.Regular);
boldLogFont = new Font(logView.Font, FontStyle.Bold);
colorRules = LogColorRuleRepository.Load();
RefreshLogView();
InitializeFilters();
// Pripojenie na udalosť pri pridaní nového logu
// nakoľko sa memo refreshuje cyklicky, tak refresh na udalosť nepotrebujem
//LiveLogCache.Instance.LogAdded += OnLogAdded;
refreshTimer = new Timer { Interval = 250 };
refreshTimer.Tick += refreshTimer_Tick;
refreshTimer.Start();
// Vytvoríme LogFilter objekt
//_logFilter = new LogFilter(memoListView);
}
private void OnLogAdded(string log)
{
try
{
RefreshLogView();
}
catch (Exception ex)
{
MessageBox.Show($"Error in OnLogAdded: {ex.Message}");
throw;
}
}
private void RefreshLogView()
{
// Skontrolujte, či voláme z iného vlákna
if (InvokeRequired)
{
Invoke((Action)RefreshLogView);
return;
}
memoListView.BeginUpdate(); // Zabraňuje vizuálnym aktualizáciám počas vykresľovania
try
{
// Skontrolujte, či je užívateľ na poslednom viditeľnom zázname
if (memoListView.Items.Count > 0)
{
var lastVisibleIndex = memoListView.TopItem.Index + memoListView.ClientRectangle.Height / memoListView.Items[0].Bounds.Height;
autoScrollEnabled = lastVisibleIndex >= memoListView.Items.Count - 1;
}
// Získajte nové logy od posledného indexu
var logs = LiveLogCache.Instance.GetLogs(lastDisplayedLogIndex, LiveLogCache.Instance.Logs.Count - lastDisplayedLogIndex);
// Pridajte len nové logy
foreach (var log in logs)
{
memoListView.Items.Add(new ListViewItem(log));
}
// Aktualizujte posledný zobrazený index
lastDisplayedLogIndex = LiveLogCache.Instance.Logs.Count;
// Ak je autoScrollEnabled, posuňte sa na posledný záznam
if (autoScrollEnabled && memoListView.Items.Count > 0)
{
memoListView.EnsureVisible(memoListView.Items.Count - 1);
}
}
finally
{
memoListView.EndUpdate(); // Umožní vizuálne aktualizácie
}
}
// Táto metóda sa spustí pri scrollovaní v memoListView (tzn. ak sa používateľ dostane na spodok listu)
private void memoListView_Scroll(object sender, EventArgs e)
{
// Skontrolujte, či používateľ dosiahol spodok ListView
if (memoListView.Items.Count > 0 &&
memoListView.Items[memoListView.Items.Count - 1].Bounds.Bottom <= memoListView.ClientSize.Height)
{
// Ak áno, načítame ďalšie logy
RefreshLogView();
}
}
private void button6_Click(object sender, EventArgs e)
{
//LiveLogCache.Instance.AddLog("Nový log z hlavnej aplikácie");
LiveLogCache.Instance.ClearLogs();
ClearListView();
}
private void runButton_Click(object sender, EventArgs e)
{
if (stopUpdate) // Ak je časovač zastavený, spustíme ho
{
stopUpdate = false; // Zastav aktualizáciu
runButton.Enabled = false; // Zakážeme tlačidlo Start počas behu
stopButton.Enabled = true; // Povolenie tlačidla Stop
refreshTimer.Start();
}
}
private void stopButton_Click(object sender, EventArgs e)
{
if (!stopUpdate) // Ak časovač beží, môžeme ho zastaviť
{
stopUpdate = true; // Spusti aktualizáciu
runButton.Enabled = true; // Povolenie tlačidla Start
stopButton.Enabled = false; // Zakážeme tlačidlo Stop
refreshTimer.Stop();
}
}
private void ClearListView()
{
if (InvokeRequired)
{
Invoke(new Action(ClearListView));
return;
}
memoListView.Items.Clear();
}
private void refreshMemoButton_Click(object sender, EventArgs e)
{
}
private void button7_Click(object sender, EventArgs e)
{
SaveLogsToFile();
//LiveLogCache.Instance.AddLog("Toto je nový log.");
RefreshView(true);
}
protected override void OnFormClosing(FormClosingEventArgs e)
{
// Odpojenie udalosti, keď sa okno zatvára, inak môže po opätovnom spustení okna a pridaní nového itemu do listu zhhodiť program
// nakoľko sa memo refreshuje cyklicky, tak refresh na udalosť nepotrebujem
//LiveLogCache.Instance.LogAdded -= OnLogAdded;
_logAdapter = null;
refreshTimer.Stop();
refreshTimer.Dispose();
regularLogFont.Dispose();
boldLogFont.Dispose();
base.OnFormClosing(e);
}
private void filterButton_Click_1(object sender, EventArgs e)
private void InitializeFilters()
{
// Aplikujeme filter na základe textu z filterTextBox
string filterText = filterTextBox.Text;
//_logFilter.ApplyFilter(filterText); // Aplikovanie filtra
_logAdapter.ApplyFilter(filterText);
loadingFilters = true;
levelComboBox.Items.AddRange(new object[] { "All levels", "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL" });
levelComboBox.SelectedIndex = 0;
applicationComboBox.Items.Add("All applications");
applicationComboBox.SelectedIndex = 0;
loadingFilters = false;
}
private void SubForm_FormClosing(object sender, FormClosingEventArgs e)
private void refreshTimer_Tick(object sender, EventArgs e)
{
ProcessActivationRequest();
RefreshView(false);
}
private void ProcessActivationRequest()
{
if (activationRequestProvider == null || !activationRequestProvider())
{
return;
}
if (WindowState == FormWindowState.Minimized)
{
WindowState = FormWindowState.Normal;
}
Show();
BringToFront();
Activate();
}
private void RefreshView(bool forceFullRefresh)
{
List<DiagnosticLogEntry> snapshot = DiagnosticLogStore.Instance.GetSnapshot();
UpdateApplicationFilter(snapshot);
if (pauseButton.Checked)
{
UpdateStatus(snapshot.Count);
return;
}
long currentVersion = DiagnosticLogStore.Instance.Version;
if (!forceFullRefresh && currentVersion == lastRenderedVersion)
{
UpdateStatus(snapshot.Count);
return;
}
bool canAppend = !forceFullRefresh && snapshot.Count > observedEntryCount;
if (canAppend)
{
AppendEntries(snapshot.Skip(observedEntryCount));
}
else
{
RebuildView(snapshot);
}
observedEntryCount = snapshot.Count;
lastRenderedVersion = currentVersion;
UpdateStatus(snapshot.Count);
}
private void RebuildView(IEnumerable<DiagnosticLogEntry> entries)
{
logView.SuspendLayout();
logView.Clear();
visibleEntryCount = 0;
AppendEntries(entries, false);
logView.ResumeLayout();
if (autoScrollButton.Checked)
{
ScrollToEnd();
}
}
private void AppendEntries(IEnumerable<DiagnosticLogEntry> entries, bool scrollAfterAppend = true)
{
int originalSelectionStart = logView.SelectionStart;
int originalSelectionLength = logView.SelectionLength;
foreach (DiagnosticLogEntry entry in entries)
{
if (!MatchesFilter(entry))
{
continue;
}
AppendEntry(entry);
visibleEntryCount++;
}
if (scrollAfterAppend && autoScrollButton.Checked)
{
ScrollToEnd();
}
else if (!autoScrollButton.Checked)
{
int safeStart = Math.Min(originalSelectionStart, logView.TextLength);
int safeLength = Math.Min(originalSelectionLength, logView.TextLength - safeStart);
logView.Select(safeStart, safeLength);
}
}
private void AppendEntry(DiagnosticLogEntry entry)
{
string text = DiagnosticLogFormatter.Format(entry);
if (logView.TextLength > 0)
{
logView.AppendText(Environment.NewLine);
}
int startIndex = logView.TextLength;
logView.AppendText(text);
LogColorizer.Apply(logView, startIndex, text.Length, text, colorRules, regularLogFont, boldLogFont);
logView.Select(logView.TextLength, 0);
}
private bool MatchesFilter(DiagnosticLogEntry entry)
{
string selectedLevel = levelComboBox.SelectedItem as string;
if (!string.IsNullOrEmpty(selectedLevel) && selectedLevel != "All levels" && !string.Equals(entry.Level, selectedLevel, StringComparison.OrdinalIgnoreCase))
{
return false;
}
string selectedApplication = applicationComboBox.SelectedItem as string;
if (!string.IsNullOrEmpty(selectedApplication) && selectedApplication != "All applications" && !string.Equals(entry.ApplicationName, selectedApplication, StringComparison.OrdinalIgnoreCase))
{
return false;
}
string filter = filterTextBox.Text.Trim();
return filter.Length == 0 || DiagnosticLogFormatter.Format(entry).IndexOf(filter, StringComparison.OrdinalIgnoreCase) >= 0;
}
private void UpdateApplicationFilter(IEnumerable<DiagnosticLogEntry> entries)
{
string selectedApplication = applicationComboBox.SelectedItem as string ?? "All applications";
List<string> applications = entries.Select(entry => entry.ApplicationName).Where(name => !string.IsNullOrWhiteSpace(name)).Distinct(StringComparer.OrdinalIgnoreCase).OrderBy(name => name).ToList();
List<string> currentApplications = applicationComboBox.Items.Cast<string>().Skip(1).ToList();
if (applications.SequenceEqual(currentApplications, StringComparer.OrdinalIgnoreCase))
{
return;
}
loadingFilters = true;
applicationComboBox.BeginUpdate();
applicationComboBox.Items.Clear();
applicationComboBox.Items.Add("All applications");
applicationComboBox.Items.AddRange(applications.Cast<object>().ToArray());
applicationComboBox.SelectedItem = applicationComboBox.Items.Cast<string>().FirstOrDefault(item => string.Equals(item, selectedApplication, StringComparison.OrdinalIgnoreCase)) ?? "All applications";
applicationComboBox.EndUpdate();
loadingFilters = false;
}
private void UpdateStatus(int storedCount)
{
int clients = connectedClientCountProvider?.Invoke() ?? 0;
receiverStatusLabel.Text = pauseButton.Checked ? $"Paused | Connected sources: {clients}" : $"Listening | Connected sources: {clients}";
countStatusLabel.Text = $"Received: {DiagnosticLogStore.Instance.TotalReceived:N0} | Stored: {storedCount:N0} | Visible: {visibleEntryCount:N0}";
}
private void ScrollToEnd()
{
logView.Select(logView.TextLength, 0);
logView.ScrollToCaret();
}
private void pauseButton_Click(object sender, EventArgs e)
{
pauseButton.Text = pauseButton.Checked ? "Resume" : "Pause";
if (!pauseButton.Checked)
{
RefreshView(true);
}
else
{
UpdateStatus(DiagnosticLogStore.Instance.GetSnapshot().Count);
}
}
private void refreshButton_Click(object sender, EventArgs e)
{
RefreshView(true);
}
private void clearButton_Click(object sender, EventArgs e)
{
DiagnosticLogStore.Instance.Clear();
observedEntryCount = 0;
visibleEntryCount = 0;
RefreshView(true);
}
private void saveButton_Click(object sender, EventArgs e)
{
using (var dialog = new SaveFileDialog())
{
dialog.Filter = "Text files (*.txt)|*.txt|Log files (*.log)|*.log|All files (*.*)|*.*";
dialog.Title = "Save visible diagnostic logs";
dialog.DefaultExt = "log";
dialog.FileName = $"AppDiagnostic_{DateTime.Now:yyyyMMdd_HHmmss}.log";
if (dialog.ShowDialog(this) != DialogResult.OK)
{
return;
}
try
{
File.WriteAllText(dialog.FileName, logView.Text);
}
catch (Exception exception)
{
MessageBox.Show(this, $"Unable to save diagnostic logs: {exception.Message}", "Save error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void copyButton_Click(object sender, EventArgs e)
{
CopySelectionOrCurrentLine();
}
private void copySelectionMenuItem_Click(object sender, EventArgs e)
{
if (logView.SelectionLength > 0)
{
CopyText(logView.SelectedText);
}
}
private void copyLineMenuItem_Click(object sender, EventArgs e)
{
CopyCurrentLine();
}
private void copyAllButton_Click(object sender, EventArgs e)
{
CopyText(logView.Text);
}
private void CopySelectionOrCurrentLine()
{
if (logView.SelectionLength > 0)
{
CopyText(logView.SelectedText);
}
else
{
CopyCurrentLine();
}
}
private void CopyCurrentLine()
{
if (logView.Lines.Length == 0)
{
return;
}
int lineIndex = logView.GetLineFromCharIndex(logView.SelectionStart);
if (lineIndex >= 0 && lineIndex < logView.Lines.Length)
{
CopyText(logView.Lines[lineIndex]);
}
}
private void CopyText(string text)
{
if (string.IsNullOrEmpty(text))
{
return;
}
try
{
// Vaša logika pri uzatváraní formy
// this.Hide(); // Podforma sa len skryje
Clipboard.SetText(text);
}
catch (Exception ex)
catch (Exception exception)
{
// Ošetrenie výnimky
MessageBox.Show("Chyba pri zatváraní pod-aplikácie: " + ex.Message);
MessageBox.Show(this, $"Unable to copy text: {exception.Message}", "Clipboard error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void SaveLogsToFile()
private void wrapButton_Click(object sender, EventArgs e)
{
using (SaveFileDialog saveFileDialog = new SaveFileDialog())
{
saveFileDialog.Filter = "Text Files (*.txt)|*.txt|All Files (*.*)|*.*";
saveFileDialog.Title = "Save TBF live logs";
saveFileDialog.DefaultExt = "txt";
saveFileDialog.FileName = "TBFLiveLogs.txt";
logView.WordWrap = wrapButton.Checked;
}
if (saveFileDialog.ShowDialog() == DialogResult.OK)
private void alwaysOnTopButton_Click(object sender, EventArgs e)
{
TopMost = alwaysOnTopButton.Checked;
}
private void colorRulesButton_Click(object sender, EventArgs e)
{
using (var editor = new ColorRuleEditorForm(colorRules))
{
if (editor.ShowDialog(this) != DialogResult.OK)
{
try
{
// Načítanie všetkých logov z LiveLogCache
var logs = LiveLogCache.Instance.GetLogs(0, LiveLogCache.Instance.GetCount());
// Uloženie logov do vybraného súboru
File.WriteAllLines(saveFileDialog.FileName, logs);
MessageBox.Show("Logs saved successfully.", "Save TBF live logs", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
MessageBox.Show($"An error occurred while saving TBF live logs: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
return;
}
colorRules = editor.Rules;
try
{
LogColorRuleRepository.Save(colorRules);
}
catch (Exception exception)
{
MessageBox.Show(this, $"Unable to save color rules: {exception.Message}", "Settings error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
RefreshView(true);
}
}
private void button2_Click(object sender, EventArgs e)
private void applyFilterButton_Click(object sender, EventArgs e)
{
this.Close();
//this.Hide(); // Podforma sa len skryje
RefreshView(true);
}
private void MemoListView_DoubleClick(object sender, EventArgs e)
private void clearFilterButton_Click(object sender, EventArgs e)
{
if (memoListView.SelectedItems.Count > 0)
loadingFilters = true;
filterTextBox.Clear();
levelComboBox.SelectedIndex = 0;
applicationComboBox.SelectedIndex = 0;
loadingFilters = false;
RefreshView(true);
}
private void filterValueChanged(object sender, EventArgs e)
{
if (!loadingFilters)
{
var selectedItem = memoListView.SelectedItems[0];
int selectedIndex = memoListView.Items.IndexOf(selectedItem);
RefreshView(true);
}
}
if (selectedIndex >= 0)
{
// Zrušenie filtra
_logAdapter._filterText = string.Empty;
private void filterTextBox_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
RefreshView(true);
e.SuppressKeyPress = true;
}
else if (e.KeyCode == Keys.Escape)
{
clearFilterButton_Click(sender, EventArgs.Empty);
e.SuppressKeyPress = true;
}
}
// Načítanie logov od indexu vybraného riadku
var logs = LiveLogCache.Instance.GetLogs(selectedIndex, LiveLogCache.Instance.GetCount() - selectedIndex);
private void closeButton_Click(object sender, EventArgs e)
{
Close();
}
// Obnovenie ListView s novými údajmi
memoListView.BeginUpdate();
memoListView.Items.Clear();
foreach (var log in logs)
{
var item = new ListViewItem(log)
{
BackColor = memoListView.Items.Count % 2 == 0 ? Color.White : Color.FromArgb(240, 240, 240)
};
memoListView.Items.Add(item);
}
memoListView.EndUpdate();
}
private void MainForm_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyCode == Keys.F)
{
filterTextBox.Focus();
filterTextBox.SelectAll();
e.SuppressKeyPress = true;
}
else if (e.Control && e.KeyCode == Keys.S)
{
saveButton_Click(sender, EventArgs.Empty);
e.SuppressKeyPress = true;
}
else if (e.KeyCode == Keys.F5)
{
RefreshView(true);
e.SuppressKeyPress = true;
}
}
}
+21 -3
View File
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
@@ -14,9 +15,26 @@ namespace AppDiagnostic
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
bool isFirstInstance;
using (var instanceMutex = new Mutex(true, "Sensus.AppDiagnostic.SingleInstance", out isFirstInstance))
using (var activationEvent = new EventWaitHandle(false, EventResetMode.AutoReset, "Sensus.AppDiagnostic.Activate"))
{
if (!isFirstInstance)
{
activationEvent.Set();
return;
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
using (var diagnosticServer = new DiagnosticPipeServer(DiagnosticLogStore.Instance.Add))
{
diagnosticServer.Start();
Application.Run(new MainForm(() => diagnosticServer.ConnectedClientCount, () => activationEvent.WaitOne(0)));
}
}
}
}
}
+149 -78
View File
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 18
VisualStudioVersion = 18.5.11723.231 stable
VisualStudioVersion = 18.5.11723.231
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TBF", "TBF\TBF.csproj", "{8648FD92-CDA1-4C3A-B5F9-FE547CE1FA48}"
ProjectSection(ProjectDependencies) = postProject
@@ -106,11 +106,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LabelPrinting", "LabelPrint
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TBFTests", "TBFTests\TBFTests.csproj", "{77EB589F-C670-4489-AAD6-2A3C02061FD1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AppDiagnostic", "AppDiagnostic\AppDiagnostic.csproj", "{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}"
ProjectSection(ProjectDependencies) = postProject
{8F942729-F454-4C99-BA6C-746962065AE3} = {8F942729-F454-4C99-BA6C-746962065AE3}
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SharedComponents", "SharedComponents\SharedComponents.csproj", "{8F942729-F454-4C99-BA6C-746962065AE3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sensus.iPerl.RfidCom", "..\iPerlHead\Sensus.iPerl.RfidCom\Sensus.iPerl.RfidCom.csproj", "{A3E14180-7F00-42E5-94A9-8DB62EAD6EE8}"
@@ -208,6 +203,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tools.JsonToXlsHelper", "Ex
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MagFluxConfig", "ExternalProjects\Laatzen\Genesis\Common\Hardware\WaterMeter\MagFlux\MagFluxConfig\MagFluxConfig.csproj", "{70398B99-B134-4BBD-968B-7399B70C3CE2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AppDiagnostic", "AppDiagnostic\AppDiagnostic.csproj", "{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AppDiagnostic.Logging", "AppDiagnostic.Logging\AppDiagnostic.Logging.csproj", "{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
_MANUAL_CONTROL|Any CPU = _MANUAL_CONTROL|Any CPU
@@ -2638,78 +2637,6 @@ Global
{77EB589F-C670-4489-AAD6-2A3C02061FD1}.XP32bit|x64.Build.0 = Release|Any CPU
{77EB589F-C670-4489-AAD6-2A3C02061FD1}.XP32bit|x86.ActiveCfg = Release|Any CPU
{77EB589F-C670-4489-AAD6-2A3C02061FD1}.XP32bit|x86.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}._MANUAL_CONTROL|Any CPU.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}._MANUAL_CONTROL|Any CPU.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}._MANUAL_CONTROL|Mixed Platforms.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}._MANUAL_CONTROL|Mixed Platforms.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}._MANUAL_CONTROL|x64.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}._MANUAL_CONTROL|x64.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}._MANUAL_CONTROL|x86.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}._MANUAL_CONTROL|x86.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.COM|Any CPU.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.COM|Any CPU.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.COM|Mixed Platforms.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.COM|Mixed Platforms.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.COM|x64.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.COM|x64.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.COM|x86.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.COM|x86.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug|x64.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug|x64.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug|x86.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug|x86.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug-local IIS-CUST|Any CPU.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug-local IIS-CUST|Any CPU.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug-local IIS-CUST|Mixed Platforms.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug-local IIS-CUST|Mixed Platforms.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug-local IIS-CUST|x64.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug-local IIS-CUST|x64.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug-local IIS-CUST|x86.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug-local IIS-CUST|x86.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.PerformTest|Any CPU.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.PerformTest|Any CPU.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.PerformTest|Mixed Platforms.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.PerformTest|Mixed Platforms.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.PerformTest|x64.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.PerformTest|x64.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.PerformTest|x86.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.PerformTest|x86.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Release|Any CPU.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Release|x64.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Release|x64.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Release|x86.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Release|x86.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.ReleaseTest|Any CPU.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.ReleaseTest|Any CPU.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.ReleaseTest|Mixed Platforms.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.ReleaseTest|Mixed Platforms.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.ReleaseTest|x64.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.ReleaseTest|x64.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.ReleaseTest|x86.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.ReleaseTest|x86.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.VPN_Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.VPN_Debug|Any CPU.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.VPN_Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.VPN_Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.VPN_Debug|x64.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.VPN_Debug|x64.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.VPN_Debug|x86.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.VPN_Debug|x86.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.XP32bit|Any CPU.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.XP32bit|Any CPU.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.XP32bit|Mixed Platforms.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.XP32bit|Mixed Platforms.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.XP32bit|x64.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.XP32bit|x64.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.XP32bit|x86.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.XP32bit|x86.Build.0 = Release|Any CPU
{8F942729-F454-4C99-BA6C-746962065AE3}._MANUAL_CONTROL|Any CPU.ActiveCfg = Release|Any CPU
{8F942729-F454-4C99-BA6C-746962065AE3}._MANUAL_CONTROL|Any CPU.Build.0 = Release|Any CPU
{8F942729-F454-4C99-BA6C-746962065AE3}._MANUAL_CONTROL|Mixed Platforms.ActiveCfg = Release|Any CPU
@@ -5806,6 +5733,150 @@ Global
{70398B99-B134-4BBD-968B-7399B70C3CE2}.XP32bit|x64.Build.0 = Debug|Any CPU
{70398B99-B134-4BBD-968B-7399B70C3CE2}.XP32bit|x86.ActiveCfg = Debug|Any CPU
{70398B99-B134-4BBD-968B-7399B70C3CE2}.XP32bit|x86.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}._MANUAL_CONTROL|Any CPU.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}._MANUAL_CONTROL|Any CPU.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}._MANUAL_CONTROL|Mixed Platforms.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}._MANUAL_CONTROL|Mixed Platforms.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}._MANUAL_CONTROL|x64.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}._MANUAL_CONTROL|x64.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}._MANUAL_CONTROL|x86.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}._MANUAL_CONTROL|x86.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.COM|Any CPU.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.COM|Any CPU.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.COM|Mixed Platforms.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.COM|Mixed Platforms.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.COM|x64.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.COM|x64.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.COM|x86.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.COM|x86.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug|x64.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug|x64.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug|x86.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug|x86.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug-local IIS-CUST|Any CPU.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug-local IIS-CUST|Any CPU.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug-local IIS-CUST|Mixed Platforms.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug-local IIS-CUST|Mixed Platforms.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug-local IIS-CUST|x64.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug-local IIS-CUST|x64.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug-local IIS-CUST|x86.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Debug-local IIS-CUST|x86.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.PerformTest|Any CPU.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.PerformTest|Any CPU.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.PerformTest|Mixed Platforms.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.PerformTest|Mixed Platforms.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.PerformTest|x64.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.PerformTest|x64.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.PerformTest|x86.ActiveCfg = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.PerformTest|x86.Build.0 = Debug|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Release|Any CPU.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Release|x64.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Release|x64.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Release|x86.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.Release|x86.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.ReleaseTest|Any CPU.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.ReleaseTest|Any CPU.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.ReleaseTest|Mixed Platforms.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.ReleaseTest|Mixed Platforms.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.ReleaseTest|x64.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.ReleaseTest|x64.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.ReleaseTest|x86.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.ReleaseTest|x86.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.VPN_Debug|Any CPU.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.VPN_Debug|Any CPU.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.VPN_Debug|Mixed Platforms.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.VPN_Debug|Mixed Platforms.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.VPN_Debug|x64.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.VPN_Debug|x64.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.VPN_Debug|x86.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.VPN_Debug|x86.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.XP32bit|Any CPU.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.XP32bit|Any CPU.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.XP32bit|Mixed Platforms.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.XP32bit|Mixed Platforms.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.XP32bit|x64.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.XP32bit|x64.Build.0 = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.XP32bit|x86.ActiveCfg = Release|Any CPU
{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}.XP32bit|x86.Build.0 = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}._MANUAL_CONTROL|Any CPU.ActiveCfg = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}._MANUAL_CONTROL|Any CPU.Build.0 = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}._MANUAL_CONTROL|Mixed Platforms.ActiveCfg = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}._MANUAL_CONTROL|Mixed Platforms.Build.0 = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}._MANUAL_CONTROL|x64.ActiveCfg = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}._MANUAL_CONTROL|x64.Build.0 = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}._MANUAL_CONTROL|x86.ActiveCfg = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}._MANUAL_CONTROL|x86.Build.0 = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.COM|Any CPU.ActiveCfg = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.COM|Any CPU.Build.0 = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.COM|Mixed Platforms.ActiveCfg = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.COM|Mixed Platforms.Build.0 = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.COM|x64.ActiveCfg = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.COM|x64.Build.0 = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.COM|x86.ActiveCfg = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.COM|x86.Build.0 = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Debug|x64.ActiveCfg = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Debug|x64.Build.0 = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Debug|x86.ActiveCfg = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Debug|x86.Build.0 = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Debug-local IIS-CUST|Any CPU.ActiveCfg = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Debug-local IIS-CUST|Any CPU.Build.0 = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Debug-local IIS-CUST|Mixed Platforms.ActiveCfg = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Debug-local IIS-CUST|Mixed Platforms.Build.0 = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Debug-local IIS-CUST|x64.ActiveCfg = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Debug-local IIS-CUST|x64.Build.0 = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Debug-local IIS-CUST|x86.ActiveCfg = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Debug-local IIS-CUST|x86.Build.0 = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.PerformTest|Any CPU.ActiveCfg = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.PerformTest|Any CPU.Build.0 = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.PerformTest|Mixed Platforms.ActiveCfg = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.PerformTest|Mixed Platforms.Build.0 = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.PerformTest|x64.ActiveCfg = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.PerformTest|x64.Build.0 = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.PerformTest|x86.ActiveCfg = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.PerformTest|x86.Build.0 = Debug|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Release|Any CPU.Build.0 = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Release|x64.ActiveCfg = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Release|x64.Build.0 = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Release|x86.ActiveCfg = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.Release|x86.Build.0 = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.ReleaseTest|Any CPU.ActiveCfg = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.ReleaseTest|Any CPU.Build.0 = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.ReleaseTest|Mixed Platforms.ActiveCfg = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.ReleaseTest|Mixed Platforms.Build.0 = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.ReleaseTest|x64.ActiveCfg = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.ReleaseTest|x64.Build.0 = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.ReleaseTest|x86.ActiveCfg = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.ReleaseTest|x86.Build.0 = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.VPN_Debug|Any CPU.ActiveCfg = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.VPN_Debug|Any CPU.Build.0 = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.VPN_Debug|Mixed Platforms.ActiveCfg = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.VPN_Debug|Mixed Platforms.Build.0 = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.VPN_Debug|x64.ActiveCfg = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.VPN_Debug|x64.Build.0 = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.VPN_Debug|x86.ActiveCfg = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.VPN_Debug|x86.Build.0 = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.XP32bit|Any CPU.ActiveCfg = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.XP32bit|Any CPU.Build.0 = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.XP32bit|Mixed Platforms.ActiveCfg = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.XP32bit|Mixed Platforms.Build.0 = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.XP32bit|x64.ActiveCfg = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.XP32bit|x64.Build.0 = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.XP32bit|x86.ActiveCfg = Release|Any CPU
{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}.XP32bit|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
+150 -147
View File
@@ -19,32 +19,32 @@ namespace TBF
{
public class Program
{
public const string HomeDir = "C:\\Tbf\\"; /// Contains subdirectories Results, Logs, Images, ...
public const string HomeDir = "C:\\Tbf\\"; /// Contains subdirectories Results, Logs, Images, ...
public const string ConfigDir = "C:\\Tbf\\Cfg\\";
public const string GraphsDir = "C:\\Tbf\\Graphs\\";
public const string ImagesDir = "C:\\Tbf\\Images\\";
public const string TempImagesDir = "C:\\Tbf\\Images\\Temp\\";
public const string TempImagesDir = "C:\\Tbf\\Images\\Temp\\";
public static string ExecutableDir;
/// log4net
static ILog log;
const string log4netConfigFName = "log4netConfig.xml";
/// log4net
static ILog log;
const string log4netConfigFName = "log4netConfig.xml";
/// Program information
public static string Version; /// version string
public static DateTime BuildDateTime; /// date and time of program build
public static DateTime BuildDateTime; /// date and time of program build
/// Local settings
public static LocalSettings LocalSettings;
public const string LocalSettingsFileName = "config.xml";
public const string LocalSettingsBackupName = "config.backup.xml";
/// Local settings
public static LocalSettings LocalSettings;
public const string LocalSettingsFileName = "config.xml";
public const string LocalSettingsBackupName = "config.backup.xml";
public static System.Globalization.CultureInfo AltCulture;
public static System.Globalization.CultureInfo AltCulture;
static IList<Procedure> listOfProcedures;
/// <summary>
/// <summary>
/// Selected procedure data
/// - before the main program window is open, objects referenced by this variable
/// are loaded from the database.
@@ -69,18 +69,18 @@ namespace TBF
[STAThread]
static void Main()
{
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(MyHandler);
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(MyHandler);
/// Program version string
System.Reflection.Assembly thisAssembly = System.Reflection.Assembly.GetExecutingAssembly();
ExecutableDir = Path.GetDirectoryName(thisAssembly.Location);
Version ver = thisAssembly.GetName().Version;
Version = string.Format("{0}.{1}.{2}", ver.Major, ver.Minor, ver.Build);
BuildDateTime = new System.IO.FileInfo(thisAssembly.Location).LastWriteTime;
BuildDateTime = new System.IO.FileInfo(thisAssembly.Location).LastWriteTime;
/// Local program configuration directory including the trailing backslash
string locAppDataDir = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) +
Path.DirectorySeparatorChar + "TestBenchFramework" + Path.DirectorySeparatorChar;
Path.DirectorySeparatorChar + "TestBenchFramework" + Path.DirectorySeparatorChar;
string sampleConfigDir = Application.StartupPath + Path.DirectorySeparatorChar + "SampleConfig" + Path.DirectorySeparatorChar;
@@ -138,67 +138,67 @@ namespace TBF
Environment.CurrentDirectory = ConfigDir;
}
if (!Directory.Exists(ImagesDir)) Directory.CreateDirectory(ImagesDir);
if (!Directory.Exists(TempImagesDir)) Directory.CreateDirectory(TempImagesDir);
if (!Directory.Exists(ImagesDir)) Directory.CreateDirectory(ImagesDir);
if (!Directory.Exists(TempImagesDir)) Directory.CreateDirectory(TempImagesDir);
IEnumerable<string> files = Directory.EnumerateFiles(TempImagesDir); /// TODO: Implement recursive directory delete
IEnumerable<string> files = Directory.EnumerateFiles(TempImagesDir); /// TODO: Implement recursive directory delete
foreach (var file in files) File.Delete(file);
}
}
catch (Exception)
{
MessageBox.Show("Error creating a local application data directory and preparing an initial configuration", "Fatal error");
return; /// Fatal error
return; /// Fatal error
}
/// Configure and start logging
/// Configure and start logging
log4net.Config.XmlConfigurator.Configure(new System.IO.FileInfo(ConfigDir + log4netConfigFName));
log = LogManager.GetLogger(typeof(Program));
log.Fatal("--------------------------------------------------------------------------------");
log.Fatal(string.Format("TBF ver.{0}", Version));
log = LogManager.GetLogger(typeof(Program));
log.Fatal("--------------------------------------------------------------------------------");
log.Fatal(string.Format("TBF ver.{0}", Version));
///
///
/// Load the local settings
///
Program.LocalSettings = LocalSettings.Load(Program.LocalSettingsFileName);
if (Program.LocalSettings == null || Program.LocalSettings.TestBenches == null)
{
/// Loading local seetings from regular config file failed. Use the backup
Program.LocalSettings = LocalSettings.Load(Program.LocalSettingsBackupName);
if (Program.LocalSettings == null || Program.LocalSettings.TestBenches == null)
{
log.Fatal("Application terminated.");
MessageBox.Show(string.Format("Could not load file {0}, nor {1}.", Program.LocalSettingsFileName, Program.LocalSettingsBackupName), "Fatal error");
return; /// Fatal error
///
Program.LocalSettings = LocalSettings.Load(Program.LocalSettingsFileName);
if (Program.LocalSettings == null || Program.LocalSettings.TestBenches == null)
{
/// Loading local seetings from regular config file failed. Use the backup
Program.LocalSettings = LocalSettings.Load(Program.LocalSettingsBackupName);
if (Program.LocalSettings == null || Program.LocalSettings.TestBenches == null)
{
log.Fatal("Application terminated.");
MessageBox.Show(string.Format("Could not load file {0}, nor {1}.", Program.LocalSettingsFileName, Program.LocalSettingsBackupName), "Fatal error");
return; /// Fatal error
}
else
{
LocalSettings.Save(); /// Save the settings to overwrite the wrong file
else
{
LocalSettings.Save(); /// Save the settings to overwrite the wrong file
log.FatalFormat("BatchNr = {0}", LocalSettings.BatchNr);
}
}
else
{
/// Loading local seetings from the regular config file was successful. Update the backup
File.Copy(Program.LocalSettingsFileName, Program.LocalSettingsBackupName, true);
log.FatalFormat("BatchNr = {0}", LocalSettings.BatchNr);
}
}
}
else
{
/// Loading local seetings from the regular config file was successful. Update the backup
File.Copy(Program.LocalSettingsFileName, Program.LocalSettingsBackupName, true);
log.FatalFormat("BatchNr = {0}", LocalSettings.BatchNr);
}
try
{
string culture = LocalSettings.Language.Replace('_', '-');
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(culture);
}
catch (Exception e)
{
string msg = e.Message;
MessageBox.Show("Selected language not supported.\nUsing English.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
System.Threading.Thread.CurrentThread.CurrentUICulture =
new System.Globalization.CultureInfo("en");
}
try
{
string culture = LocalSettings.Language.Replace('_', '-');
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(culture);
}
catch (Exception e)
{
string msg = e.Message;
MessageBox.Show("Selected language not supported.\nUsing English.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
System.Threading.Thread.CurrentThread.CurrentUICulture =
new System.Globalization.CultureInfo("en");
}
//AltCulture = null;
AltCulture = new System.Globalization.CultureInfo("SK");
//AltCulture = null;
AltCulture = new System.Globalization.CultureInfo("SK");
/// This belongs to Application.Run(new MainWnd()) ...
@@ -207,28 +207,28 @@ namespace TBF
Application.SetCompatibleTextRenderingDefault(false);
/// Ensure that there is at least one bench in the configuration
while (Program.LocalSettings.BenchesCount == 0)
{
log.Warn("No test benches in the local configuration -> display an appropriate dialog.");
/// Ensure that there is at least one bench in the configuration
while (Program.LocalSettings.BenchesCount == 0)
{
log.Warn("No test benches in the local configuration -> display an appropriate dialog.");
/// Ask what to do, ask for the password, open 'DatabaseSetingsDlg' and continue on OK
if ((new NoBenchOrDatabaseDlg { Message = Strings.NoBenchMsg }.ShowDialog() != DialogResult.OK) ||
(new SharedDatabase.Forms.LoginDlg(true).ShowDialog() == DialogResult.Cancel) ||
/// Ask what to do, ask for the password, open 'DatabaseSetingsDlg' and continue on OK
if ((new NoBenchOrDatabaseDlg { Message = Strings.NoBenchMsg }.ShowDialog() != DialogResult.OK) ||
(new SharedDatabase.Forms.LoginDlg(true).ShowDialog() == DialogResult.Cancel) ||
(new TBF.UI.Settings.BenchesDlg().ShowDialog() == DialogResult.Cancel))
{
return; /// Exit program
{
return; /// Exit program
}
log.Warn("Loading the local settings again.");
Program.LocalSettings = LocalSettings.Load(Program.LocalSettingsFileName);
if (Program.LocalSettings == null) return; /// Fatal error
log.Warn("Loading the local settings again.");
Program.LocalSettings = LocalSettings.Load(Program.LocalSettingsFileName);
if (Program.LocalSettings == null) return; /// Fatal error
}
/// User login
bool retryLogin = true; /// true = stay in a login loop
do
{
{
LoadingConfigEnd();
LoginDlgWithBenchSelection loginDlgBench;
@@ -240,8 +240,8 @@ namespace TBF
{
loginDlgBench = new LoginDlgWithBenchSelection();
}
loginDlgBench.Method = LocalSettings.LoginMethod;
DialogResult dr = loginDlgBench.ShowDialog();
loginDlgBench.Method = LocalSettings.LoginMethod;
DialogResult dr = loginDlgBench.ShowDialog();
if (dr == DialogResult.Cancel)
{
@@ -253,11 +253,11 @@ namespace TBF
{
if (LocalSettings.TestBenches[i].BenchName == loginDlgBench.BenchName)
{
log.FatalFormat("Test bench name: {0}", loginDlgBench.BenchName);
log.FatalFormat("Test bench name: {0}", loginDlgBench.BenchName);
LoadingConfigStart();
CurrentUser.RemoteUsersDB = LocalSettings.TestBenches[i].UsersDBSettings;
CurrentUser.LocalUsersDB = LocalSettings.TestBenches[i].ProceduresDBSettings;
CurrentUser.RemoteUsersDB = LocalSettings.TestBenches[i].UsersDBSettings;
CurrentUser.LocalUsersDB = LocalSettings.TestBenches[i].ProceduresDBSettings;
SharedDatabase.Entities.User loadedUser = null;
try
@@ -268,32 +268,32 @@ namespace TBF
GID[] reqGrpMembership = null;
#endif
bool authorized = false;
AuthorizedAs authorizedAs = AuthorizedAs.PowerUser;
AuthorizedAs authorizedAs = AuthorizedAs.PowerUser;
if (Common.Utils.IsPowerUser(loginDlgBench.Alias, loginDlgBench.Password))
{
loadedUser = new SharedDatabase.Entities.User(loginDlgBench.Alias, 6, true);
{
loadedUser = new SharedDatabase.Entities.User(loginDlgBench.Alias, 6, true);
authorized = loadedUser.Authorize(loginDlgBench.Alias, loginDlgBench.Password, reqGrpMembership, null);
if (authorized)
{
CurrentUser.AuthorizedAs = AuthorizedAs.PowerUser;
}
}
}
///
/// Authorisation using databases
///
if (!authorized)
{
DBSettings[] dbs = new DBSettings[] { CurrentUser.RemoteUsersDB, CurrentUser.LocalUsersDB };
{
DBSettings[] dbs = new DBSettings[] { CurrentUser.RemoteUsersDB, CurrentUser.LocalUsersDB };
authorizedAs = AuthorizedAs.RemoteUser; /// Try remote DB first
authorizedAs = AuthorizedAs.RemoteUser; /// Try remote DB first
foreach (var db in dbs)
{
/// Load and authorise user from the UsersDB database
try
{
foreach (var db in dbs)
{
/// Load and authorise user from the UsersDB database
try
{
if (loginDlgBench.Password == LoginDlgWithBenchSelection.UseTheTagPassword)
{
loadedUser = SharedDatabase.Entities.User.LoadUserByTag(loginDlgBench.Alias, db);
@@ -320,24 +320,24 @@ namespace TBF
break;
}
}
}
catch
{
authorized = false;
}
}
catch
{
authorized = false;
}
if (authorized) break;
if (authorized) break;
authorizedAs = AuthorizedAs.LocalUser; /// Try local DB afterwards
authorizedAs = AuthorizedAs.LocalUser; /// Try local DB afterwards
}
}
}
if (authorized)
if (authorized)
{
loadedUser.SetLegalizator(loginDlgBench.Legalizator);
CurrentUser.AuthorizedAs = authorizedAs;
LocalSettings.LoginMethod = loginDlgBench.Method; /// Save the login method actually used
LocalSettings.LoginMethod = loginDlgBench.Method; /// Save the login method actually used
if (LocalSettings.TestBenches[i].IsRealBench)
{
@@ -351,7 +351,7 @@ namespace TBF
}
log.InfoFormat("Password accepted, bench '{0}' parameters loaded.",
LocalSettings.TestBenches[i].BenchName);
LocalSettings.TestBenches[i].BenchName);
/// Copy the selected bench settings to CurrentBench.
/// Clone() guarantees that current bench settings wont be modified
@@ -448,31 +448,31 @@ namespace TBF
/// Ask what to do
switch ((new NoBenchOrDatabaseDlg { Message = Strings.NoDatabaseMsg, ShowRetry = true }).ShowDialog())
{
case DialogResult.Abort:
{
case DialogResult.Abort:
return; /// Exit program
case DialogResult.Retry:
case DialogResult.Retry:
break; /// Retry connection to the database, stay inside the loop
case DialogResult.Yes:
new TBF.UI.Settings.UpgradeSelectionDlg().ShowDialog();
break; /// Stay inside the loop
default:
/// Open 'DatabaseSetingsDlg' and retry DB connect on OK
default:
/// Open 'DatabaseSetingsDlg' and retry DB connect on OK
if (new SharedDatabase.Forms.LoginDlg(true).ShowDialog() == DialogResult.Cancel ||
new TBF.UI.Settings.BenchesDlg().ShowDialog() == DialogResult.Cancel)
{
return; /// Exit program
{
return; /// Exit program
}
if (Program.LocalSettings == null)
if (Program.LocalSettings == null)
return; /// Fatal error -> Exit program
else
break; /// Stay inside the loop
break; /// Stay inside the loop
}
}
} // if benchname is OK
}
} // if benchname is OK
} // for all benches in local settings loop
} // not Canceled
} //do
@@ -485,53 +485,56 @@ namespace TBF
{
if (listOfProcedures != null && listOfProcedures.Count == 1)
{
log.InfoFormat("Pre-selecting the procedure {0}", LocalSettings.LastProcedureName);
SelectedProcedure = listOfProcedures[0];
log.InfoFormat("Pre-selecting the procedure {0}", LocalSettings.LastProcedureName);
SelectedProcedure = listOfProcedures[0];
}
}
try
{
//AppDiagnostic SDK - nlog connector registration
AppDiagnostic.Logging.AppDiagnosticConnector.Register();
try
{
/// Open the main application window
log.Info("Creating the main window");
MainWnd = new UI.MainWnd();
log.Info("Opening the main window");
MainWnd = new UI.MainWnd();
log.Info("Opening the main window");
LoadingConfigEnd();
Application.Run(MainWnd);
log.Info("The main window was closed");
}
catch (Exception e)
{
LogException(log, "Exception in Application.Run(MainWnd)", e);
}
finally
{
/// Save local settings
LocalSettings.Save();
}
log.Info("The main window was closed");
}
catch (Exception e)
{
LogException(log, "Exception in Application.Run(MainWnd)", e);
}
finally
{
/// Save local settings
LocalSettings.Save();
}
/// Close Fluent NHibernate
/// Todo
log.Info("Exiting application.");
log.Info("Exiting application.");
}
static void MyHandler(object sender, UnhandledExceptionEventArgs args)
{
LogException(log, "Unhandled exception", (Exception)args.ExceptionObject);
}
static void MyHandler(object sender, UnhandledExceptionEventArgs args)
{
LogException(log, "Unhandled exception", (Exception)args.ExceptionObject);
}
static void LogException(ILog log, string description, Exception e)
{
log.FatalFormat("---------------( {0} )---------------", description);
log.FatalFormat("Message : {0}", e.Message);
if (e.InnerException != null)
{
log.FatalFormat("InnerMessage : {0}", e.InnerException.Message);
}
log.FatalFormat("StackTrace : {0}{1}", Environment.NewLine, e.StackTrace);
log.Fatal("--------------------------------------");
}
static void LogException(ILog log, string description, Exception e)
{
log.FatalFormat("---------------( {0} )---------------", description);
log.FatalFormat("Message : {0}", e.Message);
if (e.InnerException != null)
{
log.FatalFormat("InnerMessage : {0}", e.InnerException.Message);
}
log.FatalFormat("StackTrace : {0}{1}", Environment.NewLine, e.StackTrace);
log.Fatal("--------------------------------------");
}
static UI.Shared.ModelessActivityForm form;
@@ -562,5 +565,5 @@ namespace TBF
form = null;
formThread = null;
}
}
}
}
+8 -3
View File
@@ -4595,9 +4595,9 @@
<Project>{5954d496-caab-4f7a-bde2-bdc8f47dab19}</Project>
<Name>NfcS5_DLL</Name>
</ProjectReference>
<ProjectReference Include="..\AppDiagnostic\AppDiagnostic.csproj">
<Project>{fa9abad1-7184-4295-ade8-d44f2e3de6b2}</Project>
<Name>AppDiagnostic</Name>
<ProjectReference Include="..\AppDiagnostic.Logging\AppDiagnostic.Logging.csproj">
<Project>{a7af8ed2-362e-4dbb-b607-eba2820719ec}</Project>
<Name>AppDiagnostic.Logging</Name>
</ProjectReference>
<ProjectReference Include="..\Common\Common.csproj">
<Project>{c8939821-ba5c-4988-a3d0-bf53b74865c7}</Project>
@@ -4694,4 +4694,9 @@
<ItemGroup>
<Compile Include="Rig\TestMethods\GenesisCommunication\GenesisCalibrationFactors.cs" />
</ItemGroup>
<PropertyGroup>
<PostBuildEvent>if not exist "$(TargetDir)AppDiagnostic\" mkdir "$(TargetDir)AppDiagnostic\"
xcopy /Y /E /I "$(SolutionDir)AppDiagnostic\bin\$(ConfigurationName)\*" "$(TargetDir)AppDiagnostic\"
if errorlevel 1 exit /b 1</PostBuildEvent>
</PropertyGroup>
</Project>
+178 -158
View File
@@ -22,6 +22,8 @@ using SharedComponents;
using System.Diagnostics;
using TBF.Rig.TestMethods.iPerlCommunication;
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication;
using System.Diagnostics;
using System.IO;
namespace TBF.UI
{
@@ -31,6 +33,7 @@ namespace TBF.UI
public partial class MainWnd : Form
{
static readonly ILog log = LogManager.GetLogger(typeof(MainWnd));
private static readonly NLog.Logger diagnosticLogger = NLog.LogManager.GetCurrentClassLogger();
/// Used when re-scaling the dialog: 100% = 96dpi, 125% = 120dpi, 150% = 144dpi
public static int Dpi;
@@ -49,7 +52,7 @@ namespace TBF.UI
IList<SharedDatabase.Entities.OrderInfo> tracingDBOrders; /// Production orders loaded from the production tracing DB
IList<TBF.Rig.Output.DB.SensusOracle.OrderDetails> oracleOrders; /// Production orders loaded from the Oracle DB
IList<ProcedureInfo> procedureInfos; /// Composed procedure infos
///
///
public ProcedureInfo SelectedProcedure;
public Procedure CurrentProcedure;
@@ -58,7 +61,7 @@ namespace TBF.UI
/// </summary>
Shared.ModelessActivityForm closingTbfMessageForm;
TestProgressControls testProgressControls;
TestProgressControls testProgressControls;
/// <summary>
/// Set when procedures are updated while the ProceduresComboBox is disabled (i.e. during a test).
@@ -78,36 +81,36 @@ namespace TBF.UI
{
Invalid = -1,
Hydraulics = 0,
Process,
Process,
Insert,
Results,
Results,
Graphs,
Events,
Calendar,
Camera,
TabPagesCount
TabPagesCount
}
/// <summary>
/// Event handlers switching between tab pages
/// </summary>
private void homeTSMenuItem_Click(object sender, EventArgs e) { mainTabControl.SelectTab((int)MainTabPageId.Hydraulics); }
private void processTSMenuItem_Click(object sender, EventArgs e) { mainTabControl.SelectTab((int)MainTabPageId.Process); }
private void resultsTSMenuItem_Click(object sender, EventArgs e) { mainTabControl.SelectTab((int)MainTabPageId.Results); }
private void graphsToolStripMenuItem_Click(object sender, EventArgs e) { mainTabControl.SelectTab((int)MainTabPageId.Graphs); }
private void eventsTSMenuItem_Click(object sender, EventArgs e) { mainTabControl.SelectTab((int)MainTabPageId.Events); }
private void processTSMenuItem_Click(object sender, EventArgs e) { mainTabControl.SelectTab((int)MainTabPageId.Process); }
private void resultsTSMenuItem_Click(object sender, EventArgs e) { mainTabControl.SelectTab((int)MainTabPageId.Results); }
private void graphsToolStripMenuItem_Click(object sender, EventArgs e) { mainTabControl.SelectTab((int)MainTabPageId.Graphs); }
private void eventsTSMenuItem_Click(object sender, EventArgs e) { mainTabControl.SelectTab((int)MainTabPageId.Events); }
private void calendarTSMenuItem_Click(object sender, EventArgs e) { mainTabControl.SelectTab((int)MainTabPageId.Calendar); }
#if CAMERA
private System.Windows.Forms.ToolStripMenuItem cameraTSMItem;
private void cameraTSMItem_Click(object sender, EventArgs e) { mainTabControl.SelectTab((int)MainTabPageId.Camera); }
private System.Windows.Forms.ToolStripMenuItem cameraTSMItem;
private void cameraTSMItem_Click(object sender, EventArgs e) { mainTabControl.SelectTab((int)MainTabPageId.Camera); }
#endif
/// DB entities of components loaded in the MainWnd constructor
IList<Config.Entities.Component> cmpntEntities;
/// <summary>
/// <summary>
/// Constructor
/// </summary>
public MainWnd()
@@ -132,22 +135,22 @@ namespace TBF.UI
CurrentProcedure = null;
///
/// Customize menu items
///
/// Customize menu items
///
#if CAMERA
/// Add 'Camera' menu item
cameraTSMItem = new System.Windows.Forms.ToolStripMenuItem();
/// Add 'Camera' menu item
cameraTSMItem = new System.Windows.Forms.ToolStripMenuItem();
cameraTSMItem.Name = "cameraTSMItem";
cameraTSMItem.Text = Strings.Camera;
cameraTSMItem.Click += new System.EventHandler(this.cameraTSMItem_Click);
cameraTSMItem.Name = "cameraTSMItem";
cameraTSMItem.Text = Strings.Camera;
cameraTSMItem.Click += new System.EventHandler(this.cameraTSMItem_Click);
mainMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {this.cameraTSMItem});
mainMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.cameraTSMItem });
#endif
UpdateMenuItemsVisibility();
optoHeadsToolStripMenuItem.Visible = true;
optoHeadsToolStripMenuItem.Enabled = false;
optoHeadsToolStripMenuItem.Enabled = false;
IsShutdownDisabled = true;
IsShutdownPCAfterClosingTbf = false;
@@ -166,10 +169,10 @@ namespace TBF.UI
Rig.StateMachine.MachineState = TBF.DB.CurrentBench.IsRealBench ? Rig.MachineState.StartingUp : Rig.MachineState.Disabled;
#if DEBUG
#if DEBUG
//define always valid for printer test - BUMI
Rig.StateMachine.MachineState = Rig.MachineState.StartingUp;
#endif
#endif
///
if (Rig.StateMachine.MachineState == Rig.MachineState.StartingUp)
@@ -230,20 +233,20 @@ namespace TBF.UI
}
}
void Localize()
{
void Localize()
{
///
/// Menu
///
benchTSMenuItem.Text = Strings.Bench;
benchComponentsTSMenuItem.Text = Strings.Components;
benchPathsTSMenuItem.Text = Strings.Paths;
benchTransitionsToolStripMenuItem.Text = Strings.Transitions;
benchMetrologyTSMenuItem.Text = Strings.Metrology;
benchUncertaintyTSMItem.Text = Strings.Uncertainty;
benchTestProfilesTSMItem.Text = Strings.Test_profiles;
editSchDrawingTSMItem.Text = Strings.Edit_schematic_drawing;
exitToolStripMenuItem.Text = Strings.Exit;
benchComponentsTSMenuItem.Text = Strings.Components;
benchPathsTSMenuItem.Text = Strings.Paths;
benchTransitionsToolStripMenuItem.Text = Strings.Transitions;
benchMetrologyTSMenuItem.Text = Strings.Metrology;
benchUncertaintyTSMItem.Text = Strings.Uncertainty;
benchTestProfilesTSMItem.Text = Strings.Test_profiles;
editSchDrawingTSMItem.Text = Strings.Edit_schematic_drawing;
exitToolStripMenuItem.Text = Strings.Exit;
proceduresToolStripMenuItem.Text = Strings.Procedures;
homeTSMenuItem.Text = Strings.Home;
processToolStripMenuItem.Text = Strings.Process;
@@ -252,31 +255,31 @@ namespace TBF.UI
eventLogsTSMenuItem.Text = Strings.Event_logs;
calendarTSMenuItem.Text = Strings.Calendar;
settingsTSMenuItem.Text = Strings.Settings;
usersTSMenuItem.Text = Strings.Users;
languageTSMItem.Text = Strings.Language;
databaseSettingsTSMenuItem.Text = Strings.Database;
backUpTSMItem.Text = Strings.Backup;
backUpConfigTSMItem.Text = Strings.Configuration;
backUpResultsTSMItem.Text = Strings.Results;
passwdTSMItem.Text = Strings.Password;
upgradeTSMenuItem.Text = Strings.Upgrade_DB;
usersTSMenuItem.Text = Strings.Users;
languageTSMItem.Text = Strings.Language;
databaseSettingsTSMenuItem.Text = Strings.Database;
backUpTSMItem.Text = Strings.Backup;
backUpConfigTSMItem.Text = Strings.Configuration;
backUpResultsTSMItem.Text = Strings.Results;
passwdTSMItem.Text = Strings.Password;
upgradeTSMenuItem.Text = Strings.Upgrade_DB;
appDiagnosticMenuItem.Text = Strings.Application_Diagnostic;
optoHeadsToolStripMenuItem.Text = Strings.Optical_heads;
clearCountersToolStripMenuItem.Text = Strings.Clear_counters;
clearCountersToolStripMenuItem.Text = Strings.Clear_counters;
helpTSMenuItem.Text = Strings.Help;
aboutTSMenuItem.Text = Strings.About;
aboutTSMenuItem.Text = Strings.About;
procedureGroupBox.Text = Strings.Procedure;
activityGroupBox.Text = Strings.Activity;
progressGroupBox.Text = Strings.Progress;
}
activityGroupBox.Text = Strings.Activity;
progressGroupBox.Text = Strings.Progress;
}
/// <summary>
/// Initializes this window and its controls
/// </summary>
private void MainWnd_Load(object sender, EventArgs e)
{
Localize();
Localize();
TBF.LocalSettings ls = Program.LocalSettings;
WindowState = (ls.MainWndMaximized ? FormWindowState.Maximized : FormWindowState.Normal);
@@ -297,23 +300,23 @@ namespace TBF.UI
if (TBF.Rig.StateMachine.MachineState == TBF.Rig.MachineState.StartingUp)
{
var form = new Shared.ModelessActivityForm()
{
Message = Strings.Starting_system,
FontFamily = "Arial",
FontSize = 24,
FontStyle = FontStyle.Regular,
BackgroundColor = Color.OliveDrab, /// or Color.YellowGreen
StartActivityHandler = true,
};
Thread formThread = new Thread(() => form.ShowDialog());
formThread.Start();
var form = new Shared.ModelessActivityForm()
{
Message = Strings.Starting_system,
FontFamily = "Arial",
FontSize = 24,
FontStyle = FontStyle.Regular,
BackgroundColor = Color.OliveDrab, /// or Color.YellowGreen
StartActivityHandler = true,
};
Thread formThread = new Thread(() => form.ShowDialog());
formThread.Start();
try
{
string message = Rig.StateMachine.InitializeDevices();
form.CloseForm(null, new EventArgs());
formThread.Join();
form.CloseForm(null, new EventArgs());
formThread.Join();
#if !DEBUG
if (message != null)
{
@@ -324,43 +327,43 @@ namespace TBF.UI
}
#endif
Bridge.ButtonsEtcHandler += delegate(object sndr, ButtonsEtcEventArgs args)
Bridge.ButtonsEtcHandler += delegate (object sndr, ButtonsEtcEventArgs args)
{
if (InvokeRequired) { Invoke(new EventHandler<ButtonsEtcEventArgs>(OnButtonsEtc), sndr, args); }
else OnButtonsEtc(sndr, args);
};
Bridge.ActivityHandler += delegate(object sndr, UiBridge.ActivityEventArgs args)
Bridge.ActivityHandler += delegate (object sndr, UiBridge.ActivityEventArgs args)
{
if (InvokeRequired) { Invoke(new EventHandler<UiBridge.ActivityEventArgs>(OnActivity), sndr, args); }
else OnActivity(sndr, args);
};
Bridge.StateChangedHandler += delegate(object sndr, UiBridge.StateChangedEventArgs args)
Bridge.StateChangedHandler += delegate (object sndr, UiBridge.StateChangedEventArgs args)
{
if (InvokeRequired) { Invoke(new EventHandler<UiBridge.StateChangedEventArgs>(OnStateChanged), sndr, args); }
else OnStateChanged(sndr, args);
};
Bridge.StateMachineTickHandler += delegate(object sndr, UiBridge.StateMachineTickEventArgs args)
Bridge.StateMachineTickHandler += delegate (object sndr, UiBridge.StateMachineTickEventArgs args)
{
if (InvokeRequired) { Invoke(new EventHandler<UiBridge.StateMachineTickEventArgs>(OnStateMachineTick), sndr, args); }
else OnStateMachineTick(sndr, args);
};
Bridge.TestProgressHandler += delegate(object sndr, UiBridge.TestProgressEventArgs args)
Bridge.TestProgressHandler += delegate (object sndr, UiBridge.TestProgressEventArgs args)
{
if (InvokeRequired) { Invoke(new EventHandler<UiBridge.TestProgressEventArgs>(OnTestProgress), sndr, args); }
else OnTestProgress(sndr, args);
};
Bridge.ProcedureSelectedHandler += delegate(object sndr, UiBridge.ProcedureSelectedEventArgs args)
Bridge.ProcedureSelectedHandler += delegate (object sndr, UiBridge.ProcedureSelectedEventArgs args)
{
if (InvokeRequired) { Invoke(new EventHandler<UiBridge.ProcedureSelectedEventArgs>(OnProcedureSelected), sndr, args); }
else OnProcedureSelected(sndr, args);
};
Bridge.SaveSettingsHandler += delegate(object sndr, UiBridge.SaveSettingsEventArgs args)
Bridge.SaveSettingsHandler += delegate (object sndr, UiBridge.SaveSettingsEventArgs args)
{
if (InvokeRequired) { Invoke(new EventHandler<UiBridge.SaveSettingsEventArgs>(OnSaveSettings), sndr, args); }
else OnSaveSettings(sndr, args);
@@ -370,10 +373,10 @@ namespace TBF.UI
{
TBF.Rig.StateMachine.MachineState = TBF.Rig.MachineState.FailedToStart;
form.CloseForm(null, new EventArgs());
formThread.Join();
form.CloseForm(null, new EventArgs());
formThread.Join();
string errMsg = string.Format(Strings.Failed_to_initialize_device_0_1_2,
string errMsg = string.Format(Strings.Failed_to_initialize_device_0_1_2,
Rig.StateMachine.CurrentlyInitializedComponentName,
Environment.NewLine,
exc.Message);
@@ -390,26 +393,26 @@ namespace TBF.UI
SelectedProcedure = new ProcedureInfo(ls.LastProcedureSource, ls.LastProcedureNr, ls.LastProcedureName, signature);
procedureComboBox.Text = SelectedProcedure.ToString();
rightHorizSplitContainer.SplitterDistance = Program.LocalSettings.RightPaneHorizSplitterDistance;
topVerticalSplitContainer.SplitterDistance = Program.LocalSettings.TopPaneVerticalSplitterDistance;
rightHorizSplitContainer.SplitterDistance = Program.LocalSettings.RightPaneHorizSplitterDistance;
topVerticalSplitContainer.SplitterDistance = Program.LocalSettings.TopPaneVerticalSplitterDistance;
/// Initialize bench control user interface(s)
BenchControlPanel = new BenchControlPanel();
/// Initialize bench control user interface(s)
BenchControlPanel = new BenchControlPanel();
BenchControlPanel.BalancesCount = TBF.Rig.StateMachine.Tank3 != null ? 3
: TBF.Rig.StateMachine.Tank2 != null ? 2
: TBF.Rig.StateMachine.Tank1 != null ? 1
: 0;
new System.ComponentModel.ComponentResourceManager(typeof(MainWnd)).ApplyResources(BenchControlPanel, "benchControlPanel");
BenchControlPanel.Name = "benchControlPanel";
rightHorizSplitContainer.Panel2.Controls.Add(BenchControlPanel);
new System.ComponentModel.ComponentResourceManager(typeof(MainWnd)).ApplyResources(BenchControlPanel, "benchControlPanel");
BenchControlPanel.Name = "benchControlPanel";
rightHorizSplitContainer.Panel2.Controls.Add(BenchControlPanel);
ReloadProcedureComboBoxItems();
ReloadProcedureComboBoxItems();
/// Select the initial tab page
mainTabControl.SelectTab((int)MainTabPageId.Process); /// This is to load the 'Process screen'
mainTabControl.SelectTab((int)MainTabPageId.Calendar); /// This is to load the 'Calendar screen'
UpdateUser();
mainTabControl.SelectTab((int)MainTabPageId.Hydraulics);
mainTabControl.SelectTab((int)MainTabPageId.Hydraulics);
processTabPageCtrl.Settings2UI();
@@ -422,7 +425,7 @@ namespace TBF.UI
string[] edgesLcfg = null;
string[] edgesXLcfg = null;
///
var schDrawingCmpnts = (TBF.DB.CurrentBench.IsRealBench && Rig.StateMachine.Components != null)
var schDrawingCmpnts = (TBF.DB.CurrentBench.IsRealBench && Rig.StateMachine.Components != null)
? Rig.StateMachine.Components
: TBF.Rig.TbfComponents.LoadComponentsFromDB(cmpntEntities);
@@ -488,11 +491,11 @@ namespace TBF.UI
topVerticalSplitContainer.SplitterDistance = topVerticalSplitContainer.Width / 2;
}
/// <summary>
/// Pass any pressed keys to the Bench control panel.
/// Note that MainWnd.KeyPreview must be set to true.
/// </summary>
private void MainWnd_KeyPress(object sender, KeyPressEventArgs e)
/// <summary>
/// Pass any pressed keys to the Bench control panel.
/// Note that MainWnd.KeyPreview must be set to true.
/// </summary>
private void MainWnd_KeyPress(object sender, KeyPressEventArgs e)
{
#if BADGER_MALA_TRAT || BADGER_STREDNA_TRAT || BADGER_VELKA_TRAT || GENESIS || CEVAK_200 || TURA_SPECIAL || TURA_IPERL || TURA_IPERL_NEW
/// Do nothing = do not process keys
@@ -514,24 +517,24 @@ namespace TBF.UI
/// </summary>
void OnActivity(object sender, UiBridge.ActivityEventArgs args)
{
switch (args.Cmd)
{
case ActivityEventArgs.Update.Activity:
activityLabel.Text = args.Activity;
if (string.IsNullOrEmpty(messageLabel.Text)) messageLabel.ForeColor = Color.Black;
break;
case ActivityEventArgs.Update.Message:
messageLabel.Text = args.Message;
if (args.ErrorMsg) messageLabel.ForeColor = Color.Red;
else messageLabel.ForeColor = Color.Black;
break;
default:
activityLabel.Text = args.Activity;
messageLabel.Text = args.Message;
if (args.ErrorMsg) messageLabel.ForeColor = Color.Red;
else messageLabel.ForeColor = Color.Black;
break;
}
switch (args.Cmd)
{
case ActivityEventArgs.Update.Activity:
activityLabel.Text = args.Activity;
if (string.IsNullOrEmpty(messageLabel.Text)) messageLabel.ForeColor = Color.Black;
break;
case ActivityEventArgs.Update.Message:
messageLabel.Text = args.Message;
if (args.ErrorMsg) messageLabel.ForeColor = Color.Red;
else messageLabel.ForeColor = Color.Black;
break;
default:
activityLabel.Text = args.Activity;
messageLabel.Text = args.Message;
if (args.ErrorMsg) messageLabel.ForeColor = Color.Red;
else messageLabel.ForeColor = Color.Black;
break;
}
}
/// <summary>
@@ -602,10 +605,10 @@ namespace TBF.UI
}
}
void OnTestProgress(object sender, UiBridge.TestProgressEventArgs args)
{
mainProgressBar.Value = (int)(100.499f * args.OveralProgress);
}
void OnTestProgress(object sender, UiBridge.TestProgressEventArgs args)
{
mainProgressBar.Value = (int)(100.499f * args.OveralProgress);
}
void OnProcedureSelected(object sender, UiBridge.ProcedureSelectedEventArgs args)
{
@@ -671,18 +674,18 @@ namespace TBF.UI
public void UpdateUser()
{
userInfoStatusLabel.Text = string.Format("{0}: {1}{2}, ", Strings.User, CurrentUser.UserName(),
(CurrentUser.AuthorizedAs == AuthorizedAs.PowerUser) ? "(S)" :
(CurrentUser.AuthorizedAs == AuthorizedAs.LocalUser) ? "(L)" : "(R)");
userInfoStatusLabel.Text = string.Format("{0}: {1}{2}, ", Strings.User, CurrentUser.UserName(),
(CurrentUser.AuthorizedAs == AuthorizedAs.PowerUser) ? "(S)" :
(CurrentUser.AuthorizedAs == AuthorizedAs.LocalUser) ? "(L)" : "(R)");
UpdateMenuItemsVisibility();
}
void UpdateMenuItemsVisibility()
{
usersTSMenuItem.Visible = CurrentUser.IsMemberOf(GID.Administrators) || CurrentUser.IsMemberOf(GID.HeadOfLab);
databaseSettingsTSMenuItem.Visible = CurrentUser.IsMemberOf(GID.Administrators) && CurrentUser.IsPowerUser();
upgradeTSMenuItem.Visible = CurrentUser.IsMemberOf(GID.Administrators) && CurrentUser.IsPowerUser();
usersTSMenuItem.Visible = CurrentUser.IsMemberOf(GID.Administrators) || CurrentUser.IsMemberOf(GID.HeadOfLab);
databaseSettingsTSMenuItem.Visible = CurrentUser.IsMemberOf(GID.Administrators) && CurrentUser.IsPowerUser();
upgradeTSMenuItem.Visible = CurrentUser.IsMemberOf(GID.Administrators) && CurrentUser.IsPowerUser();
clearCountersToolStripMenuItem.Visible = CurrentUser.IsMemberOf(GID.Administrators) ||
CurrentUser.IsMemberOf(GID.HeadOfLab) ||
CurrentUser.IsMemberOf(GID.TestingSpecialists) ||
@@ -710,14 +713,14 @@ namespace TBF.UI
//Rig.StateMachine.Stop();
}
private void benchComponentsTSMItem_Click(object s, EventArgs e) { Cursor = Cursors.WaitCursor; new TBF.UI.Bench.Components.ComponentsManagerDlg().ShowDialog(); Cursor = Cursors.Default; }
private void benchPathsTSMItem_Click(object s, EventArgs e) { Cursor = Cursors.WaitCursor; new TBF.UI.Bench.Paths.PathsDlg().ShowDialog(); Cursor = Cursors.Default; }
private void benchTransitionsTSMItem_Click(object s, EventArgs e) { Cursor = Cursors.WaitCursor; new TBF.UI.Bench.Transitions.TransitionsDlg().ShowDialog(); Cursor = Cursors.Default; }
private void benchMetrologyTSMItem_Click(object s, EventArgs e) { Cursor = Cursors.WaitCursor; new TBF.UI.Bench.Metrology.MetrologyDlg().ShowDialog(); Cursor = Cursors.Default; }
private void benchUncertaintyTSMItem_Click(object s, EventArgs e) { Cursor = Cursors.WaitCursor; new TBF.UI.Bench.Uncertainties.UncertaintiesDlg().ShowDialog(); Cursor = Cursors.Default; }
private void benchTestProfilesTSMItem_Click(object s, EventArgs e) { Cursor = Cursors.WaitCursor; new TBF.UI.Bench.TestProfiles.TestProfilesDlg().ShowDialog(); Cursor = Cursors.Default; }
private void editSchDrawingTSMItem_Click(object sender, EventArgs e){ Cursor = Cursors.WaitCursor; new TBF.UI.Bench.EditSchDrawing.EditSchDrawingDlg().ShowDialog();Cursor = Cursors.Default; }
private void proceduresTSMItem_Click(object s, EventArgs e) { Cursor = Cursors.WaitCursor; new TBF.UI.Procedures.ProceduresDlg().ShowDialog(); Cursor = Cursors.Default; }
private void benchComponentsTSMItem_Click(object s, EventArgs e) { Cursor = Cursors.WaitCursor; new TBF.UI.Bench.Components.ComponentsManagerDlg().ShowDialog(); Cursor = Cursors.Default; }
private void benchPathsTSMItem_Click(object s, EventArgs e) { Cursor = Cursors.WaitCursor; new TBF.UI.Bench.Paths.PathsDlg().ShowDialog(); Cursor = Cursors.Default; }
private void benchTransitionsTSMItem_Click(object s, EventArgs e) { Cursor = Cursors.WaitCursor; new TBF.UI.Bench.Transitions.TransitionsDlg().ShowDialog(); Cursor = Cursors.Default; }
private void benchMetrologyTSMItem_Click(object s, EventArgs e) { Cursor = Cursors.WaitCursor; new TBF.UI.Bench.Metrology.MetrologyDlg().ShowDialog(); Cursor = Cursors.Default; }
private void benchUncertaintyTSMItem_Click(object s, EventArgs e) { Cursor = Cursors.WaitCursor; new TBF.UI.Bench.Uncertainties.UncertaintiesDlg().ShowDialog(); Cursor = Cursors.Default; }
private void benchTestProfilesTSMItem_Click(object s, EventArgs e) { Cursor = Cursors.WaitCursor; new TBF.UI.Bench.TestProfiles.TestProfilesDlg().ShowDialog(); Cursor = Cursors.Default; }
private void editSchDrawingTSMItem_Click(object sender, EventArgs e) { Cursor = Cursors.WaitCursor; new TBF.UI.Bench.EditSchDrawing.EditSchDrawingDlg().ShowDialog(); Cursor = Cursors.Default; }
private void proceduresTSMItem_Click(object s, EventArgs e) { Cursor = Cursors.WaitCursor; new TBF.UI.Procedures.ProceduresDlg().ShowDialog(); Cursor = Cursors.Default; }
private void usersTSMItem_Click(object s, EventArgs e)
{
@@ -754,15 +757,15 @@ namespace TBF.UI
}
}
}
private void backUpConfigTSMItem_Click(object s, EventArgs e) { BackupConfiguration(); }
private void backUpResultsTSMItem_Click(object s, EventArgs e) { BackupResults(); }
private void passwdTSMItem_Click(object s, EventArgs e) { new SharedDatabase.Forms.PasswordChangeDlg(CurrentUser.UserName()).ShowDialog(); }
private void aboutTSMItem_Click(object s, EventArgs e) { new TBF.UI.Help.AboutDlg().ShowDialog(); }
private void backUpConfigTSMItem_Click(object s, EventArgs e) { BackupConfiguration(); }
private void backUpResultsTSMItem_Click(object s, EventArgs e) { BackupResults(); }
private void passwdTSMItem_Click(object s, EventArgs e) { new SharedDatabase.Forms.PasswordChangeDlg(CurrentUser.UserName()).ShowDialog(); }
private void aboutTSMItem_Click(object s, EventArgs e) { new TBF.UI.Help.AboutDlg().ShowDialog(); }
/// <summary>
/// Read the database and re-initialize procedureComboBox items.
/// Try to preserve the original selection.
/// </summary>
/// <summary>
/// Read the database and re-initialize procedureComboBox items.
/// Try to preserve the original selection.
/// </summary>
public void ReloadProcedureComboBoxItems()
{
int separPos = procedureComboBox.Text.IndexOf(ProcSeparator);
@@ -771,7 +774,7 @@ namespace TBF.UI
}
public void ReloadProcedureComboBoxItems(string procedureNameToSelect)
{
{
if (!procedureComboBox.Enabled)
{
/// Test cycle in progress, reload combo box items when the session is finished
@@ -915,7 +918,7 @@ namespace TBF.UI
if (SelectedProcedure != null) BenchControlPanel.ReloadTests();
}
}
}
/// <summary>
/// To each unresolved procedure finds the first native procedure that matches teh unresolved procedure
@@ -977,8 +980,8 @@ namespace TBF.UI
return true;
}
private void procedureComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
private void procedureComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
foreach (var item in procedureComboBox.Items)
{
var procInfo = item as ProcedureInfo;
@@ -1004,7 +1007,7 @@ namespace TBF.UI
}
}
}
}
}
private void procedureComboBox_KeyPress(object sender, KeyPressEventArgs e)
{
@@ -1162,39 +1165,56 @@ namespace TBF.UI
private void appDiagnosticMenuItem_Click(object sender, EventArgs e)
{
/*diagApi = new DiagApi(liveLogCache);
//diagApi.AddLog("ahoj, toto je prvy log");
ILog loger = LogManager.GetLogger("logCache");
log.Debug("ahoj, ideme");*/
LiveLogCache.Instance.AddLog("=== Live diagnostic entry ===");
DiagApi liveDiagApi = new DiagApi();
/*try
try
{
// Predpoklad�me, �e ApplicationDiagnostic.exe je v rovnakom adres�ri ako hlavn� aplik�cia
string exePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "AppDiagnostic.exe");
string exePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "AppDiagnostic", "AppDiagnostic.exe");
if (File.Exists(exePath))
if (!File.Exists(exePath))
{
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = exePath,
UseShellExecute = true // Spust� aplik�ciu ako samostatn� proces
};
System.Diagnostics.Process.Start(startInfo);
MessageBox.Show($"AppDiagnostic.exe not found:\n{exePath}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
else
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo
{
MessageBox.Show("ApplicationDiagnostic.exe not found.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
FileName = exePath,
WorkingDirectory = Path.GetDirectoryName(exePath),
UseShellExecute = true
});
// Temporary diagnostic test.
SendDiagnosticTestLogs();
}
catch (Exception ex)
{
MessageBox.Show($"Failed to start ApplicationDiagnostic: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}*/
MessageBox.Show($"Failed to start AppDiagnostic or send test logs: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void SendDiagnosticTestLogs()
{
NLog.Logger deviceLogger = NLog.LogManager.GetLogger("TBF.TestBench.DeviceSimulation");
deviceLogger.Trace("TRACE: Communication cycle started.");
deviceLogger.Debug("DEBUG: Device configuration loaded.");
deviceLogger.Info("INFO: Test bench started.");
deviceLogger.Warn("WARN: Simulated pressure is approaching the limit.");
for (int position = 1; position <= 10; position++)
{
deviceLogger.Debug($"Reading simulated device at position {position}.");
}
try
{
throw new InvalidOperationException("Simulated device communication failure.");
}
catch (Exception ex)
{
deviceLogger.Error(ex, "ERROR: Unable to communicate with simulated device.");
}
deviceLogger.Fatal("FATAL: Simulated emergency stop.");
}
private void optoHeadsToolStripMenuItem_Click(object sender, EventArgs e)
+38
View File
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
internalLogLevel="Trace"
internalLogFile="${basedir}/nlog-internal.log"
throwConfigExceptions="true">
<extensions>
<add assembly="Xylem.Common.Utils.Logging" />
<add assembly="AppDiagnostic.Logging" />
</extensions>
<targets>
<target name="uiTrace"
xsi:type="UiTarget"
layout="${time}|${level:uppercase=true:padding=-5}|${message}" />
<target name="appDiagnostic"
xsi:type="AppDiagnostic"
pipeName="Sensus.AppDiagnostic.LogPipe"
queueLimit="10000"
reconnectDelayMilliseconds="500"
connectTimeoutMilliseconds="250"
layout="${message}" />
<target name="logfile"
xsi:type="File"
fileName="${basedir}/GenesisCordonelInterfaceLogger.log"
layout="${longdate}|${level:uppercase=true:padding=-5}|${logger}|${message}|${exception:format=tostring}" />
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="appDiagnostic" />
<logger name="GenesisCordonelInterface*" minlevel="Trace" writeTo="uiTrace" />
<logger name="GenesisCordonelInterface*" minlevel="Trace" writeTo="logfile" />
</rules>
</nlog>
+14 -1
View File
@@ -1,9 +1,13 @@
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
internalLogLevel="Trace"
internalLogFile="${basedir}/nlog-internal.log"
throwConfigExceptions="true">
<extensions>
<add assembly="Xylem.Common.Utils.Logging" />
<add assembly="AppDiagnostic.Logging" />
</extensions>
<targets>
@@ -11,6 +15,14 @@
xsi:type="UiTarget"
layout="${time}|${level:uppercase=true:padding=-5}|${message}" />
<target name="appDiagnostic"
xsi:type="AppDiagnostic"
pipeName="Sensus.AppDiagnostic.LogPipe"
queueLimit="10000"
reconnectDelayMilliseconds="500"
connectTimeoutMilliseconds="250"
layout="${message}" />
<target name="logfile"
xsi:type="File"
fileName="${basedir}/GenesisCordonelInterfaceLogger.log"
@@ -18,6 +30,7 @@
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="appDiagnostic" />
<logger name="GenesisCordonelInterface*" minlevel="Trace" writeTo="uiTrace" />
<logger name="GenesisCordonelInterface*" minlevel="Trace" writeTo="logfile" />
</rules>