Sicherung

This commit is contained in:
Maier Stephan SI
2023-01-02 04:33:49 +01:00
parent bea46135fd
commit d01747f75a
284 changed files with 6106 additions and 65112 deletions

View File

@@ -0,0 +1,76 @@
<Project Sdk="Microsoft.NET.Sdk" InitialTargets="Log">
<PropertyGroup>
<Copyright>Copyright (c) 2015-2022 by Ivan Gavryliuk</Copyright>
<AssemblyTitle>Config.Net</AssemblyTitle>
<Authors>Ivan Gavryliuk (@aloneguid)</Authors>
<AssemblyName>Config.Net</AssemblyName>
<PackageId>Config.Net</PackageId>
<AssemblyVersion>4.0.0.0</AssemblyVersion>
<FileVersion>4.7.3.0</FileVersion>
<Version>4.7.3</Version>
<Description>Super simple configuration framework for .NET focused on developer ergonomics and strong typing. Supports multiple configuration sources such as .ini, .json, .xml files, as well as external providers pluggable by other NuGet packages.</Description>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<WarningsAsErrors />
<PackageIcon>icon.png</PackageIcon>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
<PackageIconUrl />
<Nullable>enable</Nullable>
<LangVersion>latest</LangVersion>
<PackageProjectUrl>https://github.com/aloneguid/config</PackageProjectUrl>
<RepositoryUrl>https://github.com/aloneguid/config</RepositoryUrl>
<PackageReadmeFile>README.md</PackageReadmeFile>
</PropertyGroup>
<Choose>
<When Condition="'$(OS)' == 'Windows_NT'">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;netstandard2.1;netcoreapp3.1;net5.0;net6.0</TargetFrameworks>
</PropertyGroup>
</When>
<Otherwise>
<PropertyGroup>
<TargetFrameworks>netstandard2.0;netstandard2.1;netcoreapp3.1;net5.0;net6.0;net7.0</TargetFrameworks>
</PropertyGroup>
</Otherwise>
</Choose>
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
</PropertyGroup>
<Target Name="Log">
<Message Text="HELLO $(OS)" Importance="high"/>
</Target>
<ItemGroup>
<PackageReference Include="Castle.Core" Version="5.0.0" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="6.0.0" />
</ItemGroup>
<!-- we need latest system.text.json in order to support writeable json in earlier targets -->
<ItemGroup Condition="'$(TargetFramework)' != 'net6.0'">
<PackageReference Include="System.Text.Json" Version="6.0.5"/>
</ItemGroup>
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
<ItemGroup>
<None Include="..\..\docs\README.md">
<Pack>True</Pack>
<PackagePath>\</PackagePath>
</None>
<None Include="..\icon.png">
<Pack>True</Pack>
<PackagePath></PackagePath>
</None>
</ItemGroup>
<ItemGroup>
<PackageReference Update="DotNet.ReproducibleBuilds" Version="1.1.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,72 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using Castle.DynamicProxy;
using Config.Net.Core;
namespace Config.Net
{
public class ConfigurationBuilder<T> where T : class
{
private readonly ProxyGenerator _generator = new ProxyGenerator();
private List<IConfigStore> _stores = new List<IConfigStore>();
private TimeSpan _cacheInterval = TimeSpan.Zero;
private readonly List<ITypeParser> _customParsers = new List<ITypeParser>();
public ConfigurationBuilder()
{
TypeInfo ti = typeof(T).GetTypeInfo();
if (!ti.IsInterface) throw new ArgumentException($"{ti.FullName} must be an interface", ti.FullName);
}
/// <summary>
/// Creates an instance of the configuration interface
/// </summary>
/// <returns></returns>
public T Build()
{
var valueHandler = new ValueHandler(_customParsers);
var ioHandler = new IoHandler(_stores, valueHandler, _cacheInterval);
T instance = _generator.CreateInterfaceProxyWithoutTarget<T>(new InterfaceInterceptor(typeof(T), ioHandler));
return instance;
}
/// <summary>
/// Set to anything different from <see cref="TimeSpan.Zero"/> to add caching for values. By default
/// Config.Net doesn't cache any values
/// </summary>
/// <param name="time"></param>
/// <returns></returns>
public ConfigurationBuilder<T> CacheFor(TimeSpan time)
{
_cacheInterval = time;
return this;
}
public ConfigurationBuilder<T> UseConfigStore(IConfigStore store)
{
_stores.Add(store);
return this;
}
/// <summary>
/// Adds a custom type parser
/// </summary>
public ConfigurationBuilder<T> UseTypeParser(ITypeParser parser)
{
if (parser == null)
{
throw new ArgumentNullException(nameof(parser));
}
_customParsers.Add(parser);
return this;
}
}
}

View File

@@ -0,0 +1,146 @@
using System.Reflection;
using Config.Net.Stores;
using System.Collections.Generic;
using Config.Net.Stores.Impl.CommandLine;
namespace Config.Net
{
/// <summary>
/// Configuration extensions
/// </summary>
public static class ConfigurationExtensions
{
/// <summary>
/// In-memory dictionary. Optionally you can pass pre-created dictionary, otherwise it will be created internally as empty.
/// </summary>
public static ConfigurationBuilder<TInterface> UseInMemoryDictionary<TInterface>(
this ConfigurationBuilder<TInterface> builder,
IDictionary<string, string>? container = null) where TInterface : class
{
builder.UseConfigStore(new DictionaryConfigStore(container));
return builder;
}
/// <summary>
/// Standard app.config (web.config) builder store. Read-only.
/// </summary>
public static ConfigurationBuilder<TInterface> UseAppConfig<TInterface>(this ConfigurationBuilder<TInterface> builder) where TInterface : class
{
builder.UseConfigStore(new AppConfigStore());
return builder;
}
/// <summary>
/// Reads builder from the .dll.config or .exe.config file.
/// </summary>
/// <param name="builder"></param>
/// <param name="assembly">Reference to the assembly to look for</param>
/// <returns></returns>
public static ConfigurationBuilder<TInterface> UseAssemblyConfig<TInterface>(this ConfigurationBuilder<TInterface> builder, Assembly assembly) where TInterface : class
{
builder.UseConfigStore(new AssemblyConfigStore(assembly));
return builder;
}
/// <summary>
/// Uses system environment variables
/// </summary>
public static ConfigurationBuilder<TInterface> UseEnvironmentVariables<TInterface>(this ConfigurationBuilder<TInterface> builder) where TInterface : class
{
builder.UseConfigStore(new EnvironmentVariablesStore());
return builder;
}
/// <summary>
/// Simple INI storage.
/// </summary>
/// <param name="builder"></param>
/// <param name="iniFilePath">File does not have to exist, however it will be created as soon as you try to write to it.</param>
/// <param name="parseInlineComments">When true, inline comments are parsed. It is set to false by default so inline comments are considered a part of the value.</param>
/// <returns></returns>
public static ConfigurationBuilder<TInterface> UseIniFile<TInterface>(this ConfigurationBuilder<TInterface> builder,
string iniFilePath,
bool parseInlineComments = false) where TInterface : class
{
builder.UseConfigStore(new IniFileConfigStore(iniFilePath, true, parseInlineComments));
return builder;
}
/// <summary>
/// Simple INI storage.
/// </summary>
/// <param name="builder"></param>
/// <param name="iniString">File contents</param>
/// <param name="parseInlineComments">When true, inline comments are parsed. It is set to false by default so inline comments are considered a part of the value</param>
/// <returns></returns>
public static ConfigurationBuilder<TInterface> UseIniString<TInterface>(this ConfigurationBuilder<TInterface> builder,
string iniString,
bool parseInlineComments = false) where TInterface : class
{
builder.UseConfigStore(new IniFileConfigStore(iniString, false, parseInlineComments));
return builder;
}
/// <summary>
/// Accepts builder from the command line arguments. This is not intended to replace a command line parsing framework but rather
/// complement it in a builder like way. Uses current process' command line parameters automatically
/// </summary>
/// <param name="builder">Configuration object</param>
/// <param name="isCaseSensitive">When true argument names are case sensitive, false by default</param>
/// <returns>Changed builder</returns>
public static ConfigurationBuilder<TInterface> UseCommandLineArgs<TInterface>(this ConfigurationBuilder<TInterface> builder,
bool isCaseSensitive = false,
params KeyValuePair<string, int>[] parameterNameToPosition)
where TInterface : class
{
builder.UseConfigStore(new CommandLineConfigStore(null, isCaseSensitive, parameterNameToPosition));
return builder;
}
public static ConfigurationBuilder<TInterface> UseCommandLineArgs<TInterface>(this ConfigurationBuilder<TInterface> builder,
bool isCaseSensitive = false,
string[]? args = null,
params KeyValuePair<string, int>[] parameterNameToPosition)
where TInterface : class
{
builder.UseConfigStore(new CommandLineConfigStore(args, isCaseSensitive, parameterNameToPosition));
return builder;
}
public static ConfigurationBuilder<TInterface> UseCommandLineArgs<TInterface>(this ConfigurationBuilder<TInterface> builder,
params KeyValuePair<string, int>[] parameterNameToPosition)
where TInterface : class
{
builder.UseConfigStore(new CommandLineConfigStore(null, false, parameterNameToPosition));
return builder;
}
/// <summary>
/// Uses JSON file as a builder storage.
/// </summary>
/// <param name="builder">Configuration object.</param>
/// <param name="jsonFilePath">Full path to json storage file.</param>
/// <returns>Changed builder.</returns>
/// <remarks>Storage file does not have to exist, however it will be created as soon as first write performed.</remarks>
public static ConfigurationBuilder<TInterface> UseJsonFile<TInterface>(this ConfigurationBuilder<TInterface> builder, string jsonFilePath) where TInterface : class
{
builder.UseConfigStore(new JsonConfigStore(jsonFilePath, true));
return builder;
}
/// <summary>
/// Uses JSON file as a builder storage.
/// </summary>
/// <param name="builder">Configuration object.</param>
/// <param name="jsonString">Json document.</param>
/// <returns>Changed builder.</returns>
/// <remarks>Storage file does not have to exist, however it will be created as soon as first write performed.</remarks>
public static ConfigurationBuilder<TInterface> UseJsonString<TInterface>(this ConfigurationBuilder<TInterface> builder, string jsonString) where TInterface : class
{
builder.UseConfigStore(new JsonConfigStore(jsonString, false));
return builder;
}
}
}

View File

@@ -0,0 +1,204 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
namespace Config.Net.Core.Box
{
static class BoxFactory
{
public static Dictionary<string, ResultBox> Discover(Type t, ValueHandler valueHandler, string? basePath)
{
var result = new Dictionary<string, ResultBox>();
DiscoverProperties(t, valueHandler, result, basePath);
DiscoverMethods(t, valueHandler, result);
return result;
}
private static void DiscoverProperties(Type t, ValueHandler valueHandler, Dictionary<string, ResultBox> result, string? basePath)
{
IEnumerable<PropertyInfo> properties = GetHierarchyPublicProperties(t);
foreach (PropertyInfo pi in properties)
{
Type propertyType = pi.PropertyType;
ResultBox rbox;
bool isCollection = false;
if(ResultBox.TryGetCollection(propertyType, out propertyType))
{
if(pi.SetMethod != null)
{
throw new NotSupportedException($"Collection properties cannot have a setter. Detected at '{OptionPath.Combine(basePath, pi.Name)}'");
}
isCollection = true;
}
if(propertyType.GetTypeInfo().IsInterface)
{
rbox = new ProxyResultBox(pi.Name, propertyType);
}
else
{
rbox = new PropertyResultBox(pi.Name, propertyType);
}
ValidateSupportedType(rbox, valueHandler);
AddAttributes(rbox, pi, valueHandler);
//adjust to collection
if(isCollection)
{
rbox = new CollectionResultBox(pi.Name, rbox);
AddAttributes(rbox, pi, valueHandler);
}
result[pi.Name] = rbox;
}
}
private static void DiscoverMethods(Type t, ValueHandler valueHandler, Dictionary<string, ResultBox> result)
{
TypeInfo ti = t.GetTypeInfo();
IEnumerable<MethodInfo> methods = ti.DeclaredMethods.Where(m => !m.IsSpecialName);
foreach (MethodInfo method in methods)
{
var mbox = new MethodResultBox(method);
AddAttributes(mbox, method, valueHandler);
result[mbox.Name] = mbox;
}
}
private static void ValidateSupportedType(ResultBox rb, ValueHandler valueHandler)
{
Type? t = null;
if (rb is PropertyResultBox pbox)
t = rb.ResultBaseType;
if (t != null && !valueHandler.IsSupported(t))
{
throw new NotSupportedException($"type {t} on object '{rb.Name}' is not supported.");
}
}
private static object? GetDefaultValue(Type t)
{
if (t.GetTypeInfo().IsValueType) return Activator.CreateInstance(t);
return null;
}
private static void AddAttributes(ResultBox box, PropertyInfo pi, ValueHandler valueHandler)
{
AddAttributes(box, valueHandler,
pi.GetCustomAttribute<OptionAttribute>(),
pi.GetCustomAttribute<DefaultValueAttribute>());
}
private static void AddAttributes(ResultBox box, MethodInfo mi, ValueHandler valueHandler)
{
AddAttributes(box, valueHandler, mi.GetCustomAttribute<OptionAttribute>(), mi.GetCustomAttribute<DefaultValueAttribute>());
}
private static void AddAttributes(ResultBox box, ValueHandler valueHandler, params Attribute?[] attributes)
{
OptionAttribute? optionAttribute = attributes.OfType<OptionAttribute>().FirstOrDefault();
DefaultValueAttribute? defaultValueAttribute = attributes.OfType<DefaultValueAttribute>().FirstOrDefault();
if (optionAttribute?.Alias != null)
{
box.StoreByName = optionAttribute.Alias;
}
box.DefaultResult = GetDefaultValue(optionAttribute?.DefaultValue, box, valueHandler) ??
GetDefaultValue(defaultValueAttribute?.Value, box, valueHandler) ??
GetDefaultValue(box.ResultType);
}
private static object? GetDefaultValue(object? defaultValue, ResultBox box, ValueHandler valueHandler)
{
object? result = null;
if (defaultValue != null)
{
//validate that types for default value match
Type dvt = defaultValue.GetType();
if (dvt != box.ResultType && dvt != typeof(string))
{
throw new InvalidCastException($"Default value for option {box.Name} is of type {dvt.FullName} whereas the property has type {box.ResultType.FullName}. To fix this, either set default value to type {box.ResultType.FullName} or a string parseable to the target type.");
}
if (box.ResultType != typeof(string) && dvt == typeof(string))
{
valueHandler.TryParse(box.ResultType, (string?)defaultValue, out result);
}
}
if (result == null)
{
result = defaultValue;
}
return result;
}
private static PropertyInfo[] GetHierarchyPublicProperties(Type type)
{
var propertyInfos = new List<PropertyInfo>();
var considered = new List<TypeInfo>();
var queue = new Queue<TypeInfo>();
considered.Add(type.GetTypeInfo());
queue.Enqueue(type.GetTypeInfo());
while (queue.Count > 0)
{
TypeInfo typeInfo = queue.Dequeue();
//add base interfaces to the queue
foreach (Type subInterface in typeInfo.ImplementedInterfaces)
{
TypeInfo subInterfaceTypeInfo = subInterface.GetTypeInfo();
if (considered.Contains(subInterfaceTypeInfo)) continue;
considered.Add(subInterfaceTypeInfo);
queue.Enqueue(subInterfaceTypeInfo);
}
//add base classes to the queue
if (typeInfo.BaseType != null)
{
TypeInfo baseType = typeInfo.BaseType.GetTypeInfo();
if (!considered.Contains(baseType))
{
considered.Add(baseType);
queue.Enqueue(baseType);
}
}
//get properties from the current type
IEnumerable<PropertyInfo> newProperties = typeInfo.DeclaredProperties.Where(p => !propertyInfos.Contains(p));
propertyInfos.InsertRange(0, newProperties);
}
return propertyInfos.ToArray();
}
}
}

View File

@@ -0,0 +1,109 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace Config.Net.Core.Box
{
class CollectionResultBox : ResultBox
{
private readonly ResultBox _elementResultBox;
private string? _basePath;
private DynamicReader? _reader;
public CollectionResultBox(string name, ResultBox elementBox) : base(name, elementBox.ResultType, null)
{
_elementResultBox = elementBox;
}
public ResultBox ElementResultBox => _elementResultBox;
public bool IsInitialised { get; private set; }
public IEnumerable? CollectionInstance { get; private set; }
public void Initialise(string? basePath, int length, DynamicReader reader)
{
_basePath = basePath;
_reader = reader;
CollectionInstance = CreateGenericEnumerable(length);
IsInitialised = true;
}
private IEnumerable? CreateGenericEnumerable(int count)
{
Type t = typeof(DynamicEnumerable<>);
t = t.MakeGenericType(ResultType);
IEnumerable? instance = (IEnumerable?)Activator.CreateInstance(t, count, this);
return instance;
}
private object? ReadAt(int index)
{
return _reader?.Read(ElementResultBox, index);
}
private class DynamicEnumerable<T> : IEnumerable<T>
{
private readonly int _count;
private readonly CollectionResultBox _parent;
public DynamicEnumerable(int count, CollectionResultBox parent)
{
_count = count;
_parent = parent;
}
public IEnumerator<T> GetEnumerator()
{
return new DynamicEnumerator<T>(_count, _parent);
}
IEnumerator IEnumerable.GetEnumerator()
{
return new DynamicEnumerator<T>(_count, _parent);
}
}
private class DynamicEnumerator<T> : IEnumerator<T>
{
private int _index = -1;
private readonly int _count;
private readonly CollectionResultBox _parent;
private T? _current;
public DynamicEnumerator(int count, CollectionResultBox parent)
{
_count = count;
_parent = parent;
}
#pragma warning disable CS8603 // Possible null reference return.
public T Current => _current ?? default(T);
object IEnumerator.Current => _current;
#pragma warning restore CS8603 // Possible null reference return.
public void Dispose()
{
}
public bool MoveNext()
{
_index += 1;
_current = (T?)_parent.ReadAt(_index);
return _index < _count;
}
public void Reset()
{
_index = -1;
}
}
}
}

View File

@@ -0,0 +1,87 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
namespace Config.Net.Core.Box
{
class MethodResultBox : ResultBox
{
public MethodResultBox(MethodInfo methodInfo) : base(GetName(methodInfo), GetReturnType(methodInfo), null)
{
StoreByName = GetStoreName(methodInfo);
IsGettter = IsGet(methodInfo);
}
public bool IsGettter { get; private set; }
/// <summary>
/// Composes a uniqueue method name using method name itself and parameter type names, separated by underscore
/// </summary>
public static string GetName(MethodInfo mi)
{
ParameterInfo[] parameters = mi.GetParameters();
var sb = new StringBuilder();
sb.Append(mi.Name);
foreach (ParameterInfo pi in parameters)
{
sb.Append("-");
sb.Append(pi.ParameterType.ToString());
}
return sb.ToString();
}
public string GetValuePath(object[] arguments)
{
var sb = new StringBuilder();
sb.Append(StoreByName);
bool ignoreLast = !IsGettter;
for (int i = 0; i < arguments.Length - (ignoreLast ? 1 : 0); i++)
{
object value = arguments[i];
if (value == null) continue;
if (sb.Length > 0)
{
sb.Append(OptionPath.Separator);
}
sb.Append(value.ToString());
}
return sb.ToString();
}
private static string GetStoreName(MethodInfo mi)
{
string name = mi.Name;
if (name.StartsWith("get", StringComparison.OrdinalIgnoreCase) ||
name.StartsWith("set", StringComparison.OrdinalIgnoreCase))
{
name = name.Substring(3);
}
return name;
}
private static bool IsGet(MethodInfo mi)
{
return mi.ReturnType != typeof(void);
}
private static Type GetReturnType(MethodInfo mi)
{
ParameterInfo[] parameters = mi.GetParameters();
if (parameters == null || parameters.Length == 0)
{
throw new InvalidOperationException($"method {mi.Name} must have at least one parameter");
}
Type returnType = IsGet(mi) ? mi.ReturnType : parameters[parameters.Length - 1].ParameterType;
return returnType;
}
}
}

View File

@@ -0,0 +1,51 @@
using System;
using System.Reflection;
namespace Config.Net.Core.Box
{
class PropertyResultBox : ResultBox
{
public PropertyResultBox(string name, Type resultType) : base(name, resultType, null)
{
}
public static bool IsProperty(MethodInfo mi, out bool isGetter, out string? name)
{
if (mi.Name.StartsWith("get_"))
{
isGetter = true;
name = mi.Name.Substring(4);
return true;
}
if (mi.Name.StartsWith("set_"))
{
isGetter = false;
name = mi.Name.Substring(4);
return true;
}
isGetter = false;
name = null;
return false;
}
public static bool IsProperty(MethodInfo mi, out string? name)
{
if (mi.Name.StartsWith("get_") || mi.Name.StartsWith("set_"))
{
name = mi.Name.Substring(4);
return true;
}
name = null;
return false;
}
public static bool IsGetProperty(MethodInfo mi)
{
return mi.Name.StartsWith("get_");
}
}
}

View File

@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using Castle.DynamicProxy;
namespace Config.Net.Core.Box
{
class ProxyResultBox : ResultBox
{
private static readonly ProxyGenerator ProxyGenerator = new ProxyGenerator();
private readonly Dictionary<int, object> _indexToProxyInstance = new Dictionary<int, object>();
public ProxyResultBox(string name, Type interfaceType) : base(name, interfaceType, null)
{
}
public bool IsInitialisedAt(int index)
{
return _indexToProxyInstance.ContainsKey(index);
}
public object GetInstanceAt(int index)
{
return _indexToProxyInstance[index];
}
public void InitialiseAt(int index, IoHandler ioHandler, string prefix)
{
object instance = ProxyGenerator.CreateInterfaceProxyWithoutTarget(ResultBaseType,
new InterfaceInterceptor(ResultBaseType, ioHandler, prefix));
_indexToProxyInstance[index] = instance;
}
}
}

View File

@@ -0,0 +1,73 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
namespace Config.Net.Core.Box
{
abstract class ResultBox
{
private string? _storeByName;
protected ResultBox(string name, Type resultType, object? defaultResult)
{
Name = name;
ResultType = resultType;
ResultBaseType = GetBaseType(resultType);
DefaultResult = defaultResult;
}
public string Name { get; }
public string StoreByName
{
get => _storeByName ?? Name;
set => _storeByName = value;
}
public Type ResultType { get; }
public Type ResultBaseType { get; }
public object? DefaultResult { get; set; }
#region [ Utility Methods ]
private static Type GetBaseType(Type t)
{
TypeInfo ti = t.GetTypeInfo();
if (ti.IsClass)
{
return t;
}
else
{
if (ti.IsGenericType && ti.GetGenericTypeDefinition() == typeof(Nullable<>))
{
return ti.GenericTypeArguments[0];
}
else
{
return t;
}
}
}
internal static bool TryGetCollection(Type t, out Type elementType)
{
TypeInfo ti = t.GetTypeInfo();
if(ti.IsGenericType && ti.GetGenericTypeDefinition() == typeof(IEnumerable<>))
{
elementType = ti.GenericTypeArguments[0];
return true;
}
elementType = t;
return false;
}
#endregion
}
}

View File

@@ -0,0 +1,74 @@
using System;
using System.Collections.Generic;
using System.Text;
using Config.Net.Core.Box;
namespace Config.Net.Core
{
class DynamicReader
{
private readonly string? _basePath;
private readonly IoHandler _ioHandler;
public DynamicReader(string? basePath, IoHandler ioHandler)
{
_basePath = basePath;
_ioHandler = ioHandler;
}
public object? Read(ResultBox rbox, int index = -1, params object[] arguments)
{
if (rbox is PropertyResultBox pbox) return ReadProperty(pbox, index);
if (rbox is ProxyResultBox xbox) return ReadProxy(xbox, index);
if (rbox is CollectionResultBox cbox) return ReadCollection(cbox, index);
if (rbox is MethodResultBox mbox) return ReadMethod(mbox, arguments);
throw new NotImplementedException($"don't know how to read {rbox.GetType()}");
}
private object? ReadProperty(PropertyResultBox pbox, int index)
{
string path = OptionPath.Combine(index, _basePath, pbox.StoreByName);
return _ioHandler.Read(pbox.ResultBaseType, path, pbox.DefaultResult);
}
private object ReadProxy(ProxyResultBox xbox, int index)
{
if (!xbox.IsInitialisedAt(index))
{
string prefix = OptionPath.Combine(index, _basePath, xbox.StoreByName);
xbox.InitialiseAt(index, _ioHandler, prefix);
}
return xbox.GetInstanceAt(index);
}
private object? ReadCollection(CollectionResultBox cbox, int index)
{
string lengthPath = OptionPath.Combine(index, _basePath, cbox.StoreByName);
lengthPath = OptionPath.AddLength(lengthPath);
if (!cbox.IsInitialised)
{
int length = (int?)_ioHandler.Read(typeof(int), lengthPath, 0) ?? 0;
cbox.Initialise(_basePath, length, this);
}
return cbox.CollectionInstance;
}
private object? ReadMethod(MethodResultBox mbox, object[] arguments)
{
string path = mbox.GetValuePath(arguments);
path = OptionPath.Combine(_basePath, path);
return _ioHandler.Read(mbox.ResultBaseType, path, mbox.DefaultResult);
}
}
}

View File

@@ -0,0 +1,48 @@
using System;
using Config.Net.Core.Box;
namespace Config.Net.Core
{
class DynamicWriter
{
private readonly string? _basePath;
private readonly IoHandler _ioHandler;
public DynamicWriter(string? basePath, IoHandler ioHandler)
{
_basePath = basePath;
_ioHandler = ioHandler;
}
public void Write(ResultBox rbox, object[] arguments)
{
if (rbox is PropertyResultBox pbox) WriteProperty(pbox, arguments);
else if (rbox is MethodResultBox mbox) WriteMethod(mbox, arguments);
else if (rbox is ProxyResultBox xbox) WriteProxy(xbox, arguments);
else throw new NotImplementedException($"don't know how to write {rbox.GetType()}");
}
private void WriteProperty(PropertyResultBox pbox, object[] arguments)
{
string path = OptionPath.Combine(_basePath, pbox.StoreByName);
_ioHandler.Write(pbox.ResultBaseType, path, arguments[0]);
}
private void WriteMethod(MethodResultBox mbox, object[] arguments)
{
object value = arguments[arguments.Length - 1];
string path = mbox.GetValuePath(arguments);
_ioHandler.Write(mbox.ResultBaseType, path, value);
}
private void WriteProxy(ProxyResultBox xbox, object[] arguments)
{
throw new NotSupportedException("cannot assign values to interface properties");
}
}
}

View File

@@ -0,0 +1,16 @@
using System.Collections.Generic;
namespace Config.Net.Core
{
static class Extensions
{
public static TValue? GetValueOrDefaultInternal<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key)
where TKey: notnull
where TValue: class
{
if (!dictionary.TryGetValue(key, out TValue? value)) return default(TValue);
return value;
}
}
}

View File

@@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using System.Text;
using Config.Net.Core;
using Config.Net.TypeParsers;
namespace Config.Net.Core
{
/// <summary>
/// Helper class to implement flat arrays
/// </summary>
public static class FlatArrays
{
public static bool IsArrayLength(string? key, Func<string, string?> getValue, out int length)
{
if (!OptionPath.TryStripLength(key, out key))
{
length = 0;
return false;
}
string? value = key == null ? null : getValue(key);
if (value == null)
{
length = 0;
return false;
}
if (!StringArrayParser.TryParse(value, out string[]? ar))
{
length = 0;
return false;
}
length = ar?.Length ?? 0;
return true;
}
public static bool IsArrayElement(string? key, Func<string, string?> getValue, out string? value)
{
if(!OptionPath.TryStripIndex(key, out key, out int index))
{
value = null;
return false;
}
string? arrayString = key == null ? null : getValue(key);
if (!StringArrayParser.TryParse(arrayString, out string[]? array) || index >= array?.Length)
{
value = null;
return false;
}
value = array?[index] ?? null;
return true;
}
}
}

View File

@@ -0,0 +1,103 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System.Text;
using Castle.DynamicProxy;
using Config.Net.Core.Box;
namespace Config.Net.Core
{
class InterfaceInterceptor : IInterceptor
{
private readonly Dictionary<string, ResultBox> _boxes;
private IoHandler _ioHandler;
private readonly string? _prefix;
private readonly DynamicReader _reader;
private readonly DynamicWriter _writer;
private readonly bool _isInpc;
private PropertyChangedEventHandler? _inpcHandler;
public InterfaceInterceptor(Type interfaceType, IoHandler ioHandler, string? prefix = null)
{
_boxes = BoxFactory.Discover(interfaceType, ioHandler.ValueHandler, prefix);
_ioHandler = ioHandler;
_prefix = prefix;
_reader = new DynamicReader(prefix, ioHandler);
_writer = new DynamicWriter(prefix, ioHandler);
_isInpc = interfaceType.GetInterface(nameof(INotifyPropertyChanged)) != null;
}
private ResultBox FindBox(IInvocation invocation)
{
if (PropertyResultBox.IsProperty(invocation.Method, out string? propertyName) && propertyName != null)
{
return _boxes[propertyName];
}
else //method
{
string name = MethodResultBox.GetName(invocation.Method);
return _boxes[name];
}
}
public void Intercept(IInvocation invocation)
{
if (TryInterceptInpc(invocation)) return;
ResultBox rbox = FindBox(invocation);
bool isRead =
(rbox is PropertyResultBox && PropertyResultBox.IsGetProperty(invocation.Method)) ||
(rbox is ProxyResultBox && PropertyResultBox.IsGetProperty(invocation.Method)) ||
(rbox is MethodResultBox mbox && mbox.IsGettter) ||
(rbox is CollectionResultBox);
if(isRead)
{
invocation.ReturnValue = _reader.Read(rbox, -1, invocation.Arguments);
return;
}
else
{
_writer.Write(rbox, invocation.Arguments);
TryNotifyInpc(invocation, rbox);
}
}
private bool TryInterceptInpc(IInvocation invocation)
{
if (!_isInpc) return false;
if (invocation.Method.Name == "add_PropertyChanged")
{
invocation.ReturnValue =
_inpcHandler =
(PropertyChangedEventHandler)Delegate.Combine(_inpcHandler, (Delegate)invocation.Arguments[0]);
return true;
}
else if(invocation.Method.Name == "remove_PropertyChanged")
{
invocation.ReturnValue =
_inpcHandler =
(PropertyChangedEventHandler?)Delegate.Remove(_inpcHandler, (Delegate)invocation.Arguments[0]);
return true;
}
return false;
}
private void TryNotifyInpc(IInvocation invocation, ResultBox rbox)
{
if (_inpcHandler == null || rbox is MethodResultBox) return;
_inpcHandler.Invoke(invocation.InvocationTarget, new PropertyChangedEventArgs(rbox.Name));
if(rbox.Name != rbox.StoreByName)
{
//notify on StoreByName as well
_inpcHandler.Invoke(invocation.InvocationTarget, new PropertyChangedEventArgs(rbox.StoreByName));
}
}
}
}

View File

@@ -0,0 +1,70 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
namespace Config.Net.Core
{
class IoHandler
{
private readonly IEnumerable<IConfigStore> _stores;
private readonly ValueHandler _valueHandler;
private readonly TimeSpan _cacheInterval;
private readonly ConcurrentDictionary<string, LazyVar<object>> _keyToValue = new ConcurrentDictionary<string, LazyVar<object>>();
public IoHandler(IEnumerable<IConfigStore> stores, ValueHandler valueHandler, TimeSpan cacheInterval)
{
_stores = stores ?? throw new ArgumentNullException(nameof(stores));
_valueHandler = valueHandler ?? throw new ArgumentNullException(nameof(valueHandler));
_cacheInterval = cacheInterval;
}
public ValueHandler ValueHandler => _valueHandler;
public object? Read(Type baseType, string path, object? defaultValue)
{
if(!_keyToValue.TryGetValue(path, out _))
{
var v = new LazyVar<object>(_cacheInterval, () => ReadNonCached(baseType, path, defaultValue));
_keyToValue[path] = v;
return v.GetValue();
}
return _keyToValue[path].GetValue();
}
public void Write(Type baseType, string path, object? value)
{
string? valueToWrite = _valueHandler.ConvertValue(baseType, value);
foreach (IConfigStore store in _stores.Where(s => s.CanWrite))
{
store.Write(path, valueToWrite);
}
}
private object? ReadNonCached(Type baseType, string path, object? defaultValue)
{
string? rawValue = ReadFirstValue(path);
return _valueHandler.ParseValue(baseType, rawValue, defaultValue);
}
private string? ReadFirstValue(string key)
{
foreach (IConfigStore store in _stores)
{
if (store.CanRead)
{
string? value = store.Read(key);
if (value != null) return value;
}
}
return null;
}
}
}

View File

@@ -0,0 +1,96 @@
using System;
using System.Threading.Tasks;
namespace Config.Net.Core
{
/// <summary>
/// Implements a lazy value i.e. that can expire in future
/// </summary>
/// <typeparam name="T"></typeparam>
class LazyVar<T> where T : class
{
private readonly Func<Task<T?>>? _renewFuncAsync;
private readonly Func<T?>? _renewFunc;
private DateTime _lastRenewed = DateTime.MinValue;
private readonly TimeSpan _timeToLive;
private T? _value;
/// <summary>
/// Creates an instance of a lazy variable with time-to-live value
/// </summary>
/// <param name="timeToLive">Time to live. Setting to <see cref="TimeSpan.Zero"/> disables caching completely</param>
/// <param name="renewFunc"></param>
public LazyVar(TimeSpan timeToLive, Func<Task<T?>> renewFunc)
{
_timeToLive = timeToLive;
_renewFuncAsync = renewFunc ?? throw new ArgumentNullException(nameof(renewFunc));
_renewFunc = null;
}
/// <summary>
/// Creates an instance of a lazy variable with time-to-live value
/// </summary>
/// <param name="timeToLive">Time to live. Setting to <see cref="TimeSpan.Zero"/> disables caching completely</param>
/// <param name="renewFunc"></param>
public LazyVar(TimeSpan timeToLive, Func<T?> renewFunc)
{
_timeToLive = timeToLive;
_renewFuncAsync = null;
_renewFunc = renewFunc ?? throw new ArgumentNullException(nameof(renewFunc));
}
/// <summary>
/// Gets the values, renewing it if necessary
/// </summary>
/// <returns>Value</returns>
public async Task<T?> GetValueAsync()
{
if (_renewFuncAsync == null)
{
throw new InvalidOperationException("cannot renew value, async delegate is not specified");
}
if (_timeToLive == TimeSpan.Zero)
{
return await _renewFuncAsync();
}
bool expired = (DateTime.UtcNow - _lastRenewed) > _timeToLive;
if (expired)
{
_value = await _renewFuncAsync();
_lastRenewed = DateTime.UtcNow;
}
return _value;
}
/// <summary>
/// Gets the values, renewing it if necessary
/// </summary>
/// <returns>Value</returns>
public T? GetValue()
{
if (_renewFunc == null)
{
throw new InvalidOperationException("cannot renew value, synchronous delegate is not specified");
}
if (_timeToLive == TimeSpan.Zero)
{
return _renewFunc();
}
bool expired = (DateTime.UtcNow - _lastRenewed) > _timeToLive;
if (expired)
{
_value = _renewFunc();
_lastRenewed = DateTime.UtcNow;
}
return _value;
}
}
}

View File

@@ -0,0 +1,88 @@
namespace Config.Net.Core
{
public static class OptionPath
{
public const string Separator = ".";
private const string IndexOpen = "[";
private const string IndexClose = "]";
public const string LengthFunction = ".$l";
public static string Combine(params string?[] parts)
{
return Combine(-1, parts);
}
public static string AddLength(string path)
{
return path + LengthFunction;
}
public static bool TryStripLength(string? path, out string? noLengthPath)
{
if (path == null)
{
noLengthPath = path;
return false;
}
if (!path.EndsWith(LengthFunction))
{
noLengthPath = path;
return false;
}
noLengthPath = path.Substring(0, path.Length - LengthFunction.Length);
return true;
}
/// <summary>
/// For indexed paths like "creds[1]" strips index part so it becomes:
/// - noIndexPath: "creds"
/// - index: 1
///
/// If path is not indexed returns false and noIndexPath is equal to path itself
/// </summary>
public static bool TryStripIndex(string? path, out string? noIndexPath, out int index)
{
if (path == null)
{
index = 0;
noIndexPath = path;
return false;
}
int openIdx = path.IndexOf(IndexOpen);
int closeIdx = path.IndexOf(IndexClose);
if (openIdx == -1 || closeIdx == -1 || openIdx > closeIdx || closeIdx != path.Length - 1)
{
noIndexPath = path;
index = 0;
return false;
}
noIndexPath = path.Substring(0, openIdx);
int.TryParse(path.Substring(openIdx + 1, closeIdx - openIdx - 1), out index);
return true;
}
public static string Combine(int index, params string?[] parts)
{
string s = string.Empty;
for (int i = 0; i < parts.Length; i++)
{
if (s.Length > 0) s += Separator;
if (!string.IsNullOrEmpty(parts[i])) s += parts[i];
}
if (index != -1)
{
s = $"{s}{IndexOpen}{index}{IndexClose}";
}
return s;
}
}
}

View File

@@ -0,0 +1,157 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using Config.Net.TypeParsers;
namespace Config.Net.Core
{
class ValueHandler
{
private readonly DefaultParser _defaultParser = new DefaultParser();
private readonly ConcurrentDictionary<Type, ITypeParser> _allParsers = new ConcurrentDictionary<Type, ITypeParser>();
private readonly HashSet<Type> _supportedTypes = new HashSet<Type>();
private static readonly ValueHandler _default = new ValueHandler();
public ValueHandler(IEnumerable<ITypeParser>? customParsers = null)
{
foreach (ITypeParser pc in GetBuiltInParsers())
{
AddParser(pc);
}
if(customParsers != null)
{
foreach(ITypeParser pc in customParsers)
{
AddParser(pc);
}
}
}
public void AddParser(ITypeParser parser)
{
if (parser == null)
{
throw new ArgumentNullException(nameof(parser));
}
foreach (Type t in parser.SupportedTypes)
{
_allParsers[t] = parser;
_supportedTypes.Add(t);
}
}
public bool IsSupported(Type t)
{
return _supportedTypes.Contains(t) || _defaultParser.IsSupported(t);
}
public object? ParseValue(Type baseType, string? rawValue, object? defaultValue)
{
object? result;
if (rawValue == null)
{
result = defaultValue;
}
else
{
if(!TryParse(baseType, rawValue, out result))
{
result = defaultValue;
}
}
return result;
}
public bool TryParse(Type propertyType, string? rawValue, out object? result)
{
if (_defaultParser.IsSupported(propertyType)) //type here must be a non-nullable one
{
if (!_defaultParser.TryParse(rawValue, propertyType, out result))
{
return false;
}
}
else
{
ITypeParser? typeParser = GetParser(propertyType);
if (typeParser == null)
{
result = null;
return false;
}
if (!typeParser.TryParse(rawValue, propertyType, out result))
{
return false;
}
}
return true;
}
public string? ConvertValue(Type baseType, object? value)
{
string? str;
if (value == null)
{
str = null;
}
else
{
if (_defaultParser.IsSupported(baseType))
{
str = _defaultParser.ToRawString(value);
}
else
{
ITypeParser? parser = GetParser(value.GetType());
str = parser?.ToRawString(value);
}
}
return str;
}
private ITypeParser? GetParser(Type t)
{
ITypeParser? result;
_allParsers.TryGetValue(t, out result);
return result;
}
/// <summary>
/// Scans assembly for types implementing <see cref="ITypeParser"/> and builds Type => instance dictionary.
/// Not sure if I should use reflection here, however the assembly is small and this shouldn't cause any
/// performance issues
/// </summary>
/// <returns></returns>
private static IEnumerable<ITypeParser> GetBuiltInParsers()
{
return new ITypeParser[]
{
new FloatParser(),
new DoubleParser(),
new DecimalParser(),
new SByteParser(),
new ShortParser(),
new IntParser(),
new LongParser(),
new ByteParser(),
new UShortParser(),
new UIntParser(),
new ULongParser(),
new StringArrayParser(),
new StringParser(),
new TimeSpanParser(),
new CoreParsers(),
new NetworkCredentialParser()
};
}
}
}

View File

@@ -0,0 +1,35 @@
using System;
namespace Config.Net
{
/// <summary>
/// Configuration store interface
/// </summary>
public interface IConfigStore : IDisposable
{
/// <summary>
/// Returns true if store supports read operation.
/// </summary>
bool CanRead { get; }
/// <summary>
/// Returns true if store supports write operation.
/// </summary>
bool CanWrite { get; }
/// <summary>
/// Reads a key from the store.
/// </summary>
/// <param name="key">Key name.</param>
/// <returns>If key exists in the store returns the value, othwise returns null.</returns>
string? Read(string key);
/// <summary>
/// Writes a key to the store.
/// </summary>
/// <param name="key">Key name</param>
/// <param name="value">Key value. Value of NULL usually means the key will be deleted, at least
/// this is the recomendation for the custom store implementers.</param>
void Write(string key, string? value);
}
}

32
Config.Net/ITypeParser.cs Normal file
View File

@@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
namespace Config.Net
{
/// <summary>
/// Type parser interface
/// </summary>
public interface ITypeParser
{
/// <summary>
/// Returns the list of supported types this type parser handles
/// </summary>
IEnumerable<Type> SupportedTypes { get; }
/// <summary>
/// Tries to parse a value from string
/// </summary>
/// <param name="value"></param>
/// <param name="t"></param>
/// <param name="result"></param>
/// <returns></returns>
bool TryParse(string? value, Type t, out object? result);
/// <summary>
/// Converts value to a string to store in a backed store
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
string? ToRawString(object? value);
}
}

View File

@@ -0,0 +1,19 @@
using System;
namespace Config.Net
{
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Method, AllowMultiple = false)]
public class OptionAttribute : Attribute
{
/// <summary>
/// Alias is used to override option name if it's stored by a different name in external stores
/// </summary>
public string? Alias { get; set; }
/// <summary>
/// Set to override the default value if option is not found in any stores
/// </summary>
public object? DefaultValue { get; set; }
}
}

View File

@@ -0,0 +1,3 @@
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("Config.Net.Tests")]

View File

@@ -0,0 +1,313 @@
/*using System;
using System.Reflection;
using System.Collections.Concurrent;
using Config.Net.TypeParsers;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
namespace Config.Net
{
/// <summary>
/// Generic container for test settings
/// </summary>
public abstract class SettingsContainer
{
private readonly IConfigConfiguration _config = new ContainerConfiguration();
private readonly ConcurrentDictionary<string, Option> _nameToOption =
new ConcurrentDictionary<string, Option>();
private readonly ConcurrentDictionary<string, OptionValue> _nameToOptionValue =
new ConcurrentDictionary<string, OptionValue>();
private static readonly DefaultParser DefaultParser = new DefaultParser();
private readonly string _namespace;
private bool _isConfigured;
/// <summary>
/// Constructs the container in default namespace
/// </summary>
protected SettingsContainer() : this(null)
{
}
/// <summary>
/// Constructs the container allowing to specify a custom namespace
/// </summary>
/// <param name="namespaceName"></param>
protected SettingsContainer(string namespaceName)
{
_namespace = namespaceName;
DiscoverProperties();
}
/// <summary>
/// Reads the option value
/// </summary>
/// <typeparam name="T">Option type</typeparam>
/// <param name="option">Option reference</param>
/// <returns>Option value</returns>
public T Read<T>(Option<T> option)
{
CheckConfigured();
CheckCanParse(option.NonNullableType);
OptionValue optionValue;
_nameToOptionValue.TryGetValue(option.Name, out optionValue);
if (!optionValue.IsExpired(_config.CacheTimeout))
{
return (T) optionValue.RawValue;
}
string value = ReadFirstValue(option.Name);
if (value == null)
{
optionValue.RawValue = option.DefaultValue;
}
else if (DefaultParser.IsSupported(option.NonNullableType))
{
object resultObject;
if (DefaultParser.TryParse(value, option.NonNullableType, out resultObject))
{
optionValue.Update<T>((T) resultObject);
}
else
{
optionValue.Update(option.DefaultValue);
}
}
else
{
ITypeParser typeParser = _config.GetParser(option.NonNullableType);
object result;
typeParser.TryParse(value, option.NonNullableType, out result);
optionValue.Update<T>((T) result);
}
OnReadOption(option, optionValue.RawValue);
return (T) optionValue.RawValue;
}
/// <summary>
/// Writes a new value to the option
/// </summary>
/// <typeparam name="T">Option type</typeparam>
/// <param name="option">Option reference</param>
/// <param name="value">New value</param>
public void Write<T>(Option<T> option, T value)
{
CheckConfigured();
CheckCanParse(option.NonNullableType);
OptionValue optionValue;
_nameToOptionValue.TryGetValue(option.Name, out optionValue);
foreach (IConfigStore store in _config.Stores)
{
if (store.CanWrite)
{
string rawValue = AreEqual(value, option.DefaultValue) ? null : GetRawStringValue(option, value);
store.Write(option.Name, rawValue);
break;
}
}
optionValue.Update(value);
OnWriteOption(option, value);
}
/// <summary>
/// This method is called internally before containers is ready for use. You can specify
/// configuration stores or any other options here.
/// </summary>
/// <param name="configuration"></param>
protected abstract void OnConfigure(IConfigConfiguration configuration);
/// <summary>
/// Called after any value is read
/// </summary>
/// <param name="option">Optiond that is read</param>
/// <param name="value">Option value read from a store</param>
protected virtual void OnReadOption(Option option, object value)
{
}
/// <summary>
/// Called before any value is written
/// </summary>
/// <param name="option">Option that is written</param>
/// <param name="value">Option value to write</param>
protected virtual void OnWriteOption(Option option, object value)
{
}
private void CheckConfigured()
{
if (_isConfigured) return;
OnConfigure(_config);
_isConfigured = true;
}
[Ignore]
private void DiscoverProperties()
{
Type t = this.GetType();
Type optionType = typeof(Option);
IEnumerable<PropertyInfo> properties = t.GetRuntimeProperties()
.Where(f => f.PropertyType.GetTypeInfo().IsSubclassOf(optionType) && f.GetCustomAttribute<IgnoreAttribute>() == null).ToList();
// Only include fields that have not already been added as properties
IEnumerable<FieldInfo> fields = t.GetRuntimeFields()
.Where(f => f.IsPublic && f.FieldType.GetTypeInfo().IsSubclassOf(optionType)).ToList();
foreach (PropertyInfo pi in properties)
{
AssignOption(pi.GetValue(this), pi, pi.PropertyType.GetTypeInfo(), pi.CanWrite, v => pi.SetValue(this, v));
}
foreach (FieldInfo fi in fields)
{
if (properties.Any(p => p.Name == fi.Name))
throw new ArgumentException(
$"Field '{fi.Name}' has already been defined as a property.");
var methInfo = fi.FieldType.GetTypeInfo();
if (!methInfo.IsSubclassOf(optionType)) continue;
AssignOption(fi.GetValue(this), fi, methInfo, true, v => fi.SetValue(this, v));
}
}
private void AssignOption(object objValue, MemberInfo pi, TypeInfo propInfo, bool writeable,
Action<object> setter)
{
{
//check if it has the value
if (objValue == null)
{
// Throw an exception if it's impossible to assign a default value to a read-only property with no default object assigned
if (!writeable)
throw new ArgumentException(
$"Property/Field '{pi.Name}' must either be settable or be pre-initialised with an Option<> object as a property, or marked as readonly if a field");
//create default instance if it doesn't exist
var nt = typeof(Option<>);
Type[] ntArgs = propInfo.GetGenericArguments();
Type ntGen = nt.MakeGenericType(ntArgs);
objValue = Activator.CreateInstance(ntGen);
//set the instance value back to the container
setter(objValue);
}
Option value = (Option) objValue;
if (string.IsNullOrEmpty(value.Name)) value.Name = pi.Name;
value.Name = GetFullKeyName(value.Name);
value._parent = this;
value.NonNullableType = Nullable.GetUnderlyingType(value.ValueType);
value.IsNullable = value.NonNullableType != null;
if (value.NonNullableType == null) value.NonNullableType = value.ValueType;
_nameToOption[value.Name] = value;
_nameToOptionValue[value.Name] = new OptionValue();
}
}
private string GetFullKeyName(string name)
{
if (string.IsNullOrEmpty(_namespace)) return name;
return _namespace + "." + name;
}
private bool CanParse(Type t)
{
return _config.HasParser(t) || DefaultParser.IsSupported(t);
}
private string ReadFirstValue(string key)
{
foreach (IConfigStore store in _config.Stores)
{
if (store.CanRead)
{
string value = store.Read(key);
if (value != null) return value;
}
}
return null;
}
private void CheckCanParse(Type t)
{
if (!CanParse(t))
{
throw new ArgumentException("value parser for " + t.FullName +
" is not registered and not supported by default parser");
}
}
private bool AreEqual(object value1, object value2)
{
if (value1 == null && value2 == null) return true;
if (value1 != null && value2 != null)
{
Type t1 = value1.GetType();
Type t2 = value2.GetType();
if (t1.IsArray && t2.IsArray)
{
return AreEqual((Array) value1, (Array) value2);
}
}
return value1 != null && value1.Equals(value2);
}
private bool AreEqual(Array a, Array b)
{
if (a == null && b == null) return true;
if (a == null || b == null) return false;
if (a.Length != b.Length) return false;
for (int i = 0; i < a.Length; i++)
{
object obj1 = a.GetValue(i);
object obj2 = b.GetValue(i);
if (!AreEqual(obj1, obj2)) return false;
}
return true;
}
private string GetRawStringValue<T>(Option<T> option, T value)
{
string stringValue = null;
ITypeParser typeParser = _config.GetParser(option.NonNullableType);
if (typeParser != null)
{
stringValue = typeParser.ToRawString(value);
}
else
{
if (DefaultParser.IsSupported(typeof(T)))
{
stringValue = DefaultParser.ToRawString(value);
}
}
return stringValue;
}
}
}*/

View File

@@ -0,0 +1,48 @@
using System;
using System.Collections.Specialized;
using System.Configuration;
namespace Config.Net.Stores
{
/// <summary>
/// Standard app.config (web.config) configuration store. Read-only.
/// </summary>
class AppConfigStore : IConfigStore
{
public string Name => "App.config";
public bool CanRead => true;
public bool CanWrite => false;
public string? Read(string key)
{
if(key == null) return null;
//first, look at appsettings and connection strings
string? value = ConfigurationManager.AppSettings[key] ?? ConfigurationManager.ConnectionStrings[key]?.ConnectionString;
if(value == null)
{
int idx = key.IndexOf('.');
if(idx != -1)
{
string sectionName = key.Substring(0, idx);
if(ConfigurationManager.GetSection(sectionName) is NameValueCollection nvsc)
{
string keyName = key.Substring(idx + 1);
value = nvsc[keyName];
}
}
}
return value;
}
public void Write(string key, string? value) => throw new NotSupportedException();
public void Dispose()
{
}
}
}

View File

@@ -0,0 +1,61 @@
using System;
using System.Configuration;
using System.IO;
using System.Reflection;
namespace Config.Net.Stores
{
/// <summary>
/// Reads configuration from the .dll.config or .exe.config file.
/// </summary>
class AssemblyConfigStore : IConfigStore
{
private readonly Configuration _configuration;
/// <summary>
/// Creates a new instance of assembly configuration store (.dll.config files)
/// </summary>
/// <param name="assembly">reference to the assembly to look for</param>
public AssemblyConfigStore(Assembly assembly)
{
_configuration = ConfigurationManager.OpenExeConfiguration(assembly.Location);
}
/// <summary>
/// Store name
/// </summary>
public string Name => Path.GetFileName(_configuration.FilePath);
/// <summary>
/// Store is readable
/// </summary>
public bool CanRead => true;
/// <summary>
/// Store is not writeable
/// </summary>
public bool CanWrite => false;
/// <summary>
/// Reads the value by key
/// </summary>
public string? Read(string key)
{
KeyValueConfigurationElement element = _configuration.AppSettings.Settings[key];
return element?.Value;
}
/// <summary>
/// Writing is not supported
/// </summary>
public void Write(string key, string? value) => throw new NotSupportedException();
/// <summary>
/// Nothing to dispose
/// </summary>
public void Dispose()
{
}
}
}

View File

@@ -0,0 +1,64 @@
using System;
using System.Collections.Generic;
using Config.Net.Core;
namespace Config.Net.Stores
{
class DictionaryConfigStore : IConfigStore
{
private readonly IDictionary<string, string> _container;
public DictionaryConfigStore(IDictionary<string, string>? container = null)
{
_container = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
if(container != null)
{
foreach(KeyValuePair<string, string> item in container)
{
_container[item.Key] = item.Value;
}
}
}
public bool CanRead => true;
public bool CanWrite => true;
public void Dispose()
{
}
public string? Read(string key)
{
if (key == null) return null;
if (FlatArrays.IsArrayLength(key, k => _container.GetValueOrDefaultInternal(k), out int length))
{
return length.ToString();
}
if (FlatArrays.IsArrayElement(key, k => _container.GetValueOrDefaultInternal(k), out string? element))
{
return element;
}
return _container.GetValueOrDefaultInternal(key);
}
public void Write(string key, string? value)
{
if (key == null) return;
if (value == null)
{
_container.Remove(key);
}
else
{
_container[key] = value;
}
}
}
}

View File

@@ -0,0 +1,76 @@
using System;
using System.Collections.Generic;
using Config.Net.Core;
namespace Config.Net.Stores
{
/// <summary>
/// Uses system environment variables
/// </summary>
class EnvironmentVariablesStore : IConfigStore
{
/// <summary>
/// Readable
/// </summary>
public bool CanRead => true;
/// <summary>
/// Writeable
/// </summary>
public bool CanWrite => true;
/// <summary>
/// Store name
/// </summary>
public string Name => "System Environment";
/// <summary>
/// Reads value by key
/// </summary>
public string? Read(string key)
{
if (key == null) return null;
foreach(string variant in GetAllKeyVariants(key))
{
if (FlatArrays.IsArrayLength(variant, k => Environment.GetEnvironmentVariable(k), out int length))
{
return length.ToString();
}
if (FlatArrays.IsArrayElement(variant, k => Environment.GetEnvironmentVariable(k), out string? element))
{
return element;
}
string? value = Environment.GetEnvironmentVariable(variant);
if (value != null) return value;
}
return null;
}
/// <summary>
/// Writes value by key
/// </summary>
public void Write(string key, string? value)
{
Environment.SetEnvironmentVariable(key, value);
}
private IEnumerable<string> GetAllKeyVariants(string key)
{
var result = new List<string>();
result.Add(key);
result.Add(key.ToUpper().Replace(".", "_"));
return result;
}
/// <summary>
/// Nothing to dispose
/// </summary>
public void Dispose()
{
}
}
}

View File

@@ -0,0 +1,21 @@
namespace Config.Net.Stores.Formats.Ini
{
class IniComment : IniEntity
{
public const string CommentSeparator = ";";
public IniComment(string value)
{
Value = value;
}
public string Value { get; set; }
public string EscapedValue
{
get { return Value.Replace("\r", @"\r").Replace("\n", @"\n"); }
}
public override string ToString() => Value;
}
}

View File

@@ -0,0 +1,6 @@
namespace Config.Net.Stores.Formats.Ini
{
abstract class IniEntity
{
}
}

View File

@@ -0,0 +1,72 @@
using System;
namespace Config.Net.Stores.Formats.Ini
{
internal class IniKeyValue : IniEntity
{
public const string KeyValueSeparator = "=";
public IniKeyValue(string key, string value, string? comment)
{
if(key == null) throw new ArgumentNullException(nameof(key));
Key = key;
Value = value;
Comment = comment == null ? null : new IniComment(comment);
}
public string Key { get; }
public string Value { get; set; }
public string EscapedKey
{
get { return Key.Replace("\r", @"\r").Replace("\n", @"\n"); }
}
public string EscapedValue
{
get { return Value.Replace("\r", @"\r").Replace("\n", @"\n"); }
}
public IniComment? Comment { get; }
public static IniKeyValue? FromLine(string line, bool parseInlineComments, bool unescapeNewLines = false)
{
int idx = line.IndexOf(KeyValueSeparator, StringComparison.CurrentCulture);
if(idx == -1) return null;
string key = line.Substring(0, idx).Trim();
string value = line.Substring(idx + 1).Trim();
string? comment = null;
if (parseInlineComments)
{
idx = value.LastIndexOf(IniComment.CommentSeparator, StringComparison.CurrentCulture);
if (idx != -1)
{
comment = value.Substring(idx + 1).Trim();
value = value.Substring(0, idx).Trim();
}
}
if(unescapeNewLines)
{
key = UnescapeString(key);
value = UnescapeString(value);
comment = (comment != null) ? UnescapeString(comment) : null;
}
return new IniKeyValue(key, value, comment);
}
private static string UnescapeString(string key)
{
return key.Replace(@"\r", "\r").Replace(@"\n", "\n");
}
public override string ToString()
{
return $"{Value}";
}
}
}

View File

@@ -0,0 +1,121 @@
using System;
using System.Collections.Generic;
using System.IO;
namespace Config.Net.Stores.Formats.Ini
{
class IniSection
{
public const string SectionKeySeparator = ".";
private readonly List<IniEntity> _entities = new List<IniEntity>();
private readonly Dictionary<string, IniKeyValue> _keyToValue = new Dictionary<string, IniKeyValue>();
/// <summary>
/// Section name
/// </summary>
public string? Name { get; set; }
/// <summary>
///
/// </summary>
/// <param name="name">Pass null to work with global section</param>
public IniSection(string? name)
{
if(name != null)
{
if (name.StartsWith("[")) name = name.Substring(1);
if (name.EndsWith("]")) name = name.Substring(0, name.Length - 1);
}
Name = name;
}
public void Add(IniEntity entity)
{
_entities.Add(entity);
IniKeyValue? ikv = entity as IniKeyValue;
if(ikv != null)
{
_keyToValue[ikv.Key] = ikv;
}
}
public IniKeyValue? Set(string key, string? value)
{
if(value == null)
{
IniKeyValue? ikv;
if(_keyToValue.TryGetValue(key, out ikv))
{
_keyToValue.Remove(key);
return ikv;
}
return null;
}
else
{
IniKeyValue? ikv;
if(_keyToValue.TryGetValue(key, out ikv))
{
ikv.Value = value;
}
else
{
ikv = new IniKeyValue(key, value, null);
Add(ikv);
}
return ikv;
}
}
public static void SplitKey(string fullKey, out string? sectionName, out string keyName)
{
int idx = fullKey.IndexOf(SectionKeySeparator, StringComparison.CurrentCulture);
if(idx == -1)
{
sectionName = null;
keyName = fullKey;
}
else
{
sectionName = fullKey.Substring(0, idx);
keyName = fullKey.Substring(idx + 1);
}
}
public void WriteTo(StreamWriter writer)
{
foreach(IniEntity entity in _entities)
{
IniKeyValue? ikv = entity as IniKeyValue;
if(ikv != null)
{
writer.Write($"{ikv.EscapedKey}{IniKeyValue.KeyValueSeparator}{ikv.EscapedValue}");
if(ikv.Comment != null)
{
writer.Write(" ");
writer.Write(IniComment.CommentSeparator);
writer.Write(ikv.Comment.EscapedValue);
}
writer.WriteLine();
continue;
}
IniComment? comment = entity as IniComment;
if(comment != null)
{
writer.Write(IniComment.CommentSeparator);
writer.WriteLine(comment.Value);
}
}
}
public override string ToString()
{
return Name ?? string.Empty;
}
}
}

View File

@@ -0,0 +1,130 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace Config.Net.Stores.Formats.Ini
{
class StructuredIniFile
{
private const string _sectionBegin = "[";
private const string _sectionEnd = "]";
private static readonly char[] _sectionTrims = {'[', ']'};
private readonly IniSection _globalSection;
private readonly List<IniSection> _sections = new List<IniSection>();
private readonly Dictionary<string, IniKeyValue> _fullKeyNameToValue = new Dictionary<string, IniKeyValue>(StringComparer.InvariantCultureIgnoreCase);
public StructuredIniFile()
{
_globalSection = new IniSection(null);
_sections.Add(_globalSection);
}
public string? this[string key]
{
get
{
if(key == null) return null;
IniKeyValue? value;
return !_fullKeyNameToValue.TryGetValue(key, out value) ? null : value.Value;
}
set
{
if(key == null) return;
IniSection.SplitKey(key, out string? sectionName, out string keyName);
IniSection? section = sectionName == null
? _globalSection
: _sections.FirstOrDefault(s => s.Name == sectionName);
if(section == null)
{
section = new IniSection(sectionName);
_sections.Add(section);
}
IniKeyValue? ikv = section.Set(keyName, value);
//update the local cache
if(ikv != null)
{
if(value == null)
{
_fullKeyNameToValue.Remove(key);
}
else
{
_fullKeyNameToValue[key] = ikv;
}
}
}
}
public static StructuredIniFile ReadFrom(Stream inputStream, bool parseInlineComments, bool unescapeNewLines = false)
{
if(inputStream == null) throw new ArgumentNullException(nameof(inputStream));
var file = new StructuredIniFile();
using(var reader = new StreamReader(inputStream))
{
IniSection section = file._globalSection;
string? line;
while((line = reader.ReadLine()) != null)
{
line = line.Trim();
if(line.StartsWith(_sectionBegin))
{
//start new section
line = line.Trim();
section = new IniSection(line);
file._sections.Add(section);
}
else if(line.StartsWith(IniComment.CommentSeparator))
{
//whole line is a comment
string comment = line.Substring(1).Trim();
section.Add(new IniComment(comment));
}
else
{
IniKeyValue? ikv = IniKeyValue.FromLine(line, parseInlineComments, unescapeNewLines);
if(ikv == null) continue;
section.Add(ikv);
string fullKey = section.Name == null
? ikv.Key
: $"{section.Name}{IniSection.SectionKeySeparator}{ikv.Key}";
file._fullKeyNameToValue[fullKey] = ikv;
}
}
}
return file;
}
public void WriteTo(Stream outputStream)
{
if(outputStream == null) throw new ArgumentNullException(nameof(outputStream));
using(var writer = new StreamWriter(outputStream))
{
foreach(IniSection section in _sections)
{
if(section.Name != null)
{
writer.WriteLine();
writer.WriteLine($"{_sectionBegin}{section.Name}{_sectionEnd}");
}
section.WriteTo(writer);
}
}
}
//private static
}
}

View File

@@ -0,0 +1,102 @@
using System;
using System.Collections.Generic;
using Config.Net.Core;
using Config.Net.TypeParsers;
namespace Config.Net.Stores.Impl.CommandLine
{
class CommandLineConfigStore : IConfigStore
{
private readonly Dictionary<string, string> _nameToValue;
private static readonly char[] ArgPrefixes = new[] { '-', '/' };
private static readonly string[] ArgDelimiters = new[] { "=", ":" };
private readonly bool _isCaseSensitive;
public bool CanRead => true;
public bool CanWrite => false;
public CommandLineConfigStore(string[]? args = null, bool isCaseSensitive = false, IEnumerable<KeyValuePair<string, int>>? nameToPosition = null)
{
_isCaseSensitive = isCaseSensitive;
_nameToValue = new Dictionary<string, string>(_isCaseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase);
Parse(args ?? Environment.GetCommandLineArgs(), nameToPosition);
}
public void Dispose()
{
}
public string? Read(string key)
{
if (key == null) return null;
if(FlatArrays.IsArrayLength(key, k => _nameToValue.GetValueOrDefaultInternal(k), out int length))
{
return length.ToString();
}
if(FlatArrays.IsArrayElement(key, k => _nameToValue.GetValueOrDefaultInternal(k), out string? element))
{
return element;
}
string? value;
_nameToValue.TryGetValue(key, out value);
return value;
}
private string[]? GetAsArray(string key)
{
if (!_nameToValue.TryGetValue(key, out string? allString)) return null;
if (!StringArrayParser.TryParse(allString, out string[]? ar)) return null;
return ar;
}
public void Write(string key, string? value)
{
throw new NotSupportedException("command line cannot be written to");
}
private void Parse(string[] args, IEnumerable<KeyValuePair<string, int>>? nameToPosition)
{
_nameToValue.Clear();
var posToName = new Dictionary<int, string>();
if (nameToPosition != null)
{
foreach(KeyValuePair<string, int> p in nameToPosition)
{
if (p.Key != null)
{
posToName[p.Value] = p.Key;
}
}
}
if (args == null) return;
for (int i = 0; i < args.Length; i++)
{
string? name;
string? value;
Tuple<string, string?>? nameValue = Utils.SplitByDelimiter(args[i], ArgDelimiters);
name = nameValue?.Item1.TrimStart(ArgPrefixes);
value = nameValue?.Item2;
if (name != null && value != null)
{
_nameToValue[name] = value;
}
else if(name != null && posToName.TryGetValue(i, out string? ptnName))
{
_nameToValue[ptnName] = args[i];
}
}
}
}
}

View File

@@ -0,0 +1,120 @@
using System;
using System.IO;
using System.Text;
using Config.Net.Core;
using Config.Net.Stores.Formats.Ini;
namespace Config.Net.Stores
{
/// <summary>
/// Simple INI storage.
/// </summary>
class IniFileConfigStore : IConfigStore
{
private readonly string? _fullName;
private readonly StructuredIniFile _iniFile;
/// <summary>
///
/// </summary>r
/// <param name="name">File does not have to exist, however it will be created as soon as you
/// try to write to it</param>
public IniFileConfigStore(string name, bool isFilePath, bool parseInlineComments, bool unescapeNewLines = false)
{
if (name == null) throw new ArgumentNullException(nameof(name));
if (isFilePath)
{
_fullName = Path.GetFullPath(name); // Allow relative path to INI file
string? parentDirPath = Path.GetDirectoryName(_fullName);
if (string.IsNullOrEmpty(parentDirPath)) throw new IOException("the provided directory path is not valid");
if (!Directory.Exists(parentDirPath))
{
Directory.CreateDirectory(parentDirPath);
}
_iniFile = ReadIniFile(_fullName, parseInlineComments, unescapeNewLines);
CanWrite = true;
}
else
{
_iniFile = ReadIniContent(name, parseInlineComments, unescapeNewLines);
CanWrite = false;
}
CanRead = true;
}
public string Name => ".ini";
public bool CanRead { get; }
public bool CanWrite { get; }
public string? Read(string key)
{
if (FlatArrays.IsArrayLength(key, k => _iniFile[k], out int length))
{
return length.ToString();
}
if (FlatArrays.IsArrayElement(key, k => _iniFile[k], out string? element))
{
return element;
}
return _iniFile[key];
}
public void Write(string key, string? value)
{
if (!CanWrite) return;
_iniFile[key] = value;
WriteIniFile();
}
private static StructuredIniFile ReadIniFile(string fullName, bool parseInlineComments, bool unescapeNewLines = false)
{
FileInfo iniFile = new FileInfo(fullName);
if(iniFile.Exists)
{
using(FileStream stream = iniFile.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return StructuredIniFile.ReadFrom(stream, parseInlineComments, unescapeNewLines);
}
}
else
{
return new StructuredIniFile();
}
}
private static StructuredIniFile ReadIniContent(string content, bool parseInlineComments, bool unescapeNewLines = false)
{
using (Stream input = new MemoryStream(Encoding.UTF8.GetBytes(content)))
{
return StructuredIniFile.ReadFrom(input, parseInlineComments, unescapeNewLines);
}
}
private void WriteIniFile()
{
if (_fullName == null) return;
using(FileStream stream = File.Create(_fullName))
{
_iniFile.WriteTo(stream);
}
}
public void Dispose()
{
//nothing to dispose
}
}
}

View File

@@ -0,0 +1,165 @@
using System;
using System.IO;
using System.Runtime.InteropServices.ComTypes;
using System.Text.Json;
using System.Text.Json.Nodes;
using Config.Net.Core;
namespace Config.Net.Stores
{
/// <summary>
/// Simple JSON storage using System.Text.Json
/// </summary>
public class JsonConfigStore : IConfigStore
{
private readonly string? _pathName;
private JsonNode? _j;
/// <summary>
/// Create JSON storage in the file specified in <paramref name="name"/>.
/// </summary>
/// <param name="name">Name of the file, either path to JSON storage file, or json file content.</param>
/// <param name="isFilePath">Set to true if <paramref name="name"/> specifies file name, otherwise false. </param>
/// <exception cref="ArgumentNullException"><paramref name="name"/> is null.</exception>
/// <exception cref="IOException">Provided path is not valid.</exception>
/// <remarks>Storage file does not have to exist, however it will be created as soon as first write performed.</remarks>
public JsonConfigStore(string name, bool isFilePath)
{
if (name == null) throw new ArgumentNullException(nameof(name));
if (isFilePath)
{
_pathName = Path.GetFullPath(name); // Allow relative path to JSON file
_j = ReadJsonFile(_pathName);
}
else
{
_j = ReadJsonString(name);
}
}
public void Dispose()
{
// nothing to dispose.
}
public string Name => "json";
public bool CanRead => true;
public bool CanWrite => _pathName != null;
public string? Read(string rawKey)
{
if (string.IsNullOrEmpty(rawKey) || _j == null) return null;
bool isLength = OptionPath.TryStripLength(rawKey, out string? key);
if (key == null) return null;
string[] parts = key.Split('.');
if (parts.Length == 0) return null;
JsonNode? node = _j;
foreach (string rawPart in parts)
{
bool isIndex = OptionPath.TryStripIndex(rawPart, out string? part, out int partIndex);
if (part == null) return null;
node = node![part];
if (node == null) return null;
if (isIndex)
{
if (!(node is JsonArray ja)) return null;
if (partIndex < ja.Count)
{
node = ja[partIndex];
}
else
return null;
}
}
if (isLength)
return node is JsonArray ja ? ja.Count.ToString() : null;
return node!.ToString();
}
public void Write(string key, string? value)
{
if (string.IsNullOrEmpty(_pathName))
throw new InvalidOperationException("please specify file name for writeable config");
if (_j == null) _j = new JsonObject();
// navigate to target element, create if needed
string[] parts = key.Split('.');
if (parts.Length == 0) return;
JsonNode? node = _j;
string? lastPart = null;
foreach (string rawPart in parts)
{
bool isIndex = OptionPath.TryStripIndex(rawPart, out string? part, out int partIndex);
if (part == null) return;
lastPart = part;
JsonNode? nextNode = node[part];
if (isIndex)
{
throw new NotImplementedException();
}
else
{
if (nextNode == null)
{
//create missing node
nextNode = new JsonObject();
node[part] = nextNode;
}
}
node = nextNode;
}
JsonObject? parent = node.Parent as JsonObject;
parent!.Remove(lastPart!);
parent![lastPart!] = JsonValue.Create(value);
string js = _j.ToJsonString(new JsonSerializerOptions { WriteIndented = true });
FileInfo file = new FileInfo(_pathName);
if (file is not null)
{
if (file.Directory is not null)
{
file.Directory.Create();
}
}
File.WriteAllText(_pathName, js);
}
private static JsonNode? ReadJsonFile(string fileName)
{
if (File.Exists(fileName))
{
string json = File.ReadAllText(fileName);
return ReadJsonString(json);
}
return null;
}
private static JsonNode? ReadJsonString(string jsonString)
{
return JsonNode.Parse(jsonString);
}
}
}

View File

@@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
namespace Config.Net.TypeParsers
{
class ByteParser : ITypeParser
{
public IEnumerable<Type> SupportedTypes => new[] { typeof(byte) };
public bool TryParse(string? value, Type t, out object? result)
{
if(value == null)
{
result = false;
return false;
}
byte ir;
bool parsed;
if (value.StartsWith("0x"))
{
parsed = byte.TryParse(value.Substring(2), NumberStyles.HexNumber, TypeParserSettings.DefaultCulture, out ir);
}
else
{
parsed = byte.TryParse(value, NumberStyles.Integer, TypeParserSettings.DefaultCulture, out ir);
}
result = ir;
return parsed;
}
public string? ToRawString(object? value)
{
return ((byte?)value)?.ToString(TypeParserSettings.DefaultNumericFormat, TypeParserSettings.DefaultCulture);
}
}
}

View File

@@ -0,0 +1,95 @@
using System;
using System.Collections.Generic;
using System.Globalization;
namespace Config.Net.TypeParsers
{
/// <summary>
/// Container for core types. Eventually all simple parsers will merge into this class.
/// </summary>
class CoreParsers : ITypeParser
{
public IEnumerable<Type> SupportedTypes => new[] { typeof(Uri), typeof(bool), typeof(Guid), typeof(DateTime) };
private static readonly Dictionary<string, bool> BooleanTrueValues =
new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase)
{
{"true", true},
{"yes", true},
{"1", true},
};
public string? ToRawString(object? value)
{
if (value == null) return null;
Type t = value.GetType();
if(t == typeof(Uri))
return value.ToString();
if(t == typeof(bool))
return value?.ToString()?.ToLowerInvariant();
if (t == typeof(Guid))
return value.ToString();
if(t == typeof(DateTime))
return ((DateTime)value).ToUniversalTime().ToString("u");
return null;
}
public bool TryParse(string? value, Type t, out object? result)
{
if(value == null)
{
result = null;
return false;
}
if(t == typeof(Uri))
{
Uri uri = new Uri(value);
result = uri;
return true;
}
if(t == typeof(bool))
{
if(BooleanTrueValues.ContainsKey(value))
{
result = true;
return true;
}
result = false;
return true;
}
if(t == typeof(Guid))
{
if(Guid.TryParse(value, out Guid tg))
{
result = tg;
return true;
}
result = null;
return false;
}
if(t == typeof(DateTime))
{
DateTime dateResult;
bool parsed = DateTime.TryParse(value, TypeParserSettings.DefaultCulture, DateTimeStyles.None, out dateResult);
result = dateResult;
return parsed;
}
result = null;
return false;
}
}
}

View File

@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
namespace Config.Net.TypeParsers
{
class DecimalParser : ITypeParser
{
public IEnumerable<Type> SupportedTypes => new[] { typeof(decimal) };
public bool TryParse(string? value, Type t, out object? result)
{
decimal dr;
bool parsed = decimal.TryParse(value, NumberStyles.Float, TypeParserSettings.DefaultCulture, out dr);
result = dr;
return parsed;
}
public string? ToRawString(object? value)
{
return ((decimal?)value)?.ToString(TypeParserSettings.DefaultNumericFormat, TypeParserSettings.DefaultCulture);
}
}
}

View File

@@ -0,0 +1,69 @@
using System;
using System.Reflection;
namespace Config.Net.TypeParsers
{
class DefaultParser
{
public bool TryParse(string? value, Type t, out object? result)
{
if(IsEnum(t))
{
if(value == null)
{
result = null;
return false;
}
try
{
result = Enum.Parse(t, value, true);
return true;
}
catch(ArgumentException)
{
}
catch(OverflowException)
{
}
result = null;
return false;
}
throw new NotSupportedException();
}
public bool IsSupported(Type t)
{
return IsEnum(t);
}
public string? ToRawString(object? value)
{
if(value == null) return null;
Type t = value.GetType();
if(IsEnum(t))
{
return value.ToString();
}
throw new NotSupportedException();
}
static bool IsEnum(Type t)
{
if(t == null) return false;
//try to get the underlying type if this is a nullable type
Type? nullable = Nullable.GetUnderlyingType(t);
if(nullable != null) t = nullable;
return t.GetTypeInfo().IsEnum;
}
}
}

View File

@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Globalization;
namespace Config.Net.TypeParsers
{
class DoubleParser : ITypeParser
{
public IEnumerable<Type> SupportedTypes => new[] { typeof(double) };
public bool TryParse(string? value, Type t, out object? result)
{
double dr;
bool parsed = double.TryParse(value, NumberStyles.Float, TypeParserSettings.DefaultCulture, out dr);
result = dr;
return parsed;
}
public string? ToRawString(object? value)
{
return ((double?)value)?.ToString(TypeParserSettings.DefaultNumericFormat, TypeParserSettings.DefaultCulture);
}
}
}

View File

@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
namespace Config.Net.TypeParsers
{
class FloatParser : ITypeParser
{
public IEnumerable<Type> SupportedTypes => new[] { typeof(float) };
public bool TryParse(string? value, Type t, out object? result)
{
float dr;
bool parsed = float.TryParse(value, NumberStyles.Float, TypeParserSettings.DefaultCulture, out dr);
result = dr;
return parsed;
}
public string? ToRawString(object? value)
{
return ((float?)value)?.ToString(TypeParserSettings.DefaultNumericFormat, TypeParserSettings.DefaultCulture);
}
}
}

View File

@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Globalization;
namespace Config.Net.TypeParsers
{
class IntParser : ITypeParser
{
public IEnumerable<Type> SupportedTypes => new[] { typeof(int) };
public bool TryParse(string? value, Type t, out object? result)
{
int ir;
bool parsed = int.TryParse(value, NumberStyles.Integer, TypeParserSettings.DefaultCulture, out ir);
result = ir;
return parsed;
}
public string? ToRawString(object? value)
{
return ((int?)value)?.ToString(TypeParserSettings.DefaultNumericFormat, TypeParserSettings.DefaultCulture);
}
}
}

View File

@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Globalization;
namespace Config.Net.TypeParsers
{
class LongParser : ITypeParser
{
public IEnumerable<Type> SupportedTypes => new[] { typeof(long) };
public bool TryParse(string? value, Type t, out object? result)
{
long lr;
bool parsed = long.TryParse(value, NumberStyles.Integer, TypeParserSettings.DefaultCulture, out lr);
result = lr;
return parsed;
}
public string? ToRawString(object? value)
{
return ((long?)value)?.ToString(TypeParserSettings.DefaultNumericFormat, TypeParserSettings.DefaultCulture);
}
}
}

View File

@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Net;
namespace Config.Net.TypeParsers
{
class NetworkCredentialParser : ITypeParser
{
public IEnumerable<Type> SupportedTypes => new[] { typeof(NetworkCredential) };
public string? ToRawString(object? value)
{
NetworkCredential? nc = value as NetworkCredential;
return Utils.ToFriendlyString(nc);
}
public bool TryParse(string? value, Type t, out object? result)
{
NetworkCredential? nc = value.ToNetworkCredential();
result = nc;
return true;
}
}
}

View File

@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
namespace Config.Net.TypeParsers
{
class SByteParser : ITypeParser
{
public IEnumerable<Type> SupportedTypes => new[] { typeof(sbyte) };
public bool TryParse(string? value, Type t, out object? result)
{
sbyte ir;
bool parsed = sbyte.TryParse(value, NumberStyles.Integer, TypeParserSettings.DefaultCulture, out ir);
result = ir;
return parsed;
}
public string? ToRawString(object? value)
{
return ((sbyte?)value)?.ToString(TypeParserSettings.DefaultNumericFormat, TypeParserSettings.DefaultCulture);
}
}
}

View File

@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
namespace Config.Net.TypeParsers
{
class ShortParser : ITypeParser
{
public IEnumerable<Type> SupportedTypes => new[] { typeof(short) };
public bool TryParse(string? value, Type t, out object? result)
{
short ir;
bool parsed = short.TryParse(value, NumberStyles.Integer, TypeParserSettings.DefaultCulture, out ir);
result = ir;
return parsed;
}
public string? ToRawString(object? value)
{
return ((short?)value)?.ToString(TypeParserSettings.DefaultNumericFormat, TypeParserSettings.DefaultCulture);
}
}
}

View File

@@ -0,0 +1,131 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Config.Net.TypeParsers
{
class StringArrayParser : ITypeParser
{
public IEnumerable<Type> SupportedTypes => new[] { typeof(string[]) };
public bool TryParse(string? value, Type t, out object? result)
{
if (value == null)
{
result = null;
return false;
}
result = ParseAsArray(value);
return true;
}
public static bool TryParse(string? value, out string[]? result)
{
if(value == null)
{
result = null;
return false;
}
result = ParseAsArray(value);
return true;
}
public string? ToRawString(object? value)
{
string[]? arv = (string[]?)value;
if (arv == null || arv.Length == 0) return null;
return string.Join(" ", arv.Select(Escape));
}
private static string Escape(string s)
{
string s1 = s.Replace("\"", "\"\"");
return (s == s1 && !s.Contains(" "))
? s
: $"\"{s1}\"";
}
private static string[] ParseAsArray(string s)
{
var a = new List<string>();
string v = string.Empty;
int state = 0;
for(int i = 0; i < s.Length;)
{
char ch = s[i];
switch(state)
{
case 0: //default
if (ch == '\"')
{
state = 2;
}
else if(ch == ' ')
{
//skip spaces in default mode
}
else
{
v += ch;
state = 1;
}
i++;
break;
case 1: //reading unquoted value
if (ch == ' ')
{
a.Add(v);
v = string.Empty;
state = 0;
}
else
{
v += ch;
}
i++;
break;
case 2: //reading quoted value
if(ch == '\"')
{
state = 3;
}
else
{
v += ch;
}
i++;
break;
case 3: //after quote in quoted mode
if (ch == '\"')
{
v += ch;
state = 2;
}
else
{
a.Add(v);
v = string.Empty;
state = 0;
}
i++;
break;
}
}
if(!string.IsNullOrEmpty(v))
{
a.Add(v);
}
return a.ToArray();
}
}
}

View File

@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
namespace Config.Net.TypeParsers
{
class StringParser : ITypeParser
{
public IEnumerable<Type> SupportedTypes => new[] { typeof(string) };
public bool TryParse(string? value, Type t, out object? result)
{
result = value;
return value != null;
}
public string? ToRawString(object? value)
{
return value as string;
}
}
}

View File

@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
namespace Config.Net.TypeParsers
{
class TimeSpanParser : ITypeParser
{
public IEnumerable<Type> SupportedTypes => new[] { typeof(TimeSpan) };
public bool TryParse(string? value, Type t, out object? result)
{
TimeSpan ts;
bool parsed = TimeSpan.TryParse(value, TypeParserSettings.DefaultCulture, out ts);
result = ts;
return parsed;
}
public string? ToRawString(object? value)
{
return ((TimeSpan?)value)?.ToString(null, TypeParserSettings.DefaultCulture);
}
}
}

View File

@@ -0,0 +1,11 @@
using System.Globalization;
namespace Config.Net.TypeParsers
{
internal static class TypeParserSettings
{
public const string DefaultNumericFormat = "G";
public static readonly CultureInfo DefaultCulture = CultureInfo.InvariantCulture;
}
}

View File

@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
namespace Config.Net.TypeParsers
{
class UIntParser : ITypeParser
{
public IEnumerable<Type> SupportedTypes => new[] { typeof(uint) };
public bool TryParse(string? value, Type t, out object? result)
{
uint ir;
bool parsed = uint.TryParse(value, NumberStyles.Integer, TypeParserSettings.DefaultCulture, out ir);
result = ir;
return parsed;
}
public string? ToRawString(object? value)
{
return ((uint?)value)?.ToString(TypeParserSettings.DefaultNumericFormat, TypeParserSettings.DefaultCulture);
}
}
}

View File

@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
namespace Config.Net.TypeParsers
{
class ULongParser : ITypeParser
{
public IEnumerable<Type> SupportedTypes => new[] { typeof(ulong) };
public bool TryParse(string? value, Type t, out object? result)
{
ulong ir;
bool parsed = ulong.TryParse(value, NumberStyles.Integer, TypeParserSettings.DefaultCulture, out ir);
result = ir;
return parsed;
}
public string? ToRawString(object? value)
{
return ((ulong?)value)?.ToString(TypeParserSettings.DefaultNumericFormat, TypeParserSettings.DefaultCulture);
}
}
}

View File

@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
namespace Config.Net.TypeParsers
{
class UShortParser : ITypeParser
{
public IEnumerable<Type> SupportedTypes => new[] { typeof(ushort) };
public bool TryParse(string? value, Type t, out object? result)
{
ushort ir;
bool parsed = ushort.TryParse(value, NumberStyles.Integer, TypeParserSettings.DefaultCulture, out ir);
result = ir;
return parsed;
}
public string? ToRawString(object? value)
{
return ((ushort?)value)?.ToString(TypeParserSettings.DefaultNumericFormat, TypeParserSettings.DefaultCulture);
}
}
}

87
Config.Net/Utils.cs Normal file
View File

@@ -0,0 +1,87 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
namespace Config.Net
{
static class Utils
{
public static NetworkCredential? ToNetworkCredential(this string? s)
{
if (s == null) return null;
Tuple<string, string?>? credsAndDomain = SplitByDelimiter(s, "@");
string? creds = credsAndDomain?.Item1;
string? domain = credsAndDomain?.Item2;
Tuple<string, string?>? usernameAndPassword = SplitByDelimiter(creds, ":");
string? username = usernameAndPassword?.Item1;
string? password = usernameAndPassword?.Item2;
return new NetworkCredential(username, password, domain);
}
public static string? ToFriendlyString(NetworkCredential? credential)
{
if (credential == null) return null;
string usernameAndPassword;
if (string.IsNullOrEmpty(credential.UserName) && string.IsNullOrEmpty(credential.Password))
{
usernameAndPassword = string.Empty;
}
else if (string.IsNullOrEmpty(credential.UserName))
{
usernameAndPassword = $":{credential.Password}";
}
else if (string.IsNullOrEmpty(credential.Password))
{
usernameAndPassword = credential.UserName;
}
else
{
usernameAndPassword = $"{credential.UserName}:{credential.Password}";
}
return string.IsNullOrEmpty(credential.Domain)
? usernameAndPassword
: $"{usernameAndPassword}@{credential.Domain}";
}
public static Tuple<string, string?>? SplitByDelimiter(string? s, params string[] delimiter)
{
if (s == null) return null;
string key;
string? value;
if (delimiter == null || delimiter.Length == 0)
{
key = s.Trim();
value = null;
}
else
{
List<int> indexes = delimiter.Where(d => d != null).Select(d => s.IndexOf(d)).Where(d => d != -1).ToList();
if (indexes.Count == 0)
{
key = s.Trim();
value = null;
}
else
{
int idx = indexes.OrderBy(i => i).First();
key = s.Substring(0, idx);
value = s.Substring(idx + 1);
}
}
return new Tuple<string, string?>(key, value);
}
}
}

View File

@@ -13,6 +13,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NHotkey.Wpf", "NHotkey\NHot
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RadialMenu", "RadialMenu\RadialMenu.csproj", "{9DF116EE-45B1-4297-BE75-0F6B78B33689}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RoboSharp", "RoboSharp\RoboSharp.csproj", "{4280952B-6FEA-495F-B72B-14B2B9BD22E9}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Config.Net", "Config.Net\Config.Net.csproj", "{D5C7AFF9-2226-4CC4-87F6-6303DB60FEA0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -39,6 +43,14 @@ Global
{9DF116EE-45B1-4297-BE75-0F6B78B33689}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9DF116EE-45B1-4297-BE75-0F6B78B33689}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9DF116EE-45B1-4297-BE75-0F6B78B33689}.Release|Any CPU.Build.0 = Release|Any CPU
{4280952B-6FEA-495F-B72B-14B2B9BD22E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4280952B-6FEA-495F-B72B-14B2B9BD22E9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4280952B-6FEA-495F-B72B-14B2B9BD22E9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4280952B-6FEA-495F-B72B-14B2B9BD22E9}.Release|Any CPU.Build.0 = Release|Any CPU
{D5C7AFF9-2226-4CC4-87F6-6303DB60FEA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D5C7AFF9-2226-4CC4-87F6-6303DB60FEA0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D5C7AFF9-2226-4CC4-87F6-6303DB60FEA0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D5C7AFF9-2226-4CC4-87F6-6303DB60FEA0}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@@ -1,12 +1,12 @@
using Hardcodet.Wpf.TaskbarNotification;
using NHotkey;
using NHotkey.Wpf;
using System.Collections;
using System.Windows;
using System.Windows.Input;
using FSI.Lib.Helpers;
using FSI.Lib.CompareNetObjects;
using FSI.Lib.Guis.SetSizePosExWindow;
using Config.Net.Stores;
using System.IO;
using Config.Net;
namespace FSI.BT.Tools
{
@@ -17,13 +17,21 @@ namespace FSI.BT.Tools
{
private static readonly KeyGesture RadialMenu = new KeyGesture(Key.OemBackslash, ModifierKeys.Control);
private static readonly KeyGesture TimeStamp = new KeyGesture(Key.C, ModifierKeys.Control | ModifierKeys.Alt);
public void Application_Startup(object sender, StartupEventArgs e)
{
Global.Log.Info("Anwendung wurde gestartet!");
Global.Settings = new AppSettings(GetType().Namespace.ToString() + ".xml");
Global.Settings.Load();
JsonConfigStore _store = new JsonConfigStore(System.IO.Path.Combine(Directory.GetCurrentDirectory(), "config.json"), true);
Global.AppSettings = new ConfigurationBuilder<Settings.AppSettings.IAppSettings>()
.UseConfigStore(_store)
.Build();
Global.TaskbarIcon = (TaskbarIcon)FindResource("FSINotifyIcon");
Global.AdminRights = Admin.CheckAdminRight();

View File

@@ -8,8 +8,7 @@ namespace FSI.BT.Tools
public AppSettings(string fileName) : base(fileName)
{
TimeStampFormat = "_yyyyMMdd_HHmmss";
EplArguments = "/Variant:\"Electric P8\"";
SuperAdmin = "maier_s";
}
@@ -19,45 +18,45 @@ namespace FSI.BT.Tools
public string[] Admins { get; set; }
[EncryptedSetting]
public string SuperAdmin { get; set; }
public string TimeStampFormat { get; set; }
public string[] SieSimaticManagerExe { get; set; }
public string[] SieTiaV13Exe { get; set; }
public string[] SieTiaV14Exe { get; set; }
public string[] SieTiaV15Exe { get; set; }
public string[] SieTiaV16Exe { get; set; }
public string[] SieTiaV17Exe { get; set; }
public string[] SieTiaVStarterExe { get; set; }
//public string TimeStampFormat { get; set; }
//public string[] SieSimaticManagerExe { get; set; }
//public string[] SieTiaV13Exe { get; set; }
//public string[] SieTiaV14Exe { get; set; }
//public string[] SieTiaV15Exe { get; set; }
//public string[] SieTiaV16Exe { get; set; }
//public string[] SieTiaV17Exe { get; set; }
//public string[] SieTiaVStarterExe { get; set; }
public string[] EplExe { get; set; }
public string EplArguments { get; set; }
public string[] NppExe { get; set; }
public string[] TotalCmdExe { get; set; }
public string[] TeXstudioExe { get; set; }
public string[] TeXstudioPath { get; set; }
public string[] VsExe { get; set; }
public string[] VsCodeExe { get; set; }
public string[] RdpExe { get; set; }
public string[] OutlookExe { get; set; }
public string[] TeamsExe { get; set; }
public string TeamsArg { get; set; }
public string[] ExcelExe { get; set; }
public string[] WordExe { get; set; }
public string[] PaintNetExe { get; set; }
public string[] GimpExe { get; set; }
public string[] VncExe { get; set; }
public string[] VncAdrBookExe { get; set; }
public string[] IbaAnalyzerExe { get; set; }
public string ZentralWebUrl { get; set; }
public string SchichtbuchUrl { get; set; }
public string SPSUrl { get; set; }
public string Pl1PlsUrl { get; set; }
public string Pl2PlsUrl { get; set; }
public string Pl2Als { get; set; }
public string Pl3PlsUrl { get; set; }
public string GiteaUrl { get; set; }
public string WikiUrl { get; set; }
public string ErpUrl { get; set; }
public string EplPdfPath { get; set; }
public string EplPrjPath { get; set; }
//public string EplArguments { get; set; }
//public string[] NppExe { get; set; }
//public string[] TotalCmdExe { get; set; }
//public string[] TeXstudioExe { get; set; }
//public string[] TeXstudioPath { get; set; }
//public string[] VsExe { get; set; }
//public string[] VsCodeExe { get; set; }
//public string[] RdpExe { get; set; }
//public string[] OutlookExe { get; set; }
//public string[] TeamsExe { get; set; }
//public string TeamsArg { get; set; }
//public string[] ExcelExe { get; set; }
//public string[] WordExe { get; set; }
//public string[] PaintNetExe { get; set; }
//public string[] GimpExe { get; set; }
//public string[] VncExe { get; set; }
//public string[] VncAdrBookExe { get; set; }
//public string[] IbaAnalyzerExe { get; set; }
//public string ZentralWebUrl { get; set; }
//public string SchichtbuchUrl { get; set; }
//public string SPSUrl { get; set; }
//public string Pl1PlsUrl { get; set; }
//public string Pl2PlsUrl { get; set; }
//public string Pl2Als { get; set; }
//public string Pl3PlsUrl { get; set; }
//public string GiteaUrl { get; set; }
//public string WikiUrl { get; set; }
//public string ErpUrl { get; set; }
//public string EplPdfPath { get; set; }
//public string EplPrjPath { get; set; }
public bool SieTiaWinCCMsgMgtAutostart { get; set; }
public int SieTiaWinCCMsgMgtUpdateIntervall { get; set; }
public string SieTiaWinCCMsgMgtWindowsName { get; set; }
@@ -66,13 +65,14 @@ namespace FSI.BT.Tools
public bool IbaAutoSync { get; set; }
public string IbaRecordSourcePath { get; set; }
public string IbaRecordDestinationath { get; set; }
public string[] WindowMgtName { get; set; }
public string[] WindowMgtClassName { get; set; }
public int WindowMgtUpdateInterval { get; set; }
public bool WindowMgtAutostart { get; set; }
public int[] WindowMgtX { get; set; }
public int[] WindowMgtY { get; set; }
public int[] WindowMgtHeight { get; set; }
public int[] WindowMgtWight { get; set; }
public string[] WindowMgtBezeichnung { get; set; }
public string[] WindowMgtName { get; set; }
public string[] WindowMgtClassName { get; set; }
public string[] WindowMgtX { get; set; }
public string[] WindowMgtY { get; set; }
public string[] WindowMgtHeight { get; set; }
public string[] WindowMgtWight { get; set; }
}
}

View File

@@ -9,6 +9,7 @@ namespace FSI.BT.Tools.Commands
{
public override void Execute(object parameter)
{
Global.Log.Info("Anwendung wurde beendet!");
Application.Current.Shutdown();
}

View File

@@ -18,6 +18,15 @@ namespace FSI.BT.Tools.Commands
Global.UserRights =
Global.AdminRights = frmMain.PwOk;
if (frmMain.PwOk)
{
Global.Log.Info("Admin-Passowrt wurde korrekt eingegben.");
}
else
{
Global.Log.Info("Anmeldung wurde vom Benutzer abgebrochen.");
}
}
public override bool CanExecute(object parameter)

View File

@@ -1,7 +1,10 @@
using FSI.Lib;
using FSI.BT.Tools.Settings;
using FSI.Lib;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Windows;
namespace FSI.BT.Tools.Commands
@@ -13,53 +16,52 @@ namespace FSI.BT.Tools.Commands
{
public override void Execute(object parameter)
{
string[] files = new string[] { };
string[] pathes = new string[] { };
string arguments = string.Empty;
IEnumerable<Settings.Exe.IExe> files = new List<Settings.Exe.IExe>();
(string ExePath, string Path, string Arguments) selectedFile = (string.Empty, string.Empty, string.Empty);
switch ((string)parameter)
{
case "SimaticManager":
files = Global.Settings.SieSimaticManagerExe;
files = Global.AppSettings.Apps.SieSimaticManager;
break;
case "TIAv13":
files = Global.Settings.SieTiaV13Exe;
files = Global.AppSettings.Apps.SieTiaV13;
break;
case "TIAv14":
files = Global.Settings.SieTiaV14Exe;
files = Global.AppSettings.Apps.SieTiaV14;
break;
case "TIAv15":
files = Global.Settings.SieTiaV15Exe;
files = Global.AppSettings.Apps.SieTiaV15;
break;
case "TIAv16":
files = Global.Settings.SieTiaV16Exe;
files = Global.AppSettings.Apps.SieTiaV16;
break;
case "TIAv17":
files = Global.Settings.SieTiaV17Exe;
files = Global.AppSettings.Apps.SieTiaV17;
break;
case "Starter":
files = Global.Settings.SieTiaVStarterExe;
files = Global.AppSettings.Apps.SieTiaVStarter;
break;
case "Epl":
files = Global.Settings.EplExe;
arguments = Global.Settings.EplArguments;
files = Global.AppSettings.Apps.Epl;
break;
case "EplPrj":
selectedFile = GetApp(Global.AppSettings.Apps.Epl);
Lib.Guis.Prj.Mgt.FrmMain frmMainEplPrj = new Lib.Guis.Prj.Mgt.FrmMain()
{
ShowPdf = false,
CloseAtLostFocus = true,
WindowStartupLocation = WindowStartupLocation.CenterScreen,
Path = Global.Settings.EplPrjPath,
EplExes = Global.Settings.EplExe,
Path = FSI.BT.Tools.Settings.AppSettings.GetFolderByName(Global.AppSettings.Folders, "EplPrj").path,
EplExe = selectedFile.ExePath,
};
frmMainEplPrj.Show();
return;
@@ -70,7 +72,7 @@ namespace FSI.BT.Tools.Commands
ShowPdf = true,
CloseAtLostFocus = true,
WindowStartupLocation = WindowStartupLocation.CenterScreen,
Path = Global.Settings.EplPdfPath,
Path = FSI.BT.Tools.Settings.AppSettings.GetFolderByName(Global.AppSettings.Folders, "EplPdf").path
};
frmMainEplPdf.Show();
return;
@@ -84,29 +86,28 @@ namespace FSI.BT.Tools.Commands
return;
case "Npp":
files = Global.Settings.NppExe;
files = Global.AppSettings.Apps.Npp;
break;
case "TotalCmd":
files = Global.Settings.TotalCmdExe;
files = Global.AppSettings.Apps.TotalCmd;
break;
case "TeXstudio":
files = Global.Settings.TeXstudioExe;
pathes = Global.Settings.TeXstudioPath;
files = Global.AppSettings.Apps.TeXstudio;
break;
case "VS":
files = Global.Settings.VsExe;
files = Global.AppSettings.Apps.Vs;
break;
case "VS.Code":
files = Global.Settings.VsCodeExe;
files = Global.AppSettings.Apps.VsCode;
break;
case "Rdp":
files = Global.Settings.RdpExe;
files = Global.AppSettings.Apps.Rdp;
break;
case "DeEncrypt":
@@ -139,84 +140,80 @@ namespace FSI.BT.Tools.Commands
}
return;
case "Folder":
Lib.Guis.Folder.Mgt.FrmMain frmFolderMgtMain = new Lib.Guis.Folder.Mgt.FrmMain()
{
CloseAtLostFocus = true,
Data = Global.AppSettings.Folders
};
frmFolderMgtMain.Show();
return;
//case "TxtToClip":
// Lib.Guis.TxtToClip.Mgt.FrmMain frmTxtToClipMain = new Lib.Guis.TxtToClip.Mgt.FrmMain()
// {
// CloseAtLostFocus = false,
// Data = Global.AppSettings.TxtToClip
// };
// frmTxtToClipMain.Show();
// return;
case "Outlook":
files = Global.Settings.OutlookExe;
files = Global.AppSettings.Apps.Outlook;
break;
case "Teams":
files = Global.Settings.TeamsExe;
arguments = Global.Settings.TeamsArg;
files = Global.AppSettings.Apps.Teams;
break;
case "Excel":
files = Global.Settings.ExcelExe;
files = Global.AppSettings.Apps.Excel;
break;
case "Word":
files = Global.Settings.WordExe;
files = Global.AppSettings.Apps.Word;
break;
case "PaintNet":
files = Global.Settings.PaintNetExe;
files = Global.AppSettings.Apps.PaintNet;
break;
case "Gimp":
files = Global.Settings.GimpExe;
files = Global.AppSettings.Apps.Gimp;
break;
case "Vnc":
files = Global.Settings.VncExe;
files = Global.AppSettings.Apps.Vnc;
break;
case "VncAdrBook":
files = Global.Settings.VncAdrBookExe;
files = Global.AppSettings.Apps.VncAdrBook;
break;
case "IbaAnalyzer":
files = Global.Settings.VncAdrBookExe;
files = Global.AppSettings.Apps.IbaAnalyzer;
break;
}
string fileName = string.Empty;
string path = string.Empty;
selectedFile = GetApp(files);
for (int i = 0; i <= files.Length - 1; i++)
if (ProgramIsRunning(selectedFile.ExePath))
{
var test = Environment.ExpandEnvironmentVariables(files[i].Trim());
if (File.Exists(Environment.ExpandEnvironmentVariables(files[i].Trim())))
{
fileName = Environment.ExpandEnvironmentVariables(files[i].Trim());
}
else
{
continue;
}
if (pathes.Length == 0)
{
path = Path.GetDirectoryName(fileName);
}
else
{
path = Environment.ExpandEnvironmentVariables(pathes[i].Trim());
}
}
if (ProgramIsRunning(fileName))
{
ProgramToFront(fileName);
ProgramToFront(selectedFile.ExePath);
Global.Log.Info("Anwendung \"{0}\" wurde in den Vordergrund gebracht", selectedFile.ExePath);
}
else
{
Process process = new Process();
process.StartInfo.FileName = fileName;
process.StartInfo.WorkingDirectory = path;
process.StartInfo.Arguments = arguments;
process.StartInfo.FileName = selectedFile.ExePath;
process.StartInfo.WorkingDirectory = selectedFile.Path;
process.StartInfo.Arguments = selectedFile.Arguments;
try
{
process.Start();
Global.Log.Info("Anwendung \"{0}\" wurde gestartet", selectedFile.ExePath);
}
catch (System.ComponentModel.Win32Exception ex) when (ex.NativeErrorCode == 740)
{
@@ -225,47 +222,51 @@ namespace FSI.BT.Tools.Commands
process.StartInfo.UseShellExecute = true;
process.StartInfo.Verb = "runas";
process.Start();
Global.Log.Info("Anwendung \"{0}\" wurde als Admin gestartet", selectedFile.ExePath);
}
catch (Exception ex2)
{
Global.Log.Info("Anwendung konnte durch folgenden Fehler \"{0}\" nicht gestartet werden.", ex2.Message);
}
catch { }
}
}
}
public override bool CanExecute(object parameter)
{
string[] files = new string[] { };
IEnumerable<Settings.Exe.IExe> files = new List<Settings.Exe.IExe>();
switch ((string)parameter)
{
case "SimaticManager":
files = Global.Settings.SieSimaticManagerExe;
files = Global.AppSettings.Apps.SieSimaticManager;
break;
case "TIAv13":
files = Global.Settings.SieTiaV13Exe;
files = Global.AppSettings.Apps.SieTiaV13;
break;
case "TIAv14":
files = Global.Settings.SieTiaV14Exe;
files = Global.AppSettings.Apps.SieTiaV14;
break;
case "TIAv15":
files = Global.Settings.SieTiaV13Exe;
files = Global.AppSettings.Apps.SieTiaV15;
break;
case "TIAv16":
files = Global.Settings.SieTiaV16Exe;
files = Global.AppSettings.Apps.SieTiaV16;
break;
case "TIAv17":
files = Global.Settings.SieTiaV17Exe;
files = Global.AppSettings.Apps.SieTiaV17;
break;
case "Starter":
files = Global.Settings.SieTiaVStarterExe;
files = Global.AppSettings.Apps.SieTiaVStarter;
break;
case "Epl":
files = Global.Settings.EplExe;
files = Global.AppSettings.Apps.Epl;
break;
case "EplPrj":
@@ -278,28 +279,27 @@ namespace FSI.BT.Tools.Commands
return Global.AdminRights;
case "Npp":
files = Global.Settings.NppExe;
files = Global.AppSettings.Apps.Npp;
break;
case "TotalCmd":
files = Global.Settings.TotalCmdExe;
files = Global.AppSettings.Apps.TotalCmd;
break;
case "TeXstudio":
files = Global.Settings.TeXstudioExe;
files = Global.AppSettings.Apps.TeXstudio;
break;
case "VS":
files = Global.Settings.VsExe;
files = Global.AppSettings.Apps.Vs;
break;
case "VS.Code":
files = Global.Settings.VsCodeExe;
files = Global.AppSettings.Apps.VsCode;
break;
case "Rdp":
files = Global.Settings.RdpExe;
files = Global.AppSettings.Apps.Rdp;
break;
case "DeEncrypt":
@@ -311,49 +311,55 @@ namespace FSI.BT.Tools.Commands
case "Admin":
return Global.SuperAdminRights;
case "Folder":
return Global.AppSettings.Folders != null;
//case "TxtToClip":
// return Global.AppSettings.TxtToClip != null;
case "Outlook":
files = Global.Settings.OutlookExe;
files = Global.AppSettings.Apps.Outlook;
break;
case "Teams":
files = Global.Settings.TeamsExe;
files = Global.AppSettings.Apps.Teams;
break;
case "Excel":
files = Global.Settings.ExcelExe;
files = Global.AppSettings.Apps.Excel;
break;
case "Word":
files = Global.Settings.WordExe;
files = Global.AppSettings.Apps.Word;
break;
case "PaintNet":
files = Global.Settings.PaintNetExe;
files = Global.AppSettings.Apps.PaintNet;
break;
case "Gimp":
files = Global.Settings.GimpExe;
files = Global.AppSettings.Apps.Gimp;
break;
case "Vnc":
files = Global.Settings.VncExe;
files = Global.AppSettings.Apps.Vnc;
break;
case "VncAdrBook":
files = Global.Settings.VncAdrBookExe;
files = Global.AppSettings.Apps.VncAdrBook;
break;
case "IbaAnalyzer":
files = Global.Settings.VncAdrBookExe;
files = Global.AppSettings.Apps.IbaAnalyzer;
break;
default: return false;
}
foreach (string file in files)
foreach (var file in files)
{
if (File.Exists(Environment.ExpandEnvironmentVariables(file.Trim())))
if (File.Exists(Environment.ExpandEnvironmentVariables(file.ExePath.Trim())))
{
return true;
}
@@ -382,6 +388,36 @@ namespace FSI.BT.Tools.Commands
return isRunning;
}
private (string ExePath, string Path, string Arguments) GetApp(IEnumerable<Settings.Exe.IExe> files)
{
(string ExePath, string Path, string Arguments) selectedFile = (string.Empty, string.Empty, string.Empty);
for (int i = 0; i < files.ToList().Count; i++)
{
if (File.Exists(Environment.ExpandEnvironmentVariables(files.ToList()[i].ExePath.Trim())))
{
selectedFile.ExePath = Environment.ExpandEnvironmentVariables(files.ToList()[i].ExePath.Trim());
selectedFile.Arguments = files.ToList()[i].Arguments;
}
else
{
continue;
}
if (selectedFile.Path == String.Empty)
{
selectedFile.Path = Path.GetDirectoryName(selectedFile.ExePath);
}
else
{
selectedFile.Path = Path.GetDirectoryName(files.ToList()[i].ExePath.Trim());
//selectedFile.Path = Environment.ExpandEnvironmentVariables(files.ToList()[i].ExePath.Trim());
}
}
return selectedFile;
}
[System.Runtime.InteropServices.DllImport("User32.dll")]
private static extern bool SetForegroundWindow(IntPtr handle);
[System.Runtime.InteropServices.DllImport("User32.dll")]

View File

@@ -16,43 +16,43 @@ namespace FSI.BT.Tools.Commands
switch ((string)parameter)
{
case "ZentralWeb":
url = Global.Settings.ZentralWebUrl;
url = Global.AppSettings.Urls.ZentralWeb;
break;
case "Schichtbuch":
url = Global.Settings.SchichtbuchUrl;
url = Global.AppSettings.Urls.Schichtbuch;
break;
case "SPS":
url = Global.Settings.SPSUrl;
url = Global.AppSettings.Urls.SPS;
break;
case "PL1.Pls":
url = Global.Settings.Pl1PlsUrl;
url = Global.AppSettings.Urls.Pl1Pls;
break;
case "PL2.Pls":
url = Global.Settings.Pl2PlsUrl;
url = Global.AppSettings.Urls.Pl2Pls;
break;
case "PL2.Als":
url = Global.Settings.Pl2Als;
url = Global.AppSettings.Urls.Pl2Als;
break;
case "PL3.Pls":
url = Global.Settings.Pl3PlsUrl;
url = Global.AppSettings.Urls.Pl3Pls;
break;
case "FSI.Gitea":
url = Global.Settings.GiteaUrl;
url = Global.AppSettings.Urls.Gitea;
break;
case "FSI.Wiki":
url = Global.Settings.WikiUrl;
url = Global.AppSettings.Urls.Wiki;
break;
case "Erp":
url = Global.Settings.ErpUrl;
url = Global.AppSettings.Urls.Erp;
break;
}
@@ -61,6 +61,7 @@ namespace FSI.BT.Tools.Commands
url = url.Replace("&", "^&");
Process.Start(new ProcessStartInfo(url) { UseShellExecute = true });
Global.Log.Info("Link \"{0}\" wurde geföffnet.", url);
}
public override bool CanExecute(object parameter)

View File

@@ -10,13 +10,16 @@ namespace FSI.BT.Tools.Commands
{
public override void Execute(object parameter)
{
System.Windows.Forms.Clipboard.SetDataObject(DateTime.Now.ToString(Global.Settings.TimeStampFormat));
var timeStampFormat = Global.AppSettings.TimeStampFormat.Value;
System.Windows.Forms.Clipboard.SetDataObject(DateTime.Now.ToString(timeStampFormat));
Global.Log.Debug("Zeitstempel \"{0}\" wurde in die Zwischenablage kopiert.", DateTime.Now.ToString(timeStampFormat));
var balloon = new ToolTip()
{
BalloonText = "Zeitstempel",
BalloonDesc = "Der aktuelle Zeitstempel wurde in die Zwischenablage kopiert."
};
Global.TaskbarIcon.ShowCustomBalloon(balloon, PopupAnimation.Slide, 2000);
Global.TaskbarIcon.ShowCustomBalloon(balloon, PopupAnimation.Slide, 2000);
}
public override bool CanExecute(object parameter)

View File

@@ -1,8 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFrameworks>net472;net6.0-windows</TargetFrameworks>
<PropertyGroup>
<TargetFramework>net6.0-windows</TargetFramework>
<OutputType>WinExe</OutputType>
<UseWPF>true</UseWPF>
<ImportWindowsDesktopTargets>true</ImportWindowsDesktopTargets>
@@ -13,9 +12,9 @@
<ItemGroup Condition=" '$(TargetFramework)' == 'net472' ">
<Reference Include="System.Windows.Forms" />
</ItemGroup>
<ItemGroup>
<None Remove="Icons\Folders.png" />
<None Remove="Icons\Iba.jpg" />
</ItemGroup>
@@ -59,10 +58,16 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="NLog.Extensions.Logging" Version="5.2.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Config.Net\Config.Net.csproj" />
<ProjectReference Include="..\FSI.Lib\FSI.Lib\FSI.Lib.csproj" />
<ProjectReference Include="..\NHotkey\NHotkey.Wpf\NHotkey.Wpf.csproj" />
<ProjectReference Include="..\NotifyIconWpf\NotifyIconWpf\NotifyIconWpf.csproj" />
<ProjectReference Include="..\RadialMenu\RadialMenu.csproj" />
<ProjectReference Include="..\RoboSharp\RoboSharp.csproj" />
</ItemGroup>
<ItemGroup>
@@ -75,6 +80,7 @@
<Resource Include="Icons\EplP8.png" />
<Resource Include="Icons\Erp.png" />
<Resource Include="Icons\Excel.png" />
<Resource Include="Icons\Folders.png" />
<Resource Include="Icons\FondiumU.ico" />
<Resource Include="Icons\FU.png" />
<Resource Include="Icons\Gimp.png" />
@@ -107,9 +113,17 @@
</ItemGroup>
<ItemGroup>
<None Update="config.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="FSI.BT.Tools.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="nlog.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
<ProjectExtensions><VisualStudio><UserProperties config_1json__JsonSchema="" /></VisualStudio></ProjectExtensions>
</Project>

View File

@@ -2,9 +2,9 @@
<Settings>
<Users>+I945AMzKKYBAAAAB21haWVyX3M=</Users>
<Admins>e+Dt7FRUDDoBAAAAB21haWVyX3M=</Admins>
<TimeStampFormat>_yyyyMMdd_HHmmss</TimeStampFormat>
<SieSimaticManagerExe>C:\Program Files (x86)\Siemens\Step7\S7BIN\S7tgtopx.exe</SieSimaticManagerExe>
<SieTiaV13Exe>C:\Program Files (x86)\Siemens\Automation\Portal V13\Bin\Siemens.Automation.Portal.exe</SieTiaV13Exe>
<SieTiaV14Exe>C:\Program Files\Siemens\Automation\Portal V14\Bin\Siemens.Automation.Portal.exe</SieTiaV14Exe>
@@ -31,7 +31,7 @@
<VncExe>C:\Program Files\RealVNC\VNC Viewer\vncviewer.exe,c:\Users\maier_s\OneDrive - Fondium Group GmbH\Documents\Apps\VNC-Viewer-6.20.113-Windows-64bit.exe</VncExe>
<VncAdrBookExe>C:\Program Files\RealVNC\VNC Viewer\vncaddrbook.exe</VncAdrBookExe>
<IbaAnalyzerExe>C:\Program Files\iba\ibaAnalyzer\ibaAnalyzer.exe</IbaAnalyzerExe>
<ZentralWebUrl>http://desiaugetwf/web/?AspxAutoDetectCookieSupport=1</ZentralWebUrl>
<SchichtbuchUrl>http://10.10.1.42/SKSchichtbuchWeb/de-DE/Plugin/ShiftBook/ShiftBook/IR</SchichtbuchUrl>
<SPSUrl>http://10.10.1.42/SKChangeTrackerWeb/de-DE/Plugin/ChangeTracker</SPSUrl>
@@ -42,17 +42,27 @@
<GiteaUrl>http://desiaugetc7-088:3000/</GiteaUrl>
<WikiUrl>http://desiaugetc7-088:3001/en/home</WikiUrl>
<ErpUrl>https://mingle-portal.eu1.inforcloudsuite.com/FONDIUM_prd</ErpUrl>
<EplPdfPath>\\10.10.1.40\Betriebstechnik\Eplan</EplPdfPath>
<EplPrjPath>\\fondium.org\DESI$\AUG_Abteilung\Betriebstechnik\EPL\P8\Data\Projekte\FSI\</EplPrjPath>
<SieTiaWinCCMsgMgtAutostart>true</SieTiaWinCCMsgMgtAutostart>
<SieTiaWinCCMsgMgtUpdateIntervall>10</SieTiaWinCCMsgMgtUpdateIntervall>
<SieTiaWinCCMsgMgtWindowsName></SieTiaWinCCMsgMgtWindowsName>
<SieTiaWinCCMsgMgtClassName>#32770</SieTiaWinCCMsgMgtClassName>
<SieTiaWinCCMsgMgtBtnName>Zur Kenntnis genommen</SieTiaWinCCMsgMgtBtnName>
<IbaAutoSync>true</IbaAutoSync>
<IbaRecordSourcePath>d:\tmp</IbaRecordSourcePath>
<IbaRecordDestinationath>c:\tmp</IbaRecordDestinationath>
<WindowMgtAutostart>false</WindowMgtAutostart>
<WindowMgtUpdateInterval>10</WindowMgtUpdateInterval>
<WindowMgtBezeichnung>Starter Trace</WindowMgtBezeichnung>
<WindowMgtName>Signalauswahl Trace</WindowMgtName>
<WindowMgtClassName>#32770</WindowMgtClassName>
<WindowMgtX>10</WindowMgtX>
<WindowMgtY>10</WindowMgtY>
<WindowMgtHeight>800</WindowMgtHeight>
<WindowMgtWight>1000</WindowMgtWight>
</Settings>

View File

@@ -363,6 +363,39 @@
</WrapPanel>
</RadialMenu:RadialMenuItem>
<RadialMenu:RadialMenuItem Command="{commands:OpenAppCommand}"
CommandParameter="Folder">
<WrapPanel Orientation="Vertical">
<Rectangle Width="40"
Height="40">
<Rectangle.Fill>
<ImageBrush ImageSource="../../Icons/Folders.png" />
</Rectangle.Fill>
</Rectangle>
<TextBlock FontSize="14"
TextAlignment="Center">
Verzeichnisse
</TextBlock>
</WrapPanel>
</RadialMenu:RadialMenuItem>
<RadialMenu:RadialMenuItem Command="{commands:OpenAppCommand}"
CommandParameter="TxtToClip">
<WrapPanel Orientation="Vertical">
<Rectangle Width="40"
Height="40">
<Rectangle.Fill>
<ImageBrush ImageSource="../../Icons/Folders.png" />
</Rectangle.Fill>
</Rectangle>
<TextBlock FontSize="14"
TextAlignment="Center">
Verzeichnisse
</TextBlock>
</WrapPanel>
</RadialMenu:RadialMenuItem>
</RadialMenu:RadialMenu>
<RadialMenu:RadialMenu IsOpen="{Binding IsOpenSie}">

View File

@@ -1,50 +1,59 @@
using FSI.Lib.Guis.IbaDirSync.ViewModel;
using Config.Net.Stores;
using FSI.Lib.Guis.IbaDirSync.ViewModel;
using FSI.Lib.Guis.SetSizePosExWindow.ViewModel;
using FSI.Lib.Guis.SieTiaWinCCMsgMgt.ViewModel;
using Hardcodet.Wpf.TaskbarNotification;
using Microsoft.Extensions.Logging;
using NLog;
namespace FSI.BT.Tools
{
internal static class Global
{
public static Logger Log = LogManager.GetCurrentClassLogger();
public static FrmRadialMenu FrmRadialMenu { get; set; }
public static TaskbarIcon TaskbarIcon { get; set; }
public static ViewModelWinCC WinCC { get; set; }
public static AppSettings Settings { get; set; }
public static Settings.AppSettings.IAppSettings AppSettings { get; set; }
public static ViewModelIba Iba { get; set; }
public static ViewModelWindow WindowMgt { get; set; }
public static bool UserRights { get; set; }
public static bool AdminRights { get; set; }
public static bool SuperAdminRights { get; set; }
public static class Window
{
public static void Load()
{
for (int i = 0; i < Global.Settings.WindowMgtName.Length; i++)
for (int i = 0; i < Global.Settings.WindowMgtBezeichnung.Length; i++)
{
WindowMgt.Windows.Add(new Lib.Guis.SetSizePosExWindow.Model.Window
{
Bezeichnung = Global.Settings.WindowMgtBezeichnung[i],
Name = Global.Settings.WindowMgtName[i],
ClassName = Global.Settings.WindowMgtClassName[i],
Height = Global.Settings.WindowMgtHeight[i],
Width = Global.Settings.WindowMgtWight[i],
X = Global.Settings.WindowMgtX[i],
Y = Global.Settings.WindowMgtY[i],
Height = int.Parse(Global.Settings.WindowMgtHeight[i]),
Width = int.Parse(Global.Settings.WindowMgtWight[i]),
X = int.Parse(Global.Settings.WindowMgtX[i]),
Y = int.Parse(Global.Settings.WindowMgtY[i]),
});
}
}
}
public static void Save()
{
for (int i = 0; i < Global.WindowMgt.Windows.Count; i++)
{
Global.Settings.WindowMgtBezeichnung[i] = Global.WindowMgt.Windows[i].Bezeichnung;
Global.Settings.WindowMgtName[i] = Global.WindowMgt.Windows[i].Name;
Global.Settings.WindowMgtClassName[i] = Global.WindowMgt.Windows[i].ClassName;
Global.Settings.WindowMgtHeight[i] = Global.WindowMgt.Windows[i].Height;
Global.Settings.WindowMgtWight[i] = Global.WindowMgt.Windows[i].Width;
Global.Settings.WindowMgtX[i] = Global.WindowMgt.Windows[i].X;
Global.Settings.WindowMgtY[i] = Global.WindowMgt.Windows[i].Y;
Global.Settings.WindowMgtHeight[i] = Global.WindowMgt.Windows[i].Height.ToString();
Global.Settings.WindowMgtWight[i] = Global.WindowMgt.Windows[i].Width.ToString();
Global.Settings.WindowMgtX[i] = Global.WindowMgt.Windows[i].X.ToString();
Global.Settings.WindowMgtY[i] = Global.WindowMgt.Windows[i].Y.ToString();
}
}
}

View File

@@ -174,8 +174,8 @@
</Grid.ColumnDefinitions>
<TextBlock Text="Fenster:"
Margin="5 5 5 5" />
<ComboBox ItemsSource="{Binding Plcs}"
SelectedItem="{Binding SelectedPlc, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
<ComboBox ItemsSource="{Binding Windows}"
SelectedItem="{Binding SelectedWindow, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
DisplayMemberPath="Name"
SelectedIndex="0"
Grid.Column="1"
@@ -186,16 +186,28 @@
Background="Transparent" />
<Button Content="neu"
Name="ABC"
Command="{Binding CmdCreatNewConnection}"
Command="{Binding CmdNew}"
Grid.Column="3"
MinWidth="50"
Margin="5 5 5 5"/>
<Button Content="löschen"
Command="{Binding CmdDelConnection}"
Command="{Binding CmdDelDel}"
Grid.Column="4"
Margin="5 5 5 5"
MinWidth="50" />
</Grid>
<Grid Margin="0 5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"
SharedSizeGroup="a" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="Bezeichnung:"
Margin="5 5 5 5" />
<TextBox Grid.Column="1"
Text="{Binding SelectedWindow.Bezeichnung, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Margin="5 5 5 5" />
</Grid>
<Grid Margin="0 5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"
@@ -205,7 +217,7 @@
<TextBlock Text="Fenster Name:"
Margin="5 5 5 5" />
<TextBox Grid.Column="1"
Text="{Binding Iba.Destination, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Text="{Binding SelectedWindow.Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Margin="5 5 5 5" />
</Grid>
<Grid Margin="0 5">
@@ -217,7 +229,7 @@
<TextBlock Text="Klassen Name:"
Margin="5 5 5 5" />
<TextBox Grid.Column="1"
Text="{Binding Iba.Destination, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Text="{Binding SelectedWindow.ClassName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Margin="5 5 5 5" />
</Grid>
<Grid Margin="0 5">
@@ -229,7 +241,7 @@
<TextBlock Text="Fenster Höhe:"
Margin="5 5 5 5" />
<TextBox Grid.Column="1"
Text="{Binding Iba.Destination, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Text="{Binding SelectedWindow.Height, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Margin="5 5 5 5" />
</Grid>
<Grid Margin="0 5">
@@ -241,7 +253,7 @@
<TextBlock Text="Fenster Breite:"
Margin="5 5 5 5" />
<TextBox Grid.Column="1"
Text="{Binding Iba.Destination, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Text="{Binding SelectedWindow.Width, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Margin="5 5 5 5" />
</Grid>
<Grid Margin="0 5">
@@ -253,7 +265,7 @@
<TextBlock Text="X-Position:"
Margin="5 5 5 5" />
<TextBox Grid.Column="1"
Text="{Binding Iba.Destination, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Text="{Binding SelectedWindow.X, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Margin="5 5 5 5" />
</Grid>
<Grid Margin="0 5">
@@ -265,7 +277,7 @@
<TextBlock Text="Y-Position:"
Margin="5 5 5 5" />
<TextBox Grid.Column="1"
Text="{Binding Iba.Destination, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Text="{Binding SelectedWindow.Y, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Margin="5 5 5 5" />
</Grid>
<Grid Margin="0 5">

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -0,0 +1,43 @@
using Config.Net;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FSI.BT.Tools.Settings
{
public static class AppSettings
{
public interface IAppSettings
{
StringValue.IStringValue TimeStampFormat { get; set; }
Apps.IApps Apps { get; }
Urls.IUrls Urls { get; }
IEnumerable<Folder.IFolder> Folders { get; }
// IEnumerable<TxtToClip.ITxtToClip> TxtToClip { get; }
[Option(Alias = "Folders")]
string GetFolderByName(string fodlerName, string keyName);
}
public static (string path, string description) GetFolderByName(IEnumerable<Folder.IFolder> folders, string name)
{
foreach (var folder in folders)
{
if (folder.Name.Equals(name))
{
return (folder.Path, folder.Description);
}
}
return (null, null);
}
}
}

View File

@@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FSI.BT.Tools.Settings
{
public class Apps
{
public interface IApps
{
IEnumerable<Exe.IExe> SieSimaticManager { get; }
IEnumerable<Exe.IExe> SieTiaV13 { get; }
IEnumerable<Exe.IExe> SieTiaV14 { get; }
IEnumerable<Exe.IExe> SieTiaV15 { get; }
IEnumerable<Exe.IExe> SieTiaV16 { get; }
IEnumerable<Exe.IExe> SieTiaV17 { get; }
IEnumerable<Exe.IExe> SieTiaVStarter { get; }
IEnumerable<Exe.IExe> Epl { get; }
IEnumerable<Exe.IExe> Npp { get; }
IEnumerable<Exe.IExe> TotalCmd { get; }
IEnumerable<Exe.IExe> TeXstudio { get; }
IEnumerable<Exe.IExe> Vs { get; }
IEnumerable<Exe.IExe> VsCode { get; }
IEnumerable<Exe.IExe> Rdp { get; }
IEnumerable<Exe.IExe> Outlook { get; }
IEnumerable<Exe.IExe> Teams { get; }
IEnumerable<Exe.IExe> Excel { get; }
IEnumerable<Exe.IExe> Word { get; }
IEnumerable<Exe.IExe> PaintNet { get; }
IEnumerable<Exe.IExe> Gimp { get; }
IEnumerable<Exe.IExe> Vnc { get; }
IEnumerable<Exe.IExe> VncAdrBook { get; }
IEnumerable<Exe.IExe> IbaAnalyzer { get; }
}
}
}

View File

@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FSI.BT.Tools.Settings
{
public class Exe
{
public interface IExe
{
string ExePath { get; set; }
string Path { get; set; }
string Arguments { get; set; }
}
}
}

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FSI.BT.Tools.Settings
{
public class Folder
{
public interface IFolder : Lib.Guis.Folder.Mgt.IInterface { }
}
}

View File

@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FSI.BT.Tools.Settings
{
public class StringValue
{
public interface IStringValue
{
string Value { get; set; }
}
}
}

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FSI.BT.Tools.Settings
{
public class TxtToClip
{
// public interface ITxtToClip : Lib.Guis.TxtToClip.Mgt.Model.IInterface { }
}
}

View File

@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FSI.BT.Tools.Settings
{
public class Urls
{
public interface IUrls
{
string ZentralWeb { get; }
string Schichtbuch { get; }
string SPS { get; }
string Pl1Pls { get; }
string Pl2Pls { get; }
string Pl2Als { get; }
string Pl3Pls { get; }
string Gitea { get; }
string Wiki { get; }
string Erp { get; }
}
}
}

View File

@@ -62,6 +62,7 @@ namespace FSI.BT.Tools
InitializeComponent();
TaskbarIcon.AddBalloonClosingHandler(this, OnBalloonClosing);
}
/// <summary>
/// By subscribing to the <see cref="TaskbarIcon.BalloonClosingEvent"/>
/// and setting the "Handled" property to true, we suppress the popup
@@ -73,7 +74,6 @@ namespace FSI.BT.Tools
isClosing = true;
}
/// <summary>
/// Resolves the <see cref="TaskbarIcon"/> that displayed
/// the balloon and requests a close action.

215
FSI.BT.Tools/config.json Normal file
View File

@@ -0,0 +1,215 @@
{
"TimeStampFormat": {
"Value": "_yyyyMMdd_HHmmss"
},
"Apps": {
"SieSimaticManager": [
{
"ExePath": "C:\\Program Files (x86)\\Siemens\\STEP7\\S7BIN\\S7tgtopx.exe",
"Path": "",
"Arguments": ""
}
],
"SieTiaV13": [
{
"ExePath": "C:\\Program Files (x86)\\Siemens\\Automation\\Portal V13\\Bin\\Siemens.Automation.Portal.exe"
},
{
"ExePath": "C:\\Program Files (x86)\\Portal V13\\Bin\\Siemens.Automation.Portal.exe"
}
],
"SieTiaV14": [
{
"ExePath": "C:\\Program Files\\Siemens\\Automation\\Portal V14\\Bin\\Siemens.Automation.Portal.exe"
},
{
"ExePath": "C:\\Program Files\\Portal V14\\Bin\\Siemens.Automation.Portal.exe"
}
],
"SieTiaV15": [
{
"ExePath": "C:\\Program Files\\Siemens\\Automation\\Portal V15\\Bin\\Siemens.Automation.Portal.exe"
},
{
"ExePath": "c:\\Program Files\\Siemens\\Automation\\Portal V15_1\\Bin\\Siemens.Automation.Portal.exe"
},
{
"ExePath": "C:\\Program Files\\Portal V15_1\\Bin\\Siemens.Automation.Portal.exe"
}
],
"SieTiaV16": [
{
"ExePath": "C:\\Program Files\\Siemens\\Automation\\Portal V16\\Bin\\Siemens.Automation.Portal.exe"
},
{
"ExePath": "C:\\Program Files\\Portal V16\\Bin\\Siemens.Automation.Portal.exe"
}
],
"SieTiaV17": [
{
"ExePath": "C:\\Program Files\\Siemens\\Automation\\Portal V17\\Bin\\Siemens.Automation.Portal.exe"
}
],
"SieTiaVStarter": [
{
"ExePath": "C:\\Program Files (x86)\\Siemens\\Step7\\S7BIN\\u7wdrfax.exe"
}
],
"Epl": [
{
"ExePath": "C:\\Program Files\\EPLAN\\Platform\\2.9.4\\Bin\\EPLAN.exe",
"Arguments": "/Variant:\"Electric P8\""
},
{
"ExePath": "C:\\Program Files\\EPLAN\\Platform\\2022.0.3\\Bin\\Eplan.exe",
"Arguments": "/Variant:\"Electric P8\""
}
],
"Npp": [
{
"ExePath": "C:\\Windows\\system32\\notepad.exe"
},
{
"ExePath": "c:\\Program Files\\Notepad++\\notepad++.exe"
}
],
"TotalCmd": [
{
"ExePath": "C:\\Program Files\\totalcmd\\TOTALCMD.EXE"
},
{
"ExePath": "C:\\Program Files\\totalcmd\\TOTALCMD64.EXE"
},
{
"ExePath": "C:\\totalcmd\\TOTALCMD64.EXE"
},
{
"ExePath": "C:\\totalcmd\\TOTALCMD.EXE"
}
],
"TeXstudio": [
{
"ExePath": "C:\\Program Files\\texstudio\\texstudio.exe"
}
],
"Vs": [
{
"ExePath": "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\Common7\\IDE\\devenv.exe"
}
],
"VsCode": [
{
"ExePath": "%USERPROFILE%\\AppData\\Local\\Programs\\Microsoft VS Code\\Code.exe"
}
],
"Rdp": [
{
"ExePath": "%windir%\\system32\\mstsc.exe"
}
],
"Outlook": [
{
"ExePath": "C:\\Program Files (x86)\\Microsoft Office\\root\\Office16\\OUTLOOK.EXE"
}
],
"Teams": [
{
"ExePath": "C:\\Users\\maier_s\\AppData\\Local\\Microsoft\\Teams\\Update.exe",
"Arguments": "--processStart \"Teams.exe\""
}
],
"Excel": [
{
"ExePath": "C:\\Program Files (x86)\\Microsoft Office\\root\\Office16\\EXCEL.EXE"
}
],
"Word": [
{
"ExePath": "C:\\Program Files (x86)\\Microsoft Office\\root\\Office16\\WINWORD.EXE"
}
],
"PaintNet": [
{
"ExePath": "C:\\Program Files\\paint.net\\paintdotnet.exe"
}
],
"Gimp": [
{
"ExePath": "C:\\Program Files\\GIMP 2\\bin\\gimp-2.10.exe"
}
],
"Vnc": [
{
"ExePath": "C:\\Program Files\\RealVNC\\VNC Viewer\\vncviewer.exe"
},
{
"ExePath": "c:\\Users\\maier_s\\OneDrive - Fondium Group GmbH\\Documents\\Apps\\VNC-Viewer-6.20.113-Windows-64bit.exe"
}
],
"VncAdrBook": [
{
"ExePath": "C:\\Program Files\\RealVNC\\VNC Viewer\\vncaddrbook.exe"
}
],
"IbaAnalyzer": [
{
"ExePath": "C:\\Program Files\\iba\\ibaAnalyzer\\ibaAnalyzer.exe"
}
]
},
"Urls": {
"ZentralWeb": "http://desiaugetwf/web/?AspxAutoDetectCookieSupport=1",
"Schichtbuch": "http://10.10.1.42/SKSchichtbuchWeb/de-DE/Plugin/ShiftBook/ShiftBook/IR",
"SPS": "http://10.10.1.42/SKChangeTrackerWeb/de-DE/Plugin/ChangeTracker",
"Pl1Pls": "http://10.10.200.2/SKPL1Web/index.aspx",
"Pl2Pls": "http://10.10.213.4/SKPL2Web/index.aspx",
"Pl2Als": "http://10.10.213.234:84/emb_1/index.html",
"Pl3Pls": "http://10.10.202.10/SKPL3Web/index.aspx",
"Gitea": "http://desiaugetc7-088:3000/",
"Wiki": "http://desiaugetc7-088:3001/en/home",
"Erp": "https://mingle-portal.eu1.inforcloudsuite.com/FONDIUM_prd"
},
"Folders": [
{
"Plant": "Alg",
"SubPlant": "Alg",
"Name": "EplPdf",
"Description": "Eplan PDF Ablage",
"Path": "\\\\10.10.1.40\\Betriebstechnik\\Eplan"
},
{
"Plant": "Alg",
"SubPlant": "Alg",
"Name": "EplPrj",
"Description": "Eplan Projekt Ablage",
"Path": "\\\\fondium.org\\DESI$\\AUG_Abteilung\\Betriebstechnik\\EPL\\P8\\Data\\Projekte\\FSI\\"
},
{
"Plant": "PL2",
"SubPlant": "Alg",
"Name": "PL2 Backup",
"Description": "PL2 Backupverzeichnis",
"Path": "\\\\10.10.1.40\\Betriebstechnik\\Datensicherung\\1_IuR_Giesserei\\PL2"
}
],
"TxtToClip": [
{
"Plant": "Alg",
"SubPlant": "Alg",
"Description": "Siehe Prg.-Änderungen",
"Txt": "Siehe Prg.-Änderungen"
},
{
"Plant": "Alg",
"SubPlant": "Alg",
"Description": "Eplan Projekt Ablage",
"Txt": "\\\\fondium.org\\DESI$\\AUG_Abteilung\\Betriebstechnik\\EPL\\P8\\Data\\Projekte\\FSI\\"
},
{
"Plant": "PL2",
"SubPlant": "Alg",
"Description": "PL2 Backupverzeichnis",
"Txt": "\\\\10.10.1.40\\Betriebstechnik\\Datensicherung\\1_IuR_Giesserei\\PL2"
}
]
}

23
FSI.BT.Tools/nlog.config Normal file
View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- XSD manual extracted from package NLog.Schema: https://www.nuget.org/packages/NLog.Schema-->
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xsi:schemaLocation="NLog NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true"
internalLogFile="c:\temp\console-example-internal.log"
internalLogLevel="Info" >
<!-- the targets to write to -->
<targets>
<!-- write logs to file -->
<target xsi:type="File" name="logfile" fileName="logs/log.log" archiveFileName ="logs/{#}_log.log" archiveNumbering ="Date" archiveEvery="Day" archiveDateFormat="yyyyMMdd"
layout="${longdate}|${level}|${message} |${all-event-properties} ${exception:format=tostring}" />
<target xsi:type="Console" name="logconsole"
layout="${longdate}|${level}|${message} |${all-event-properties} ${exception:format=tostring}" />
</targets>
<!-- rules to map from logger name to target -->
<rules>
<logger name="*" minlevel="Trace" writeTo="logfile,logconsole,console" />
</rules>
</nlog>

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net472;net6.0-windows</TargetFrameworks>
<TargetFramework>net6.0-windows</TargetFramework>
<OutputType>Library</OutputType>
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
<UseWPF>true</UseWPF>
@@ -11,6 +11,14 @@
<ItemGroup Condition=" '$(TargetFramework)' == 'net472' ">
<Reference Include="System.Management" />
<Reference Include="System.Windows.Forms" />
</ItemGroup>
<ItemGroup>
<Compile Remove="Guis\TxtToClip.Mgt\**" />
<EmbeddedResource Remove="Guis\TxtToClip.Mgt\**" />
<None Remove="Guis\TxtToClip.Mgt\**" />
<Page Remove="Guis\TxtToClip.Mgt\**" />
</ItemGroup>
<ItemGroup>
@@ -34,356 +42,11 @@
<ItemGroup>
<PackageReference Include="Microsoft.Management.Infrastructure" Version="2.0.0" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="6.0.0" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="7.0.0" />
<PackageReference Include="TextCopy" Version="6.2.1" />
</ItemGroup>
<ItemGroup>
<None Update="TraceTool\Viewer\clientaccesspolicy.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\crossdomain.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\debug.bat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\DotNetWrapper.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\DotNetWrapper.pdb">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\FastMM_FullDebugMode.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\TraceTool.drc">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\TraceTool.exe">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\TraceTool.exe - debug.lnk">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\tracetool.jmin.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\tracetool.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\TraceTool.map">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\TracetoolConfig.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\TracetoolConfigProd.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\TraceTool_Icon.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\Fleck.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\Microsoft.Win32.Primitives.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\netstandard.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.AppContext.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Collections.Concurrent.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Collections.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Collections.NonGeneric.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Collections.Specialized.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.ComponentModel.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.ComponentModel.EventBasedAsync.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.ComponentModel.Primitives.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.ComponentModel.TypeConverter.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Console.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Data.Common.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Diagnostics.Contracts.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Diagnostics.Debug.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Diagnostics.FileVersionInfo.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Diagnostics.Process.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Diagnostics.StackTrace.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Diagnostics.TextWriterTraceListener.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Diagnostics.Tools.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Diagnostics.TraceSource.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Diagnostics.Tracing.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Drawing.Primitives.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Dynamic.Runtime.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Globalization.Calendars.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Globalization.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Globalization.Extensions.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.IO.Compression.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.IO.Compression.ZipFile.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.IO.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.IO.FileSystem.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.IO.FileSystem.DriveInfo.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.IO.FileSystem.Primitives.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.IO.FileSystem.Watcher.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.IO.IsolatedStorage.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.IO.MemoryMappedFiles.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.IO.Pipes.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.IO.UnmanagedMemoryStream.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Linq.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Linq.Expressions.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Linq.Parallel.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Linq.Queryable.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Net.Http.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Net.NameResolution.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Net.NetworkInformation.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Net.Ping.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Net.Primitives.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Net.Requests.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Net.Security.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Net.Sockets.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Net.WebHeaderCollection.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Net.WebSockets.Client.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Net.WebSockets.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.ObjectModel.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Reflection.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Reflection.Extensions.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Reflection.Primitives.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Resources.Reader.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Resources.ResourceManager.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Resources.Writer.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Runtime.CompilerServices.VisualC.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Runtime.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Runtime.Extensions.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Runtime.Handles.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Runtime.InteropServices.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Runtime.InteropServices.RuntimeInformation.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Runtime.Numerics.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Runtime.Serialization.Formatters.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Runtime.Serialization.Json.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Runtime.Serialization.Primitives.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Runtime.Serialization.Xml.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Security.Claims.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Security.Cryptography.Algorithms.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Security.Cryptography.Csp.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Security.Cryptography.Encoding.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Security.Cryptography.Primitives.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Security.Cryptography.X509Certificates.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Security.Principal.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Security.SecureString.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Text.Encoding.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Text.Encoding.Extensions.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Text.RegularExpressions.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Threading.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Threading.Overlapped.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Threading.Tasks.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Threading.Tasks.Parallel.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Threading.Thread.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Threading.ThreadPool.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Threading.Timer.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.ValueTuple.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Xml.ReaderWriter.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Xml.XDocument.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Xml.XmlDocument.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Xml.XmlSerializer.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Xml.XPath.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\System.Xml.XPath.XDocument.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\TraceTool.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\TraceTool.pdb">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\WebsockPlugin.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TraceTool\Viewer\WebSock\WebsockPlugin.pdb">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<ProjectReference Include="..\..\RoboSharp\RoboSharp.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,186 @@
<Window x:Class="FSI.Lib.Guis.Folder.Mgt.FrmMain"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:diagnostics="clr-namespace:System.Diagnostics;assembly=WindowsBase"
xmlns:local="clr-namespace:FSI.Lib.Guis.Folder.Mgt"
xmlns:control="clr-namespace:FSI.Lib.Wpf.Ctrls.FilterDataGrid"
d:DataContext="{d:DesignInstance Type=local:ViewModel}"
mc:Ignorable="d"
SizeToContent="Width"
Height="800"
Width="Auto"
Icon="../../Icons/FondiumU.ico">
<Window.Resources>
<ObjectDataProvider x:Key="FilteredData"></ObjectDataProvider>
</Window.Resources>
<Window.InputBindings>
<KeyBinding Command="{Binding CmdOpen}"
Gesture="CTRL+o" Key="O" />
<KeyBinding Command="{Binding CmdCopyToClip}"
Gesture="CTRL+x" Key="X" />
</Window.InputBindings>
<Grid FocusManager.FocusedElement="{Binding ElementName=tbSearch}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="0"
Margin="0,10"
HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0"
HorizontalAlignment="Left"
Orientation="Horizontal">
<Label Margin="0,0,20,0"
VerticalAlignment="Bottom"
Content="Suche:"
FontWeight="Bold" />
<TextBox Name="tbSearch"
Height="26"
MinWidth="200"
VerticalAlignment="Center"
VerticalContentAlignment="Center"
Text="{Binding Search, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
TextChanged="tbSearch_TextChanged" />
<Button Width="Auto"
Margin="5,0,0,0"
Padding="4"
Command="{Binding RefreshCommand}"
ToolTip="Filter löschen"
Cursor="Hand">
<Image Source="../../Icons/Cross.png"
Height="14" />
</Button>
</StackPanel>
<StackPanel Grid.Column="2"
HorizontalAlignment="Right"
Orientation="Horizontal">
<Button Width="Auto"
Margin="0 0 20 0"
Padding="4"
ToolTip="öffen"
Command="{Binding CmdOpen}"
IsEnabled="{Binding CanExecuteOpen}"
Cursor="Hand">
<Image Source="../../Icons/Open.png"
Height="14" />
</Button>
</StackPanel>
</Grid>
<StackPanel Grid.Row="1"
HorizontalAlignment="Left"
Orientation="Horizontal"
Margin="0,5">
<Label Margin="0,0,20,0"
VerticalAlignment="Bottom"
Content="Quick-Filter:"
FontWeight="Bold" />
<Button Width="Auto"
Margin="5,0,0,0"
Padding="4"
ToolTip="Filter löschen"
Command="{Binding RefreshCommand}"
Cursor="Hand">
<Image Source="../../Icons/Cross.png"
Height="14" />
</Button>
<Button Content="Alg"
Width="Auto"
Margin="10,0,0,0"
ToolTip="Filter auf Alg"
Command="{Binding CmdQuickSearch}"
CommandParameter="Alg"
FocusManager.FocusedElement="{Binding ElementName=tbSearch}" />
<Button Content="PL1"
Width="Auto"
Margin="10,0,0,0"
ToolTip="Filter auf PL1"
Command="{Binding CmdQuickSearch}"
CommandParameter="PL1"
FocusManager.FocusedElement="{Binding ElementName=tbSearch}" />
<Button Content="PL2"
Width="Auto"
Margin="10,0,0,0"
ToolTip="Filter auf PL2"
Command="{Binding CmdQuickSearch}"
CommandParameter="PL2"
FocusManager.FocusedElement="{Binding ElementName=tbSearch}" />
<Button Content="PL3"
Width="Auto"
Margin="10,0,0,0"
ToolTip="Filter auf PL3"
Command="{Binding CmdQuickSearch}"
CommandParameter="PL3"
FocusManager.FocusedElement="{Binding ElementName=tbSearch}" />
<Button Content="SMZ"
Width="Auto"
Margin="10,0,0,0"
ToolTip="Filter auf SMZ"
Command="{Binding CmdQuickSearch}"
CommandParameter="SMZ"
FocusManager.FocusedElement="{Binding ElementName=tbSearch}" />
</StackPanel>
<control:FilterDataGrid x:Name="FilterDataGrid"
Grid.Row="2"
AutoGenerateColumns="False"
DateFormatString="d"
FilterLanguage="German"
ItemsSource="{Binding FilteredData, UpdateSourceTrigger=PropertyChanged}"
SelectionMode="Single"
SelectedItem="{Binding SelectedData, UpdateSourceTrigger=PropertyChanged}"
ShowElapsedTime="false"
ShowRowsCount="True"
ShowStatusBar="True">
<control:FilterDataGrid.InputBindings>
<MouseBinding MouseAction="LeftDoubleClick"
Command="{Binding CmdOpen}" />
<MouseBinding MouseAction="RightDoubleClick"
Command="{Binding CmdCopyToClip}" />
</control:FilterDataGrid.InputBindings>
<control:FilterDataGrid.Columns>
<control:DataGridTemplateColumn FieldName="Plant"
Header="Anlage"
IsColumnFiltered="True"
SortMemberPath="Plant">
<control:DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="local:Interface">
<TextBlock Text="{Binding Plant}" />
</DataTemplate>
</control:DataGridTemplateColumn.CellTemplate>
</control:DataGridTemplateColumn>
<control:DataGridTextColumn Binding="{Binding SubPlant}"
Header="Teilanlagen"
IsReadOnly="True"
IsColumnFiltered="True" />
<control:DataGridTextColumn Binding="{Binding Description}"
Header="Beschreibung"
IsReadOnly="True"
IsColumnFiltered="True" />
<control:DataGridTextColumn Binding="{Binding Path}"
Header="Pfad"
IsReadOnly="True"
IsColumnFiltered="True" />
</control:FilterDataGrid.Columns>
</control:FilterDataGrid>
</Grid>
</Window>

View File

@@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
namespace FSI.Lib.Guis.Folder.Mgt
{
/// <summary>
/// Interaktionslogik für FrmMain.xaml
/// </summary>
public partial class FrmMain : Window
{
public ViewModel Folder { get; set; }
public bool CloseAtLostFocus { get; set; }
public IEnumerable<IInterface> Data { get; set; }
public FrmMain()
{
InitializeComponent();
Loaded += Main_Loaded;
Deactivated += FrmMain_Deactivated;
}
private void FrmMain_Deactivated(object sender, System.EventArgs e)
{
if (CloseAtLostFocus)
Visibility = Visibility.Hidden;
}
private void Main_Loaded(object sender, RoutedEventArgs e)
{
Title = "FSI Ordner-Auswahl";
Title += " v" + Assembly.GetExecutingAssembly().GetName().Version; // Version in Titel eintragen
Folder = new ViewModel(new DataProvider())
{
InputData = Data
};
DataContext = Folder;
Folder.Load();
}
private void tbSearch_TextChanged(object sender, TextChangedEventArgs e)
{
tbSearch.Select(tbSearch.Text.Length, 0);
}
}
}

View File

@@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FSI.Lib.Guis.Folder.Mgt//.Model
{
public interface IInterface
{
string Plant { get; set; }
string SubPlant { get; set; }
string Name { get; set; }
string Description { get; set; }
string Path { get; set; }
}
public struct Model : IInterface
{
private string _plant;
private string _subPlant;
private string _name;
private string _description;
private string _path;
public string Plant { get => _plant; set => _plant = value; }
public string SubPlant { get => _subPlant; set => _subPlant = value; }
public string Name { get => _name; set => _name = value; }
public string Description { get => _description; set => _description = value; }
public string Path { get => _path; set => _path = value; }
public string DescriptionDtl { get => _plant + " " + SubPlant + " " + Description; }
}
public interface IDataProvider
{
IEnumerable<Model> Load(IEnumerable<IInterface> folders);
}
}

View File

@@ -0,0 +1,180 @@
using FSI.Lib.MVVM;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Windows.Data;
using System.Windows.Input;
namespace FSI.Lib.Guis.Folder.Mgt
{
public class ViewModel : MVVM.ViewModelBase
{
readonly IDataProvider _dataProvider;
private string _search;
private ICollectionView _collView;
public ICommand RefreshCommand => new DelegateCommand(RefreshData);
private ICommand _cmdQuickSearch;
private ICommand _cmdOpen;
private ICommand _cmdCopyToClip;
public ViewModel(IDataProvider dataProvider)
{
Datas = new ObservableCollection<Model>();
_dataProvider = dataProvider;
_cmdQuickSearch = new RelayCommand<object>(ExecuteQuickSearch, CanExecuteQuickSearch);
_cmdOpen = new RelayCommand<object>(ExecuteOpen, CanExecuteOpen);
_cmdCopyToClip = new RelayCommand<object>(ExecuteCopyToClip, CanExecuteCopyToClip);
}
public ObservableCollection<Model> Datas { get; }
public ObservableCollection<Model> FilteredData { get; set; }
public Model SelectedData { get; set; }
public IEnumerable<IInterface> InputData { get; set; }
public void Load()
{
var datas = _dataProvider.Load(InputData);
Datas.Clear();
if (datas != null)
{
foreach (Model data in datas)
{
Datas.Add(data);
}
}
FilteredData = new ObservableCollection<Model>(Datas);
_collView = CollectionViewSource.GetDefaultView(FilteredData);
}
public string Search
{
get => _search;
set
{
_search = value;
_collView.Filter = e =>
{
var item = (Model)e;
return ((item.Plant?.StartsWith(_search, StringComparison.OrdinalIgnoreCase) ?? false)
|| (item.SubPlant?.StartsWith(_search, StringComparison.OrdinalIgnoreCase) ?? false)
#if NET472
|| (item.Path?.Contains(_search) ?? false)
|| (item.DescriptionDtl?.Contains(_search) ?? false)
#elif NET6_0
|| (item.Path?.Contains(_search, StringComparison.OrdinalIgnoreCase) ?? false)
|| (item.DescriptionDtl?.Contains(_search, StringComparison.OrdinalIgnoreCase) ?? false)
#endif
);
};
_collView.Refresh();
FilteredData = new ObservableCollection<Model>(_collView.OfType<Model>().ToList());
OnPropertyChanged();
}
}
public void QuickSearch(string search)
{
Search = search + " ";
}
private void RefreshData(object obj)
{
Search = string.Empty;
}
private bool CanExecuteQuickSearch(object obj)
{
return true;
}
private void ExecuteQuickSearch(object obj)
{
QuickSearch(obj.ToString());
}
public ICommand CmdQuickSearch
{
get { return _cmdQuickSearch; }
set => _cmdQuickSearch = value;
}
private bool CanExecuteOpen(object obj)
{
if (Directory.Exists(SelectedData.Path))
return true;
else
return false;
}
private void ExecuteOpen(object obj)
{
new Process
{
StartInfo = new ProcessStartInfo()
{
FileName = "explorer.exe",
Arguments = SelectedData.Path
}
}.Start();
}
public ICommand CmdOpen
{
get { return _cmdOpen; }
set => _cmdOpen = value;
}
private bool CanExecuteCopyToClip(object obj)
{
if (Directory.Exists(SelectedData.Path))
return true;
else
return false;
}
private void ExecuteCopyToClip(object obj)
{
TextCopy.ClipboardService.SetText(SelectedData.Path);
}
public ICommand CmdCopyToClip
{
get { return _cmdCopyToClip; }
set => _cmdCopyToClip = value;
}
}
public class DataProvider : IDataProvider
{
public IEnumerable<Model> Load(IEnumerable<IInterface> folders)
{
var newDatas = new ObservableCollection<Model>();
foreach (IInterface folder in folders)
{
Model newData = new();
newData.Plant = folder.Plant;
newData.SubPlant = folder.SubPlant;
newData.Name = folder.Name;
newData.Description = folder.Description;
newData.Path = folder.Path;
newDatas.Add(newData);
}
return newDatas;
}
}
}

View File

@@ -0,0 +1,181 @@
//using FSI.Lib.Guis.Folder.Mgt.Model;
//using FSI.Lib.MVVM;
//using System;
//using System.Collections.Generic;
//using System.Collections.ObjectModel;
//using System.ComponentModel;
//using System.Diagnostics;
//using System.Linq;
//using System.Windows.Data;
//using System.Windows.Input;
//using System.IO;
//namespace FSI.Lib.Guis.Folder.Mgt.ViewModel
//{
// public class ViewModel : MVVM.ViewModelBase
// {
// readonly IDataProvider _dataProvider;
// private string _search;
// private ICollectionView _collView;
// public ICommand RefreshCommand => new DelegateCommand(RefreshData);
// private ICommand _cmdQuickSearch;
// private ICommand _cmdOpen;
// private ICommand _cmdCopyToClip;
// public ViewModel(IDataProvider dataProvider)
// {
// Datas = new ObservableCollection<Model.Model>();
// _dataProvider = dataProvider;
// _cmdQuickSearch = new RelayCommand<object>(ExecuteQuickSearch, CanExecuteQuickSearch);
// _cmdOpen = new RelayCommand<object>(ExecuteOpen, CanExecuteOpen);
// _cmdCopyToClip = new RelayCommand<object>(ExecuteCopyToClip, CanExecuteCopyToClip);
// }
// public ObservableCollection<Model.Model> Datas { get; }
// public ObservableCollection<Model.Model> FilteredData { get; set; }
// public Model.Model SeletctedData { get; set; }
// public IEnumerable<Model.IInterface> InputData { get; set; }
// public void Load()
// {
// var datas = _dataProvider.Load(InputData);
// Datas.Clear();
// if (datas != null)
// {
// foreach (Model.Model data in datas)
// {
// Datas.Add(data);
// }
// }
// FilteredData = new ObservableCollection<Model.Model>(Datas);
// _collView = CollectionViewSource.GetDefaultView(FilteredData);
// }
// public string Search
// {
// get => _search;
// set
// {
// _search = value;
// _collView.Filter = e =>
// {
// var item = (Model.Model)e;
// return ((item.Plant?.StartsWith(_search, StringComparison.OrdinalIgnoreCase) ?? false)
// || (item.SubPlant?.StartsWith(_search, StringComparison.OrdinalIgnoreCase) ?? false)
//#if NET472
// || (item.Path?.Contains(_search) ?? false)
// || (item.DescriptionDtl?.Contains(_search) ?? false)
//#elif NET6_0
// || (item.Path?.Contains(_search, StringComparison.OrdinalIgnoreCase) ?? false)
// || (item.DescriptionDtl?.Contains(_search, StringComparison.OrdinalIgnoreCase) ?? false)
//#endif
// );
// };
// _collView.Refresh();
// FilteredData = new ObservableCollection<Model.Model>(_collView.OfType<Model.Model>().ToList());
// OnPropertyChanged();
// }
// }
// public void QuickSearch(string search)
// {
// Search = search + " ";
// }
// private void RefreshData(object obj)
// {
// Search = string.Empty;
// }
// private bool CanExecuteQuickSearch(object obj)
// {
// return true;
// }
// private void ExecuteQuickSearch(object obj)
// {
// QuickSearch(obj.ToString());
// }
// public ICommand CmdQuickSearch
// {
// get { return _cmdQuickSearch; }
// set => _cmdQuickSearch = value;
// }
// private bool CanExecuteOpen(object obj)
// {
// if (Directory.Exists(SeletctedData.Path))
// return true;
// else
// return false;
// }
// private void ExecuteOpen(object obj)
// {
// new Process
// {
// StartInfo = new ProcessStartInfo()
// {
// FileName = "explorer.exe",
// Arguments = SeletctedData.Path
// }
// }.Start();
// }
// public ICommand CmdOpen
// {
// get { return _cmdOpen; }
// set => _cmdOpen = value;
// }
// private bool CanExecuteCopyToClip(object obj)
// {
// if (Directory.Exists(SeletctedData.Path))
// return true;
// else
// return false;
// }
// private void ExecuteCopyToClip(object obj)
// {
// TextCopy.ClipboardService.SetText(SeletctedData.Path);
// }
// public ICommand CmdCopyToClip
// {
// get { return _cmdCopyToClip; }
// set => _cmdCopyToClip = value;
// }
// }
// public class DataProvider : IDataProvider
// {
// public IEnumerable<Model.Model> Load(IEnumerable<IInterface> folders)
// {
// var newDatas = new ObservableCollection<Model.Model>();
// foreach (IInterface folder in folders)
// {
// Model.Model newData = new();
// newData.Plant = folder.Plant;
// newData.SubPlant = folder.SubPlant;
// newData.Name = folder.Name;
// newData.Description = folder.Description;
// newData.Path = folder.Path;
// newDatas.Add(newData);
// }
// return newDatas;
// }
// }
//}

View File

@@ -1,6 +1,6 @@
using FSI.Lib.Guis.IbaDirSync.Model;
using FSI.Lib.MVVM;
using FSI.Lib.Tools.RoboSharp;
using RoboSharp;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -38,8 +38,8 @@ namespace FSI.Lib.Guis.IbaDirSync.ViewModel
{
_cmdStart = new RelayCommand<object>(ExecuteStart, CanExecuteStart);
_cmdStop = new RelayCommand<object>(ExecuteStop, CanExecuteStop);
RoboCopy = new Lib.Tools.RoboSharp.RoboCommand();
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
RoboCopy = new RoboSharp.RoboCommand();
if (_iba.AutoStart)
ExecuteStart(null);

View File

@@ -14,7 +14,7 @@ namespace FSI.Lib.Guis.Prj.Mgt
public bool ShowPdf { get; set; }
public bool CloseAtLostFocus { get; set; }
public string Path { get; set; }
public string[] EplExes { get; set; }
public string EplExe { get; set; }
public FrmMain()
{
@@ -47,7 +47,7 @@ namespace FSI.Lib.Guis.Prj.Mgt
{
DataPath = Path,
ShowPdf = ShowPdf,
EplExes = EplExes,
EplExe = EplExe,
};
DataContext = Prj;

View File

@@ -39,7 +39,7 @@ namespace FSI.Lib.Guis.Prj.Mgt.ViewModel
public string DataPath { get; set; }
public bool ShowPdf { get; set; }
public string[] EplExes { get; set; }
public string EplExe { get; set; }
public void Load()
{
@@ -136,22 +136,12 @@ namespace FSI.Lib.Guis.Prj.Mgt.ViewModel
{
var arguments = " /Variant:\"Electric P8\" ProjectOpen /Project:\"" + SeletctedPrj.FullName + "\"";
string fileName = string.Empty;
string path = string.Empty;
for (int i = 0; i <= EplExes.Length - 1; i++)
{
if (File.Exists(EplExes[i].Trim()))
{
fileName = EplExes[i].Trim();
}
}
new Process
{
StartInfo = new ProcessStartInfo()
{
FileName = fileName,
FileName = EplExe.Trim(),
Arguments = arguments,
}
}.Start();
@@ -177,9 +167,9 @@ namespace FSI.Lib.Guis.Prj.Mgt.ViewModel
if (((file.EndsWith(".elk") || file.EndsWith(".elp") || file.EndsWith(".els") || file.EndsWith(".elx") || file.EndsWith(".elr") || file.EndsWith(".ell") || file.EndsWith(".elf"))
&& !showPdf) || (file.EndsWith(".pdf") && showPdf))
{
Model.Prj prj = new Model.Prj();
FileInfo fileInfo = new FileInfo(file);
string[] nameNo = fileInfo.Name.Substring(0, 27 - 1).Split('-');
Model.Prj prj = new();
FileInfo fileInfo = new(file);
string[] nameNo = fileInfo.Name[..(27 - 1)].Split('-');
if (nameNo.Length == 3) // 3 Zahlenblöcke vorhanden?
{

View File

@@ -7,7 +7,8 @@ using System.Threading.Tasks;
namespace FSI.Lib.Guis.SetSizePosExWindow.Model
{
public class Window
{
{
public string Bezeichnung { get; set; }
public string Name { get; set; }
public string ClassName { get; set; }
public int Height { get; set; }

View File

@@ -71,12 +71,12 @@ namespace FSI.Lib.Guis.SetSizePosExWindow.ViewModel
private ObservableCollection<Model.Window> _windows;
private int _updateIntervall;
private bool _autoStart;
private Window _selectedWindow;
public ViewModelWindow()
{
_windows = new ObservableCollection<Model.Window>();
Init();
if (AutoStart)
@@ -129,6 +129,22 @@ namespace FSI.Lib.Guis.SetSizePosExWindow.ViewModel
}
}
public Model.Window SelectedWindow
{
get
{
return _selectedWindow;
}
set
{
if (SelectedWindow != value & SelectedWindow != null)
{
SelectedWindow = value;
OnPropertyChanged();
}
}
}
public int UpdateIntervall
{
get
@@ -144,6 +160,7 @@ namespace FSI.Lib.Guis.SetSizePosExWindow.ViewModel
}
}
}
public bool AutoStart
{
get

View File

@@ -0,0 +1,183 @@
<Window x:Class="FSI.Lib.Guis.TxtToClip.Mgt.FrmMain"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:FSI.Lib.Guis.TxtToClip.Mgt"
xmlns:diagnostics="clr-namespace:System.Diagnostics;assembly=WindowsBase"
xmlns:control="clr-namespace:FSI.Lib.Wpf.Ctrls.FilterDataGrid"
xmlns:viewmodel="clr-namespace:FSI.Lib.Guis.Folder.Mgt.ViewModel"
d:DataContext="{d:DesignInstance Type=viewmodel:ViewModel}"
mc:Ignorable="d"
SizeToContent="Width"
Height="800"
Width="Auto"
Icon="../../Icons/FondiumU.ico">
<Window.Resources>
<ObjectDataProvider x:Key="FilteredData"></ObjectDataProvider>
</Window.Resources>
<Window.InputBindings>
<KeyBinding Command="{Binding CmdCopyToClip}"
Gesture="CTRL+x" Key="X" />
</Window.InputBindings>
<Grid FocusManager.FocusedElement="{Binding ElementName=tbSearch}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="0"
Margin="0,10"
HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0"
HorizontalAlignment="Left"
Orientation="Horizontal">
<Label Margin="0,0,20,0"
VerticalAlignment="Bottom"
Content="Suche:"
FontWeight="Bold" />
<TextBox Name="tbSearch"
Height="26"
MinWidth="200"
VerticalAlignment="Center"
VerticalContentAlignment="Center"
Text="{Binding Search, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
TextChanged="tbSearch_TextChanged" />
<Button Width="Auto"
Margin="5,0,0,0"
Padding="4"
Command="{Binding RefreshCommand}"
ToolTip="Filter löschen"
Cursor="Hand">
<Image Source="../../Icons/Cross.png"
Height="14" />
</Button>
</StackPanel>
<StackPanel Grid.Column="2"
HorizontalAlignment="Right"
Orientation="Horizontal">
<Button Width="Auto"
Margin="0 0 20 0"
Padding="4"
ToolTip="öffen"
Command="{Binding CmdOpen}"
IsEnabled="{Binding CanExecuteOpen}"
Cursor="Hand">
<Image Source="../../Icons/Open.png"
Height="14" />
</Button>
</StackPanel>
</Grid>
<StackPanel Grid.Row="1"
HorizontalAlignment="Left"
Orientation="Horizontal"
Margin="0,5">
<Label Margin="0,0,20,0"
VerticalAlignment="Bottom"
Content="Quick-Filter:"
FontWeight="Bold" />
<Button Width="Auto"
Margin="5,0,0,0"
Padding="4"
ToolTip="Filter löschen"
Command="{Binding RefreshCommand}"
Cursor="Hand">
<Image Source="../../Icons/Cross.png"
Height="14" />
</Button>
<Button Content="Alg"
Width="Auto"
Margin="10,0,0,0"
ToolTip="Filter auf Alg"
Command="{Binding CmdQuickSearch}"
CommandParameter="Alg"
FocusManager.FocusedElement="{Binding ElementName=tbSearch}" />
<Button Content="PL1"
Width="Auto"
Margin="10,0,0,0"
ToolTip="Filter auf PL1"
Command="{Binding CmdQuickSearch}"
CommandParameter="PL1"
FocusManager.FocusedElement="{Binding ElementName=tbSearch}" />
<Button Content="PL2"
Width="Auto"
Margin="10,0,0,0"
ToolTip="Filter auf PL2"
Command="{Binding CmdQuickSearch}"
CommandParameter="PL2"
FocusManager.FocusedElement="{Binding ElementName=tbSearch}" />
<Button Content="PL3"
Width="Auto"
Margin="10,0,0,0"
ToolTip="Filter auf PL3"
Command="{Binding CmdQuickSearch}"
CommandParameter="PL3"
FocusManager.FocusedElement="{Binding ElementName=tbSearch}" />
<Button Content="SMZ"
Width="Auto"
Margin="10,0,0,0"
ToolTip="Filter auf SMZ"
Command="{Binding CmdQuickSearch}"
CommandParameter="SMZ"
FocusManager.FocusedElement="{Binding ElementName=tbSearch}" />
</StackPanel>
<control:FilterDataGrid x:Name="FilterDataGrid"
Grid.Row="2"
AutoGenerateColumns="False"
DateFormatString="d"
FilterLanguage="German"
ItemsSource="{Binding FilteredData, UpdateSourceTrigger=PropertyChanged}"
SelectionMode="Single"
SelectedItem="{Binding SeletctedData, UpdateSourceTrigger=PropertyChanged}"
ShowElapsedTime="false"
ShowRowsCount="True"
ShowStatusBar="True">
<control:FilterDataGrid.InputBindings>
<MouseBinding MouseAction="RightDoubleClick"
Command="{Binding CmdCopyToClip}" />
</control:FilterDataGrid.InputBindings>
<control:FilterDataGrid.Columns>
<control:DataGridTemplateColumn FieldName="Plant"
Header="Anlage"
IsColumnFiltered="True"
SortMemberPath="Plant">
<control:DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="local:Interface">
<TextBlock Text="{Binding Plant}" />
</DataTemplate>
</control:DataGridTemplateColumn.CellTemplate>
</control:DataGridTemplateColumn>
<control:DataGridTextColumn Binding="{Binding SubPlant}"
Header="Teilanlagen"
IsReadOnly="True"
IsColumnFiltered="True" />
<control:DataGridTextColumn Binding="{Binding Description}"
Header="Beschreibung"
IsReadOnly="True"
IsColumnFiltered="True" />
<control:DataGridTextColumn Binding="{Binding Txt}"
Header="Text"
IsReadOnly="True"
IsColumnFiltered="True" />
</control:FilterDataGrid.Columns>
</control:FilterDataGrid>
</Grid>
</Window>

View File

@@ -0,0 +1,63 @@
using FSI.Lib.Guis.TxtToClip.Mgt.ViewModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace FSI.Lib.Guis.TxtToClip.Mgt
{
/// <summary>
/// Interaktionslogik für frmMain.xaml
/// </summary>
public partial class FrmMain : Window
{
public ViewModelTxtToClip Folder { get; set; }
public bool CloseAtLostFocus { get; set; }
public IEnumerable<Model.IInterface> Data { get; set; }
public FrmMain()
{
InitializeComponent();
Loaded += Main_Loaded;
Deactivated += FrmMain_Deactivated;
}
private void FrmMain_Deactivated(object sender, System.EventArgs e)
{
if (CloseAtLostFocus)
Visibility = Visibility.Hidden;
}
private void Main_Loaded(object sender, RoutedEventArgs e)
{
Title = "FSI Text in die Zwischenablage kopieren";
Title += " v" + Assembly.GetExecutingAssembly().GetName().Version; // Version in Titel eintragen
Folder = new ViewModelTxtToClip(new DataProvider())
{
InputData = Data
};
DataContext = Folder;
Folder.Load();
}
private void tbSearch_TextChanged(object sender, TextChangedEventArgs e)
{
tbSearch.Select(tbSearch.Text.Length, 0);
}
}
}

View File

@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FSI.Lib.Guis.TxtToClip.Mgt.Model
{
public interface IInterface
{
string Plant { get; set; }
string SubPlant { get; set; }
string Description { get; set; }
string Txt { get; set; }
}
public struct Interface : IInterface
{
private string _plant;
private string _subPlant;
private string _description;
private string _txt;
public string Plant { get => _plant; set => _plant = value; }
public string SubPlant { get => _subPlant; set => _subPlant = value; }
public string Description { get => _description; set => _description = value; }
public string Txt { get => _txt; set => _txt = value; }
public string DescriptionDtl { get => _plant + " " + SubPlant + " " + Description; }
}
public interface IDataProvider
{
IEnumerable<Interface> Load(IEnumerable<IInterface> folders);
}
}

View File

@@ -0,0 +1,150 @@
using FSI.Lib.Guis.TxtToClip.Mgt.Model;
using FSI.Lib.MVVM;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Windows.Data;
using System.Windows.Input;
namespace FSI.Lib.Guis.TxtToClip.Mgt.ViewModel
{
public class ViewModelTxtToClip : MVVM.ViewModelBase
{
readonly IDataProvider _dataProvider;
private string _search;
private ICollectionView _collView;
public ICommand RefreshCommand => new DelegateCommand(RefreshData);
private ICommand _cmdQuickSearch;
private ICommand _cmdCopyToClip;
public ViewModelTxtToClip(IDataProvider dataProvider)
{
Datas = new ObservableCollection<Model.Interface>();
_dataProvider = dataProvider;
_cmdQuickSearch = new RelayCommand<object>(ExecuteQuickSearch, CanExecuteQuickSearch);
_cmdCopyToClip = new RelayCommand<object>(ExecuteCopyToClip, CanExecuteCopyToClip);
}
public ObservableCollection<Model.Interface> Datas { get; }
public ObservableCollection<Model.Interface> FilteredData { get; set; }
public Model.Interface SeletctedData { get; set; }
public IEnumerable<Model.IInterface> InputData { get; set; }
public void Load()
{
var datas = _dataProvider.Load(InputData);
Datas.Clear();
if (datas != null)
{
foreach (Model.Interface data in datas)
{
Datas.Add(data);
}
}
FilteredData = new ObservableCollection<Model.Interface>(Datas);
_collView = CollectionViewSource.GetDefaultView(FilteredData);
}
public string Search
{
get => _search;
set
{
_search = value;
_collView.Filter = e =>
{
var item = (Model.Interface)e;
return ((item.Plant?.StartsWith(_search, StringComparison.OrdinalIgnoreCase) ?? false)
|| (item.SubPlant?.StartsWith(_search, StringComparison.OrdinalIgnoreCase) ?? false)
#if NET472
|| (item.Path?.Contains(_search) ?? false)
|| (item.DescriptionDtl?.Contains(_search) ?? false)
#elif NET6_0
|| (item.Txt?.Contains(_search, StringComparison.OrdinalIgnoreCase) ?? false)
|| (item.DescriptionDtl?.Contains(_search, StringComparison.OrdinalIgnoreCase) ?? false)
#endif
);
};
_collView.Refresh();
FilteredData = new ObservableCollection<Model.Interface>(_collView.OfType<Model.Interface>().ToList());
OnPropertyChanged();
}
}
public void QuickSearch(string search)
{
Search = search + " ";
}
private void RefreshData(object obj)
{
Search = string.Empty;
}
private bool CanExecuteQuickSearch(object obj)
{
return true;
}
private void ExecuteQuickSearch(object obj)
{
QuickSearch(obj.ToString());
}
public ICommand CmdQuickSearch
{
get { return _cmdQuickSearch; }
set => _cmdQuickSearch = value;
}
private bool CanExecuteCopyToClip(object obj)
{
if (SeletctedData.Txt != null)
return true;
else
return false;
}
private void ExecuteCopyToClip(object obj)
{
TextCopy.ClipboardService.SetText(SeletctedData.Txt);
}
public ICommand CmdCopyToClip
{
get { return _cmdCopyToClip; }
set => _cmdCopyToClip = value;
}
}
public class DataProvider : IDataProvider
{
public IEnumerable<Model.Interface> Load(IEnumerable<IInterface> datas)
{
var newDatas = new ObservableCollection<Model.Interface>();
foreach (IInterface data in datas)
{
Model.Interface newData = new();
newData.Plant = data.Plant;
newData.SubPlant = data.SubPlant;
newData.Description = data.Description;
newData.Txt = data.Txt;
newDatas.Add(newData);
}
return newDatas;
}
}
}

View File

@@ -1,37 +0,0 @@
# RoboSharp
Link: https://github.com/tjscience/RoboSharp
### Available on NuGet - https://www.nuget.org/packages/RoboSharp/
### Wiki - in progress - https://github.com/tjscience/RoboSharp/wiki
## About
RoboSharp is a .NET wrapper for the awesome Robocopy windows application.
Robocopy is a very extensive file copy application written by microsoft and included in modern versions of Windows. To learn more about Robocopy, visit the documentation page at http://technet.microsoft.com/en-us/library/cc733145.aspx.
RoboSharp came out of a need to manipulate Robocopy in a c# backup application that I was writing. It has helped me tremendously so I thought that I would share it! It exposes all of the switches available in RoboCopy as descriptive properties. With RoboSharp, you can subscribe to events that fire when files are processed, errors occur and even as the progress of a file copy changes. Another really nice feature of RoboSharp is that you can pause and resume a copy that is in progress which is a feature that I though was lacking in Robocopy.
In the project, you will find the RoboSharp library as well as a recently updated sample backup application that shows off many (but not all) of the options.
If you like the project, please rate it!
## Examples
See the [Wiki](https://github.com/tjscience/RoboSharp/wiki) for examples and code snippets
---
| <h2>[RoboSharp Going Forward...](https://github.com/tjscience/RoboSharp/issues/63)</h2> | [![image](https://user-images.githubusercontent.com/3706870/44311401-a9064000-a3b4-11e8-96a3-d308f52aeec1.png)](https://github.com/tjscience/RoboSharp/issues/63) |
| ------ | ----------- |
---
# Contributing to RoboSharp
First off, thanks! Please go through the [guidelines](CONTRIBUTING.md).

Binary file not shown.

View File

@@ -1,82 +0,0 @@
// Plugin.cs
//
// Provide classes and interfaces for plugins
//
// Author : Thierry Parent
//
// HomePage : http://www.codeproject.com/csharp/TraceTool.asp
// Download : http://sourceforge.net/projects/tracetool/
// See License.txt for license information
//
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable ConvertIfStatementToNullCoalescingExpression
// ReSharper disable ConvertIfStatementToConditionalTernaryExpression
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable IntroduceOptionalParameters.Global
// ReSharper disable FieldCanBeMadeReadOnly.Global
// ReSharper disable UnusedMethodReturnValue.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable InlineOutVariableDeclaration
// ReSharper disable UseStringInterpolation
// ReSharper disable UseObjectOrCollectionInitializer
// ReSharper disable UseNullPropagation
// ReSharper disable MergeCastWithTypeCheck
// ReSharper disable UsePatternMatching
// ReSharper disable ArrangeAccessorOwnerBody
// ReSharper disable UnusedType.Global
#if NET472
namespace TraceTool
{
/// <summary>
/// Plugin interface. Inherit from this interface to create a TraceTool plugin
/// </summary>
public interface ITracePlugin
{
/// <summary>
/// Get the plugin name
/// </summary>
/// <returns>
/// plugin name
/// </returns>
string GetPlugName();
/// <summary>
/// Called when the user click on a button, label or menu on a WinTrace.
/// The plugin must call WinTrace.LinkToPlugin in order to receive this event
/// </summary>
/// <param name="winId">Wintrace Id</param>
/// <param name="resourceId">Resource Id</param>
/// <param name="nodeId">Node id of the current selected trace (can be empty)</param>
/// <returns>
/// when true : tracetool perform the default action
/// when false : tracetool don't perform any action
/// </returns>
bool OnAction(string winId, int resourceId, string nodeId);
/// <summary>
/// Called when a node is to be deleted on a WinTrace
/// The plugin must call WinTrace.LinkToPlugin in order to receive this event
/// </summary>
/// <param name="winId">Wintrace Id</param>
/// <param name="nodeId">Node Id</param>
/// <returns>
/// when true : tracetool delete the node
/// when false : tracetool don't delete the node
/// </returns>
bool OnBeforeDelete(string winId, string nodeId);
/// <summary>
/// Called every 500 ms. Can be used for example to refresh labels
/// The plugin must call LinkToPlugin in order to receive this event
/// </summary>
void OnTimer();
/// <summary>
/// Initialise the plugin
/// </summary>
void Start();
/// <summary>
/// Stop the plugin
/// </summary>
void Stop();
} // ITracePlugin
} // namespace TraceTool
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,117 +0,0 @@
// traceListener.cs
//
// listener,for the classic Microsoft trace
//
// Author : Thierry Parent
//
// HomePage : http://www.codeproject.com/csharp/TraceTool.asp
// Download : http://sourceforge.net/projects/tracetool/
// See License.txt for license information
//
using System.Diagnostics;
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable ConvertIfStatementToNullCoalescingExpression
// ReSharper disable ConvertIfStatementToConditionalTernaryExpression
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable IntroduceOptionalParameters.Global
// ReSharper disable FieldCanBeMadeReadOnly.Global
// ReSharper disable UnusedMethodReturnValue.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable InlineOutVariableDeclaration
// ReSharper disable UseStringInterpolation
// ReSharper disable UseObjectOrCollectionInitializer
// ReSharper disable UseNullPropagation
// ReSharper disable MergeCastWithTypeCheck
// ReSharper disable UsePatternMatching
// ReSharper disable ArrangeAccessorOwnerBody
namespace TraceTool
{
/// <summary>
/// TTraceListener is the trace listener, if you want to use the classic Microsoft Trace class.
/// </summary>
// ReSharper disable once InconsistentNaming
public class TTraceListener : TraceListener
{
/// <summary>
/// Specify at any time what is top node that receive the traces
/// </summary>
public readonly TraceToSend Listener;
private TraceNode _currentNode;
/// <summary>
/// the current node (read only)
/// </summary>
public TraceNode CurrentNode { get { return _currentNode; } }
//----------------------------------------------------------------------
/// <summary>
/// Create a listener. TTrace.Debug is used to send traces
/// </summary>
public TTraceListener()
{
Listener = TTrace.Debug;
NeedIndent = true;
}
//----------------------------------------------------------------------
/// <summary>
/// Create a listener giving a TraceNode as the parent node.
/// </summary>
/// <param name="traceDoor">Specify Debug,Warning,Error or user TraceNode object</param>
public TTraceListener(TraceNode traceDoor)
{
Listener = traceDoor;
NeedIndent = true;
}
//----------------------------------------------------------------------
/// <summary>
/// Send message to TTrace
/// </summary>
/// <param name="message">the message</param>
public override void Write(string message)
{
if (Listener == null)
return;
if (NeedIndent)
WriteIndent();
_currentNode.AppendLeft(message);
}
//----------------------------------------------------------------------
/// <summary>
/// Send message to TTrace
/// </summary>
/// <param name="message">the message</param>
public override void WriteLine(string message)
{
if (Listener == null)
return;
if (NeedIndent)
WriteIndent();
_currentNode.AppendLeft(message);
NeedIndent = true;
}
//----------------------------------------------------------------------
/// <summary>
/// Force creation of new trace node
/// </summary>
protected override void WriteIndent()
{
if (Listener == null)
return;
_currentNode = Listener.Send("");
NeedIndent = false;
}
}
}

View File

@@ -1,645 +0,0 @@
// TraceNode.CS
//
// construct the trace node
//
// Author : Thierry Parent
//
// HomePage : http://www.codeproject.com/csharp/TraceTool.asp
// Download : http://sourceforge.net/projects/tracetool/
// See License.txt for license information
//
using System;
using System.Text;
using System.Collections.Generic;
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable ConvertIfStatementToNullCoalescingExpression
// ReSharper disable ConvertIfStatementToConditionalTernaryExpression
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable IntroduceOptionalParameters.Global
// ReSharper disable FieldCanBeMadeReadOnly.Global
// ReSharper disable UnusedMethodReturnValue.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable InlineOutVariableDeclaration
// ReSharper disable UseStringInterpolation
// ReSharper disable UseObjectOrCollectionInitializer
// ReSharper disable UseNullPropagation
// ReSharper disable MergeCastWithTypeCheck
// ReSharper disable UsePatternMatching
// ReSharper disable ArrangeAccessorOwnerBody
namespace TraceTool
{
/// <summary>
/// TraceNode represent node on the viewer.
/// </summary>
public class TraceNode : TraceToSend
{
/// <summary>
/// Constructor. Use TTrace or TraceNodeEx class as entry point
/// Create a Node with an unique ID (true)
/// You can also recreated an already send node if you still have the id
/// </summary>
/// <param name="parentNode">The parent node where to place that trace.
/// The IconIndex and the enabled properties are also recopied
/// Can be null : the root tree become the parent node, enabled is true and the default icon is used
/// </param>
/// <param name="generateUniqueId">When true, a unique ID (a guid) is generated for the trace.
/// </param>
public TraceNode(TraceNode parentNode, bool generateUniqueId) // TraceToSend base class don't have constructor
{
if (generateUniqueId)
Id = Helper.NewGuid().ToString();// else : no more reset to empty string if generateUniqueId is false
if (parentNode == null)
{
IconIndex = TraceConst.CST_ICO_DEFAULT;
Enabled = true;
}
else
{
IconIndex = parentNode.IconIndex;
Enabled = parentNode.Enabled;
WinTraceId = parentNode.WinTraceId;
}
}
//----------------------------------------------------------------------
/// <summary>
/// Copy constructor : create a TraceNode copy of a TraceToSend
/// </summary>
/// <param name="source">TraceNode to copy</param>
internal TraceNode(TraceToSend source) // TraceToSend base class don't have constructor
{
IconIndex = source.IconIndex;
Enabled = source.Enabled;
WinTraceId = source.WinTraceId;
Id = source.Id;
Tag = source.Tag;
}
//----------------------------------------------------------------------
/// <summary>
/// Copy constructor : create a TraceNode copy of a TraceNodeEx
/// </summary>
/// <param name="source">TraceNodeEx to copy</param>
internal TraceNode(TraceNodeEx source) // TraceToSend base class don't have constructor
{
IconIndex = source.IconIndex;
Enabled = source.Enabled;
WinTraceId = source.WinTraceId;
Id = source.Id;
Tag = source.Tag;
}
//----------------------------------------------------------------------
/// <summary>
/// Resend the left and right trace message to the viewer
/// </summary>
/// <param name="newLeftMsg">new left message</param>
/// <param name="newRightMsg">new right message</param>
/// <returns>The trace node</returns>
public TraceNode Resend(string newLeftMsg, string newRightMsg)
{
if (Enabled == false)
return this;
if (Id == "")
throw new Exception("Node Id is null, root node cannot be modified (for now)");
List<string> commandList = new List<string>();
Helper.AddCommand(commandList, TraceConst.CST_USE_NODE, Id); // param : guid
Helper.AddCommand(commandList, TraceConst.CST_LEFT_MSG, newLeftMsg); // param : left string
Helper.AddCommand(commandList, TraceConst.CST_RIGHT_MSG, newRightMsg); // param : right string
// don't resend members and icon
TTrace.SendToWinTraceClient(commandList, WinTraceId);
return this;
}
//----------------------------------------------------------------------
/// <summary>
/// ReSend left trace to the server
/// </summary>
/// <param name="newLeftMsg">new left message</param>
/// <returns>The trace node</returns>
public TraceNode ResendLeft(string newLeftMsg)
{
if (Enabled == false)
return this;
if (Id == "")
throw new Exception("Node Id is null, root node cannot be modified (for now)");
List<string> commandList = new List<string>();
Helper.AddCommand(commandList, TraceConst.CST_USE_NODE, Id); // param : guid
Helper.AddCommand(commandList, TraceConst.CST_LEFT_MSG, newLeftMsg); // param : left string
// don't resend members and icon
TTrace.SendToWinTraceClient(commandList, WinTraceId);
return this;
}
//----------------------------------------------------------------------
/// <summary>
/// ReSend right trace to the server
/// </summary>
/// <param name="newRightMsg">new right message</param>
/// <returns>The trace node</returns>
public TraceNode ResendRight(string newRightMsg)
{
if (Enabled == false)
return this;
if (Id == "")
throw new Exception("Node Id is null, root node cannot be modified (for now)");
List<string> commandList = new List<string>();
Helper.AddCommand(commandList, TraceConst.CST_USE_NODE, Id); // param : guid
Helper.AddCommand(commandList, TraceConst.CST_RIGHT_MSG, newRightMsg); // param : right string
// don't resend members and icon
TTrace.SendToWinTraceClient(commandList, WinTraceId);
return this;
}
//----------------------------------------------------------------------
/// <summary>
/// Change the Icon index
/// </summary>
/// <param name="index">Index of the icon to use</param>
/// <returns>The trace node</returns>
public TraceNode ResendIconIndex(int index)
{
if (Enabled == false)
return this;
if (Id == "")
throw new Exception("Node Id is null, root node cannot be modified (for now)");
List<string> commandList = new List<string>();
Helper.AddCommand(commandList, TraceConst.CST_USE_NODE, Id); // param : the node that receive the string
Helper.AddCommand(commandList, TraceConst.CST_ICO_INDEX, index); // param : left string
TTrace.SendToWinTraceClient(commandList, WinTraceId);
return this;
}
//------------------------------------------------------------------------------
/// <summary>
/// Change Background Color (whole line) of a node
/// </summary>
/// <param name="color">new background color of the node</param>
/// <returns>The trace node</returns>
public TraceNode SetBackgroundColor(int color)
{
return SetBackgroundColor(color, -1);
}
//------------------------------------------------------------------------------
/// <summary>
/// Change Background Color (specific column) of a node
/// </summary>
/// <param name="color">new background color of the node</param>
/// <param name="colId">Column index : All columns=-1, Icon=0, Time=1, thread=2, left msg=3, right msg =4 or user defined column</param>
/// <returns>The trace node</returns>
public TraceNode SetBackgroundColor(int color, int colId)
{
if (Enabled == false)
return this;
if (Id == "")
throw new Exception("Node Id is null, root node cannot be modified (for now)");
List<string> commandList = new List<string>();
Helper.AddCommand(commandList, TraceConst.CST_USE_NODE, Id); // param : the node that receive font change
Helper.AddCommand(commandList, TraceConst.CST_BACKGROUND_COLOR, color, colId.ToString()); // param : color, colId
TTrace.SendToWinTraceClient(commandList, WinTraceId);
return this;
}
//----------------------------------------------------------------------
/// <summary>
/// Change font detail for an item in the trace
/// </summary>
/// <param name="colId">Column index : All columns=-1, Icon=0, Time=1, thread=2, left msg=3, right msg =4 or user defined column</param>
/// <param name="bold">Change font to bold</param>
/// <returns>The trace node</returns>
public TraceNode SetFontDetail(int colId, bool bold)
{
return SetFontDetail(colId, bold, false, -1, 0, "");
}
//----------------------------------------------------------------------
/// <summary>
/// Change font detail for an item in the trace
/// </summary>
/// <param name="colId">Column index : All columns=-1, Icon=0, Time=1, thread=2, left msg=3, right msg =4 or user defined column</param>
/// <param name="bold">Change font to bold</param>
/// <param name="italic">Change font to Italic</param>
/// <returns>The trace node</returns>
public TraceNode SetFontDetail(int colId, bool bold, bool italic)
{
return SetFontDetail(colId, bold, italic, -1, 0, "");
}
//----------------------------------------------------------------------
/// <summary>
/// Change font detail for an item in the trace
/// </summary>
/// <param name="colId">Column index : All columns=-1, Icon=0, Time=1, thread=2, left msg=3, right msg =4 or user defined column</param>
/// <param name="bold">Change font to bold</param>
/// <param name="italic">Change font to Italic</param>
/// <param name="color">Change Color. To reduce the number assembly reference, the Color structure is not used. Use YourColor.ToArgb() instead. </param>
/// <returns>The trace node</returns>
public TraceNode SetFontDetail(int colId, bool bold, bool italic, int color)
{
return SetFontDetail(colId, bold, italic, color, 0, "");
}
//----------------------------------------------------------------------
/// <summary>
/// Change font detail for an item in the trace
/// </summary>
/// <param name="colId">Column index : All columns=-1, Icon=0, Time=1, thread=2, left msg=3, right msg =4 or user defined column</param>
/// <param name="bold">Change font to bold</param>
/// <param name="italic">Change font to Italic</param>
/// <param name="color">Change Color. To reduce the number assembly reference, the Color structure is not used. Use YourColor.ToArgb() instead. Use -1 to keep default color</param>
/// <param name="size">Change font size</param>
/// <returns>The trace node</returns>
public TraceNode SetFontDetail(int colId, bool bold, bool italic, int color, int size)
{
return SetFontDetail(colId, bold, italic, color, size, "");
}
//----------------------------------------------------------------------
/// <summary>
/// Change font detail for an item in the trace
/// </summary>
/// <param name="colId">Column index : All columns=-1, Icon=0, Time=1, thread=2, left msg=3, right msg =4 or user defined column</param>
/// <param name="bold">Change font to bold</param>
/// <param name="italic">Change font to Italic</param>
/// <param name="color">Change Color. To reduce the number assembly reference, the Color structure is not used. Use YourColor.ToArgb() instead. Use -1 to keep default color</param>
/// <param name="size">Change font size, use zero to keep normal size</param>
/// <param name="fontName">Change font name</param>
/// <returns>The trace node</returns>
public TraceNode SetFontDetail(int colId, bool bold, bool italic, int color, int size, string fontName)
{
if (Enabled == false)
return this;
if (Id == "")
throw new Exception("Node Id is null, root node cannot be modified (for now)");
List<string> commandList = new List<string>();
Helper.AddCommand(commandList, TraceConst.CST_USE_NODE, Id); // param : guid
StringBuilder tempStr = new StringBuilder();
tempStr.Append(String.Format("{0,5}{1,3}", TraceConst.CST_FONT_DETAIL, colId));
if (bold)
tempStr.Append("1");
else
tempStr.Append("0");
if (italic)
tempStr.Append("1");
else
tempStr.Append("0");
if (color != -1)
{
// remove Alpha blending
color &= 0xFFFFFF;
// Color is coded as RGB. convert to BGR
int b = color & 0xff;
int g = (color >> 8) & 0xff;
int r = (color >> 0x10) & 0xff;
color = (b << 0x10) + (g << 8) + r;
}
tempStr.Append(String.Format("{0,11}{1,11}", color, size)).Append(fontName);
commandList.Add(tempStr.ToString());
TTrace.SendToWinTraceClient(commandList, WinTraceId);
return this;
}
//----------------------------------------------------------------------
/// <summary>
/// append right and left texts to an existing node
/// </summary>
/// <param name="leftMsgToAdd">left message</param>
/// <param name="rightMsgToAdd">right message</param>
/// <returns>The trace node</returns>
public TraceNode Append(string leftMsgToAdd, string rightMsgToAdd)
{
if (Enabled == false)
return this;
if (Id == "")
throw new Exception("Node Id is null, root node cannot be modified (for now)");
List<string> commandList = new List<string>();
Helper.AddCommand(commandList, TraceConst.CST_USE_NODE, Id); // param : guid
Helper.AddCommand(commandList, TraceConst.CST_APPEND_LEFT_MSG, leftMsgToAdd); // param : right string
Helper.AddCommand(commandList, TraceConst.CST_APPEND_RIGHT_MSG, rightMsgToAdd); // param : right string
// don't resend members and icon
TTrace.SendToWinTraceClient(commandList, WinTraceId);
return this;
}
//----------------------------------------------------------------------
/// <summary>
/// append left text to an existing node
/// </summary>
/// <param name="leftMsgToAdd">left message</param>
/// <returns>The trace node</returns>
public TraceNode AppendLeft(string leftMsgToAdd)
{
if (Enabled == false)
return this;
if (Id == "")
throw new Exception("Node Id is null, root node cannot be modified (for now)");
List<string> commandList = new List<string>();
Helper.AddCommand(commandList, TraceConst.CST_USE_NODE, Id); // param : guid
Helper.AddCommand(commandList, TraceConst.CST_APPEND_LEFT_MSG, leftMsgToAdd); // param : right string
// don't resend members and icon
TTrace.SendToWinTraceClient(commandList, WinTraceId);
return this;
}
//----------------------------------------------------------------------
/// <summary>
/// append right text to an existing node
/// </summary>
/// <param name="rightMsgToAdd">right message</param>
/// <returns>The trace node</returns>
public TraceNode AppendRight(string rightMsgToAdd)
{
if (Enabled == false)
return this;
if (Id == "")
throw new Exception("Node Id is null, root node cannot be modified (for now)");
List<string> commandList = new List<string>();
Helper.AddCommand(commandList, TraceConst.CST_USE_NODE, Id); // param : guid
Helper.AddCommand(commandList, TraceConst.CST_APPEND_RIGHT_MSG, rightMsgToAdd); // param : right string
// don't resend members and icon
TTrace.SendToWinTraceClient(commandList, WinTraceId);
return this;
}
//----------------------------------------------------------------------
/// <summary>
/// append right text to an existing node
/// </summary>
/// <returns>The trace node</returns>
public TraceNode AppendStack()
{
if (Enabled == false)
return this;
if (Id == "")
throw new Exception("Node Id is null, root node cannot be modified (for now)");
List<string> commandList = new List<string>();
Helper.AddCommand(commandList, TraceConst.CST_USE_NODE, Id); // param : guid
TraceNodeEx result = new TraceNodeEx(this, true); // create a node with same properties as "this" with new ID
result.AddStackTrace(1);
result.Members.AddToStringList(commandList); // convert all groups and nested items/group to strings
TTrace.SendToWinTraceClient(commandList, WinTraceId);
return this;
}
//----------------------------------------------------------------------
/// <summary>
/// Show the node in the tree (not means selected, just visible in the tree)
/// </summary>
/// <returns>The trace node</returns>
public TraceNode Show()
{
if (Enabled == false)
return this;
if (Id == "")
throw new Exception("Node Id is null, root node cannot be modified (for now)");
List<string> commandList = new List<string>();
Helper.AddCommand(commandList, TraceConst.CST_FOCUS_NODE, Id); // param : guid
TTrace.SendToWinTraceClient(commandList, WinTraceId);
return this;
}
//----------------------------------------------------------------------
/// <summary>
/// Select the node in the viewer
/// </summary>
/// <returns>The trace node</returns>
public TraceNode SetSelected()
{
if (Enabled == false)
return this;
if (Id == "")
throw new Exception("Node Id is null, root node cannot be modified (for now)");
List<string> commandList = new List<string>();
Helper.AddCommand(commandList, TraceConst.CST_SELECT_NODE, Id); // param : guid
TTrace.SendToWinTraceClient(commandList, WinTraceId);
return this;
}
//----------------------------------------------------------------------
/// <summary>
/// Delete the node
/// </summary>
/// <returns>The trace node</returns>
public TraceNode Delete()
{
if (Enabled == false)
return this;
if (Id == "")
throw new Exception("Node Id is null, root node cannot be modified (for now)");
List<string> commandList = new List<string>();
Helper.AddCommand(commandList, TraceConst.CST_CLEAR_NODE, Id); // param : guid
TTrace.SendToWinTraceClient(commandList, WinTraceId);
return this;
}
//------------------------------------------------------------------------------
/// <summary>
/// Delete children node
/// </summary>
/// <returns>The trace node</returns>
public TraceNode DeleteChildren()
{
if (Enabled == false)
return this;
if (Id == "")
throw new Exception("Node Id is null, root node cannot be modified (for now)");
List<string> commandList = new List<string>();
Helper.AddCommand(commandList, TraceConst.CST_CLEAR_SUBNODES, Id); // param : guid
TTrace.SendToWinTraceClient(commandList, WinTraceId);
return this;
}
//------------------------------------------------------------------------------
/// <summary>
/// Set or reset the bookmark for the node
/// </summary>
/// <param name="bookmarked">true/false</param>
/// <returns>The trace node</returns>
public TraceNode SetBookmark(bool bookmarked)
{
if (Enabled == false)
return this;
if (Id == "")
throw new Exception("Node Id is null, root node cannot be modified (for now)");
List<string> commandList = new List<string>();
Helper.AddCommand(commandList, TraceConst.CST_USE_NODE, Id);
Helper.AddCommand(commandList, TraceConst.CST_SET_BOOKMARK, bookmarked);
TTrace.SendToWinTraceClient(commandList, WinTraceId);
return this;
}
//------------------------------------------------------------------------------
/// <summary>
/// set a node visible or invisible
/// </summary>
/// <param name="visible">true/false</param>
/// <returns>The trace node</returns>
public TraceNode SetVisible(bool visible)
{
if (Enabled == false)
return this;
if (Id == "")
throw new Exception("Node Id is null, root node cannot be modified (for now)");
List<string> commandList = new List<string>();
Helper.AddCommand(commandList, TraceConst.CST_USE_NODE, Id); // param : the node
Helper.AddCommand(commandList, TraceConst.CST_VISIBLE_NODE, visible); // param : visible flag
TTrace.SendToWinTraceClient(commandList, WinTraceId);
return this;
}
//------------------------------------------------------------------------------
/// <summary>
/// Set focus to next sibling
/// </summary>
/// <returns>The trace node</returns>
public TraceNode GotoNextSibling()
{
if (Enabled == false)
return this;
if (Id == "")
throw new Exception("Node Id is null, root node cannot be modified (for now)");
List<string> commandList = new List<string>();
Helper.AddCommand(commandList, TraceConst.CST_GOTO_NEXTSIBLING, Id);
TTrace.SendToWinTraceClient(commandList, WinTraceId);
return this;
}
//------------------------------------------------------------------------------
/// <summary>
/// Set focus to previous sibling
/// </summary>
/// <returns>The trace node</returns>
public TraceNode GotoPrevSibling()
{
if (Enabled == false)
return this;
if (Id == "")
throw new Exception("Node Id is null, root node cannot be modified (for now)");
List<string> commandList = new List<string>();
Helper.AddCommand(commandList, TraceConst.CST_GOTO_PREVSIBLING, Id);
TTrace.SendToWinTraceClient(commandList, WinTraceId);
return this;
}
//------------------------------------------------------------------------------
/// <summary>
/// Set focus to first child
/// </summary>
/// <returns>The trace node</returns>
public TraceNode GotoFirstChild()
{
if (Enabled == false)
return this;
if (Id == "")
throw new Exception("Node Id is null, root node cannot be modified (for now)");
List<string> commandList = new List<string>();
Helper.AddCommand(commandList, TraceConst.CST_GOTO_FIRST_CHILD, Id);
TTrace.SendToWinTraceClient(commandList, WinTraceId);
return this;
}
//------------------------------------------------------------------------------
/// <summary>
/// Set focus to last child
/// </summary>
/// <returns>The trace node</returns>
public TraceNode GotoLastChild()
{
if (Enabled == false)
return this;
if (Id == "")
throw new Exception("Node Id is null, root node cannot be modified (for now)");
List<string> commandList = new List<string>();
Helper.AddCommand(commandList, TraceConst.CST_GOTO_LAST_CHILD, Id);
TTrace.SendToWinTraceClient(commandList, WinTraceId);
return this;
}
}
} // namespace TraceTool

View File

@@ -1,67 +0,0 @@
// TraceNodeBase.CS
//
// Base class for TraceToSend(TraceNode and Wintrace) and TraceNodeEx.
//
// Author : Thierry Parent
//
// HomePage : http://www.codeproject.com/csharp/TraceTool.asp
// Download : http://sourceforge.net/projects/tracetool/
// See License.txt for license information
//
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable ConvertIfStatementToNullCoalescingExpression
// ReSharper disable ConvertIfStatementToConditionalTernaryExpression
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable IntroduceOptionalParameters.Global
// ReSharper disable FieldCanBeMadeReadOnly.Global
// ReSharper disable UnusedMethodReturnValue.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable InlineOutVariableDeclaration
// ReSharper disable UseStringInterpolation
// ReSharper disable UseObjectOrCollectionInitializer
// ReSharper disable UseNullPropagation
// ReSharper disable MergeCastWithTypeCheck
// ReSharper disable UsePatternMatching
// ReSharper disable ArrangeAccessorOwnerBody
namespace TraceTool
{
/// <summary>
/// base class for TraceToSend (TraceNode, Wintrace) and traceNodeEx
/// </summary>
public abstract class TraceNodeBase
{
/// <summary>
/// The unique ID. Normally it's a GUID, but can be replaced by something else for inter process traces.
/// </summary>
public string Id;
/// <summary>
/// When Enabled is false, all traces are disabled. Default is true.
/// All node have a Enabled property, that lets you define group of Enabled trace.
/// For example set the TTrace.Debug.enabled to false but continue to accept Error and Warning traces
/// </summary>
public bool Enabled;
/// <summary>
/// The window where trace is send.
/// </summary>
public string WinTraceId;
/// <summary>
/// User variable, provided for the convenience of developers
/// </summary>
public object Tag;
/// <summary>
/// The index of the icon to use. You can then show an icon for Warning traces different for Error traces
/// </summary>
public int IconIndex;
/// <summary>
/// return the node id
/// </summary>
/// <returns>node id</returns>
public new string ToString()
{
return Id;
}
}
}

Some files were not shown because too many files have changed in this diff Show More