Projektdateien hinzufügen.

This commit is contained in:
Jonathan Jenne 2020-08-25 10:43:21 +02:00
parent 48c4b42d41
commit 614b415a98
29 changed files with 2444 additions and 0 deletions

View File

@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29728.190
MinimumVisualStudioVersion = 10.0.40219.1
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "WinLineArtikelnummerGenerator", "WinLineArtikelnummerGenerator\WinLineArtikelnummerGenerator.vbproj", "{BA171D0B-6421-4294-B5DC-BF77D93C91E7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{BA171D0B-6421-4294-B5DC-BF77D93C91E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BA171D0B-6421-4294-B5DC-BF77D93C91E7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BA171D0B-6421-4294-B5DC-BF77D93C91E7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BA171D0B-6421-4294-B5DC-BF77D93C91E7}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {2FFA2908-335A-4211-8E21-1E5323B7C645}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="WinLineArtikelnummerGenerator.My.MySettings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<connectionStrings>
<add name="WinLineArtikelnummerGenerator.My.MySettings.MyConnectionString"
connectionString="Data Source=SDD-VMP04-SQL17\MEDACOM;Initial Catalog=CWLDATEN_MEDS;User ID=sa;Password=dd"
providerName="System.Data.SqlClient" />
</connectionStrings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
<userSettings>
<WinLineArtikelnummerGenerator.My.MySettings>
<setting name="ConnectionString" serializeAs="String">
<value />
</setting>
</WinLineArtikelnummerGenerator.My.MySettings>
</userSettings>
</configuration>

View File

@ -0,0 +1,242 @@
'------------------------------------------------------------------------------
' <auto-generated>
' Dieser Code wurde von einem Tool generiert.
' Laufzeitversion:4.0.30319.42000
'
' Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
' der Code erneut generiert wird.
' </auto-generated>
'------------------------------------------------------------------------------
Option Strict Off
Option Explicit On
'''<summary>
'''Represents a strongly typed in-memory cache of data.
'''</summary>
<Global.System.Serializable(), _
Global.System.ComponentModel.DesignerCategoryAttribute("code"), _
Global.System.ComponentModel.ToolboxItem(true), _
Global.System.Xml.Serialization.XmlSchemaProviderAttribute("GetTypedDataSetSchema"), _
Global.System.Xml.Serialization.XmlRootAttribute("CWLDATEN_MEDSDataSet"), _
Global.System.ComponentModel.Design.HelpKeywordAttribute("vs.data.DataSet")> _
Partial Public Class CWLDATEN_MEDSDataSet
Inherits Global.System.Data.DataSet
Private _schemaSerializationMode As Global.System.Data.SchemaSerializationMode = Global.System.Data.SchemaSerializationMode.IncludeSchema
<Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "16.0.0.0")> _
Public Sub New()
MyBase.New
Me.BeginInit
Me.InitClass
Dim schemaChangedHandler As Global.System.ComponentModel.CollectionChangeEventHandler = AddressOf Me.SchemaChanged
AddHandler MyBase.Tables.CollectionChanged, schemaChangedHandler
AddHandler MyBase.Relations.CollectionChanged, schemaChangedHandler
Me.EndInit
End Sub
<Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "16.0.0.0")> _
Protected Sub New(ByVal info As Global.System.Runtime.Serialization.SerializationInfo, ByVal context As Global.System.Runtime.Serialization.StreamingContext)
MyBase.New(info, context, false)
If (Me.IsBinarySerialized(info, context) = true) Then
Me.InitVars(false)
Dim schemaChangedHandler1 As Global.System.ComponentModel.CollectionChangeEventHandler = AddressOf Me.SchemaChanged
AddHandler Me.Tables.CollectionChanged, schemaChangedHandler1
AddHandler Me.Relations.CollectionChanged, schemaChangedHandler1
Return
End If
Dim strSchema As String = CType(info.GetValue("XmlSchema", GetType(String)),String)
If (Me.DetermineSchemaSerializationMode(info, context) = Global.System.Data.SchemaSerializationMode.IncludeSchema) Then
Dim ds As Global.System.Data.DataSet = New Global.System.Data.DataSet()
ds.ReadXmlSchema(New Global.System.Xml.XmlTextReader(New Global.System.IO.StringReader(strSchema)))
Me.DataSetName = ds.DataSetName
Me.Prefix = ds.Prefix
Me.Namespace = ds.Namespace
Me.Locale = ds.Locale
Me.CaseSensitive = ds.CaseSensitive
Me.EnforceConstraints = ds.EnforceConstraints
Me.Merge(ds, false, Global.System.Data.MissingSchemaAction.Add)
Me.InitVars
Else
Me.ReadXmlSchema(New Global.System.Xml.XmlTextReader(New Global.System.IO.StringReader(strSchema)))
End If
Me.GetSerializationData(info, context)
Dim schemaChangedHandler As Global.System.ComponentModel.CollectionChangeEventHandler = AddressOf Me.SchemaChanged
AddHandler MyBase.Tables.CollectionChanged, schemaChangedHandler
AddHandler Me.Relations.CollectionChanged, schemaChangedHandler
End Sub
<Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "16.0.0.0"), _
Global.System.ComponentModel.BrowsableAttribute(true), _
Global.System.ComponentModel.DesignerSerializationVisibilityAttribute(Global.System.ComponentModel.DesignerSerializationVisibility.Visible)> _
Public Overrides Property SchemaSerializationMode() As Global.System.Data.SchemaSerializationMode
Get
Return Me._schemaSerializationMode
End Get
Set
Me._schemaSerializationMode = value
End Set
End Property
<Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "16.0.0.0"), _
Global.System.ComponentModel.DesignerSerializationVisibilityAttribute(Global.System.ComponentModel.DesignerSerializationVisibility.Hidden)> _
Public Shadows ReadOnly Property Tables() As Global.System.Data.DataTableCollection
Get
Return MyBase.Tables
End Get
End Property
<Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "16.0.0.0"), _
Global.System.ComponentModel.DesignerSerializationVisibilityAttribute(Global.System.ComponentModel.DesignerSerializationVisibility.Hidden)> _
Public Shadows ReadOnly Property Relations() As Global.System.Data.DataRelationCollection
Get
Return MyBase.Relations
End Get
End Property
<Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "16.0.0.0")> _
Protected Overrides Sub InitializeDerivedDataSet()
Me.BeginInit
Me.InitClass
Me.EndInit
End Sub
<Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "16.0.0.0")> _
Public Overrides Function Clone() As Global.System.Data.DataSet
Dim cln As CWLDATEN_MEDSDataSet = CType(MyBase.Clone,CWLDATEN_MEDSDataSet)
cln.InitVars
cln.SchemaSerializationMode = Me.SchemaSerializationMode
Return cln
End Function
<Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "16.0.0.0")> _
Protected Overrides Function ShouldSerializeTables() As Boolean
Return false
End Function
<Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "16.0.0.0")> _
Protected Overrides Function ShouldSerializeRelations() As Boolean
Return false
End Function
<Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "16.0.0.0")> _
Protected Overrides Sub ReadXmlSerializable(ByVal reader As Global.System.Xml.XmlReader)
If (Me.DetermineSchemaSerializationMode(reader) = Global.System.Data.SchemaSerializationMode.IncludeSchema) Then
Me.Reset
Dim ds As Global.System.Data.DataSet = New Global.System.Data.DataSet()
ds.ReadXml(reader)
Me.DataSetName = ds.DataSetName
Me.Prefix = ds.Prefix
Me.Namespace = ds.Namespace
Me.Locale = ds.Locale
Me.CaseSensitive = ds.CaseSensitive
Me.EnforceConstraints = ds.EnforceConstraints
Me.Merge(ds, false, Global.System.Data.MissingSchemaAction.Add)
Me.InitVars
Else
Me.ReadXml(reader)
Me.InitVars
End If
End Sub
<Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "16.0.0.0")> _
Protected Overrides Function GetSchemaSerializable() As Global.System.Xml.Schema.XmlSchema
Dim stream As Global.System.IO.MemoryStream = New Global.System.IO.MemoryStream()
Me.WriteXmlSchema(New Global.System.Xml.XmlTextWriter(stream, Nothing))
stream.Position = 0
Return Global.System.Xml.Schema.XmlSchema.Read(New Global.System.Xml.XmlTextReader(stream), Nothing)
End Function
<Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "16.0.0.0")> _
Friend Overloads Sub InitVars()
Me.InitVars(true)
End Sub
<Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "16.0.0.0")> _
Friend Overloads Sub InitVars(ByVal initTable As Boolean)
End Sub
<Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "16.0.0.0")> _
Private Sub InitClass()
Me.DataSetName = "CWLDATEN_MEDSDataSet"
Me.Prefix = ""
Me.Namespace = "http://tempuri.org/CWLDATEN_MEDSDataSet.xsd"
Me.EnforceConstraints = true
Me.SchemaSerializationMode = Global.System.Data.SchemaSerializationMode.IncludeSchema
End Sub
<Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "16.0.0.0")> _
Private Sub SchemaChanged(ByVal sender As Object, ByVal e As Global.System.ComponentModel.CollectionChangeEventArgs)
If (e.Action = Global.System.ComponentModel.CollectionChangeAction.Remove) Then
Me.InitVars
End If
End Sub
<Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "16.0.0.0")> _
Public Shared Function GetTypedDataSetSchema(ByVal xs As Global.System.Xml.Schema.XmlSchemaSet) As Global.System.Xml.Schema.XmlSchemaComplexType
Dim ds As CWLDATEN_MEDSDataSet = New CWLDATEN_MEDSDataSet()
Dim type As Global.System.Xml.Schema.XmlSchemaComplexType = New Global.System.Xml.Schema.XmlSchemaComplexType()
Dim sequence As Global.System.Xml.Schema.XmlSchemaSequence = New Global.System.Xml.Schema.XmlSchemaSequence()
Dim any As Global.System.Xml.Schema.XmlSchemaAny = New Global.System.Xml.Schema.XmlSchemaAny()
any.Namespace = ds.Namespace
sequence.Items.Add(any)
type.Particle = sequence
Dim dsSchema As Global.System.Xml.Schema.XmlSchema = ds.GetSchemaSerializable
If xs.Contains(dsSchema.TargetNamespace) Then
Dim s1 As Global.System.IO.MemoryStream = New Global.System.IO.MemoryStream()
Dim s2 As Global.System.IO.MemoryStream = New Global.System.IO.MemoryStream()
Try
Dim schema As Global.System.Xml.Schema.XmlSchema = Nothing
dsSchema.Write(s1)
Dim schemas As Global.System.Collections.IEnumerator = xs.Schemas(dsSchema.TargetNamespace).GetEnumerator
Do While schemas.MoveNext
schema = CType(schemas.Current,Global.System.Xml.Schema.XmlSchema)
s2.SetLength(0)
schema.Write(s2)
If (s1.Length = s2.Length) Then
s1.Position = 0
s2.Position = 0
Do While ((s1.Position <> s1.Length) _
AndAlso (s1.ReadByte = s2.ReadByte))
Loop
If (s1.Position = s1.Length) Then
Return type
End If
End If
Loop
Finally
If (Not (s1) Is Nothing) Then
s1.Close
End If
If (Not (s2) Is Nothing) Then
s2.Close
End If
End Try
End If
xs.Add(dsSchema)
Return type
End Function
End Class

View File

@ -0,0 +1 @@


View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="CWLDATEN_MEDSDataSet" targetNamespace="http://tempuri.org/CWLDATEN_MEDSDataSet.xsd" xmlns:mstns="http://tempuri.org/CWLDATEN_MEDSDataSet.xsd" xmlns="http://tempuri.org/CWLDATEN_MEDSDataSet.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:msprop="urn:schemas-microsoft-com:xml-msprop" attributeFormDefault="qualified" elementFormDefault="qualified">
<xs:annotation>
<xs:appinfo source="urn:schemas-microsoft-com:xml-msdatasource">
<DataSource DefaultConnectionIndex="0" FunctionsComponentName="QueriesTableAdapter" Modifier="AutoLayout, AnsiClass, Class, Public" SchemaSerializationMode="IncludeSchema" xmlns="urn:schemas-microsoft-com:xml-msdatasource">
<Connections>
<Connection AppSettingsObjectName="MySettings" AppSettingsPropertyName="MyConnectionString" ConnectionStringObject="" IsAppSettingsProperty="true" Modifier="Assembly" Name="MyConnectionString (MySettings)" ParameterPrefix="@" PropertyReference="ApplicationSettings.WinLineArtikelnummerGenerator.My.MySettings.GlobalReference.Default.MyConnectionString" Provider="System.Data.SqlClient" />
</Connections>
<Tables />
<Sources />
</DataSource>
</xs:appinfo>
</xs:annotation>
<xs:element name="CWLDATEN_MEDSDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true" msprop:EnableTableAdapterManager="True" msprop:Generator_DataSetName="CWLDATEN_MEDSDataSet" msprop:Generator_UserDSName="CWLDATEN_MEDSDataSet">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded" />
</xs:complexType>
</xs:element>
</xs:schema>

View File

@ -0,0 +1 @@


View File

@ -0,0 +1,5 @@
Imports DigitalData.Modules.Config.ConfigAttributes
Public Class Config
Public Property ConnectionString As String
End Class

View File

@ -0,0 +1,105 @@
Imports System.Data.SqlClient
Public Class Database
Private _Config As ConfigManager(Of Config)
Private _LogConfig As LogConfig
Private _Logger As Logger
Private Const QUERY_TIMEOUT = 120000
Public Sub New(LogConfig As LogConfig, ConfigManager As ConfigManager(Of Config))
_LogConfig = LogConfig
_Logger = LogConfig.GetLogger()
_Config = ConfigManager
End Sub
Public Function LoadVendors() As DataTable
Return GetDatatable("SELECT C229, C003 FROM V050 WHERE C229 IS NOT NULL")
End Function
Public Function LoadVendorIdByCode(VendorCode As String) As String
Return GetScalarValue($"SELECT SUBSTRING(C000,0,6) C999 FROM T309 WHERE C001 = '{VendorCode}' AND C002 = 1")
End Function
Public Function LoadGroupsByVendor(VendorId As String) As DataTable
Return GetDatatable($"SELECT C001, SUBSTRING(C000,7,5) C999 FROM T309 WHERE C000 LIKE '{VendorId}%' AND C002 = 2 AND C001 LIKE '__ | %'")
End Function
Public Function LoadVersionsByVendorAndGroup(VendorId As String, GroupId As String) As DataTable
Return GetDatatable($"SELECT C001 FROM T309 WHERE C000 LIKE '{VendorId}-{GroupId}-%' AND C002 = 3 AND C001 LIKE '__ | %'")
End Function
#Region "Database-Access"
Private Function GetSQLConnection() As SqlConnection
Return GetSQLConnection(_Config.Config.ConnectionString)
End Function
Private Function GetSQLConnection(ConnectionString As String) As SqlConnection
Try
Dim oConnection As New SqlConnection(ConnectionString)
oConnection.Open()
Dim oMaskedConnectionString = MaskConnectionString(ConnectionString)
_Logger.Debug("The Following Connection is open: {0}", oMaskedConnectionString)
Return oConnection
Catch ex As Exception
_Logger.Error(ex)
Return Nothing
End Try
End Function
Private Function MaskConnectionString(ConnectionString As String) As String
Try
Dim oBuilder As New SqlConnectionStringBuilder() With {.ConnectionString = ConnectionString}
Dim oConnectionString = ConnectionString.Replace(oBuilder.Password, "XXXXX")
Return oConnectionString
Catch ex As Exception
_Logger.Error(ex)
Return "Invalid ConnectionString"
End Try
End Function
Public Function GetDatatable(SqlCommand As String) As DataTable
Try
_Logger.Debug("GetDatatable: Running Query [{0}]", SqlCommand)
Using oConnection = GetSQLConnection()
Using oSQLCOmmand = oConnection.CreateCommand()
oSQLCOmmand.CommandText = SqlCommand
oSQLCOmmand.CommandTimeout = QUERY_TIMEOUT
Dim dt As DataTable = New DataTable()
Dim oAdapter As SqlDataAdapter = New SqlDataAdapter(oSQLCOmmand)
oAdapter.Fill(dt)
Return dt
End Using
End Using
Catch ex As Exception
_Logger.Warn($"GetDatatable failed SQLCommand [{SqlCommand}] - ERROR: {ex.Message}")
Return Nothing
End Try
End Function
Public Function GetScalarValue(SQLCommand As String) As Object
Try
_Logger.Debug("GetScalarValue: Running Query [{0}]", SQLCommand)
Using oConnection As SqlConnection = GetSQLConnection()
Using oSQLCOmmand = oConnection.CreateCommand()
oSQLCOmmand.CommandText = SQLCommand
oSQLCOmmand.CommandTimeout = QUERY_TIMEOUT
Dim oResult As Object = oSQLCOmmand.ExecuteScalar()
Return oResult
End Using
End Using
Catch ex As Exception
_Logger.Warn($"GetScalarValue failed SQLCommand [{SQLCommand}] - ERROR: {ex.Message}")
Return Nothing
End Try
End Function
#End Region
End Class

View File

@ -0,0 +1,11 @@
Public Class Article
Public VendorId As String
Public ProductGroupId As String
Public ProductVersionId As String
Public RunningNumber As String
Public AddedWho As String
Public ChangedWho As String
Public AddedWhen As Date
Public ChangedWhen As Date
End Class

View File

@ -0,0 +1,11 @@
Public Class ProductGroup
Public Guid As Integer
Public Name As String
Public NickName As String
Public Property Versions As List(Of ProductVersion)
Public Sub New()
Versions = New List(Of ProductVersion)
End Sub
End Class

View File

@ -0,0 +1,4 @@
Public Class ProductVersion
Public Guid As Integer
Public Name As String
End Class

View File

@ -0,0 +1,5 @@
Public Class Vendor
Public Guid As Integer
Public Id As String
Public Name As String
End Class

View File

@ -0,0 +1,333 @@
Imports System.IO
Imports System.Reflection
Imports System.Xml.Serialization
Imports DigitalData.Modules.Logging
Imports DigitalData.Modules.Config.ConfigAttributes
Public Class ConfigManager(Of T)
Private Const USER_CONFIG_NAME As String = "UserConfig.xml"
Private Const COMPUTER_CONFIG_NAME As String = "ComputerConfig.xml"
Private Const APP_CONFIG_NAME As String = "AppConfig.xml"
Private ReadOnly _LogConfig As LogConfig
Private ReadOnly _Logger As Logger
Private ReadOnly _File As File
Private ReadOnly _UserDirectory As String
Private ReadOnly _UserConfigPath As String
Private ReadOnly _ComputerDirectory As String
Private ReadOnly _ComputerConfigPath As String
Private ReadOnly _AppConfigPath As String
Private ReadOnly _AppConfigDirectory As String
Private ReadOnly _TestMode As Boolean = False
Private ReadOnly _Blueprint As T
Private ReadOnly _BlueprintType As Type
Private ReadOnly _Serializer As XmlSerializer
Private ReadOnly _ExcludedAttributes = New List(Of Type) From {
GetType(ConnectionStringAttribute),
GetType(ConnectionStringTestAttribute),
GetType(GlobalSettingAttribute)
}
Private _WriteAllValuesToUserConfig As Boolean = False
''' <summary>
''' Returns the currently loaded config object
''' </summary>
''' <returns></returns>
Public ReadOnly Property Config As T
''' <summary>
''' Path to the current user config.
''' </summary>
''' <returns></returns>
Public ReadOnly Property UserConfigPath As String
Get
Return _UserConfigPath
End Get
End Property
''' <summary>
''' Path to the current computer config. Maybe the same as `UserConfigPath`
''' </summary>
''' <returns></returns>
Public ReadOnly Property ComputerConfigPath As String
Get
Return _ComputerConfigPath
End Get
End Property
Public ReadOnly Property AppConfigPath As String
Get
Return _AppConfigPath
End Get
End Property
''' <summary>
''' Creates a new instance of the ConfigManager
''' </summary>
''' <seealso cref="ConfigSample"/>
''' <param name="LogConfig">LogConfig instance</param>
''' <param name="UserConfigPath">The path to check for a user config file, eg. AppData (Usually Application.UserAppDataPath or Application.LocalUserAppDataPath)</param>
''' <param name="ComputerConfigPath">The path to check for a computer config file, eg. ProgramData (Usually Application.CommonAppDataPath)</param>
''' <param name="ApplicationStartupPath">The path to check for a third config file. This is useful when running the Application in an environment where AppData/ProgramData directories are not available</param>
''' <param name="ForceUserConfig">Override values from ComputerConfig with UserConfig</param>
Public Sub New(LogConfig As LogConfig, UserConfigPath As String, ComputerConfigPath As String, Optional ApplicationStartupPath As String = "", Optional ForceUserConfig As Boolean = False)
_LogConfig = LogConfig
_Logger = LogConfig.GetLogger()
_File = New File(_LogConfig)
_Blueprint = Activator.CreateInstance(Of T)
_BlueprintType = _Blueprint.GetType
_Serializer = New XmlSerializer(_BlueprintType)
_UserDirectory = _File.CreateDirectory(UserConfigPath)
_UserConfigPath = Path.Combine(_UserDirectory, USER_CONFIG_NAME)
If ComputerConfigPath <> String.Empty Then
_ComputerDirectory = _File.CreateDirectory(ComputerConfigPath)
_ComputerConfigPath = Path.Combine(_ComputerDirectory, COMPUTER_CONFIG_NAME)
End If
If ApplicationStartupPath <> String.Empty Then
_AppConfigPath = Path.Combine(ApplicationStartupPath, APP_CONFIG_NAME)
End If
_WriteAllValuesToUserConfig = ForceUserConfig
Config = LoadConfig()
End Sub
''' <summary>
''' Creates a new ConfigManager with a single (user)config path
''' </summary>
''' <param name="LogConfig">LogConfig instance</param>
''' <param name="ConfigPath">The path to check for a user config file, eg. AppData (Usually Application.UserAppDataPath or Application.LocalUserAppDataPath)</param>
Public Sub New(LogConfig As LogConfig, ConfigPath As String)
MyClass.New(LogConfig, ConfigPath, String.Empty, String.Empty, ForceUserConfig:=True)
End Sub
''' <summary>
''' Save the current config object to `UserConfigPath`
''' </summary>
''' <param name="ForceAll">Force saving all attributes including the attributes marked as excluded</param>
''' <returns>True if save was successful, False otherwise</returns>
Public Function Save(Optional ForceAll As Boolean = False) As Boolean
Try
WriteToFile(Config, _UserConfigPath, ForceAll)
Return True
Catch ex As Exception
_Logger.Error(ex)
Return False
End Try
End Function
''' <summary>
''' Copies all properties from Source to Target, except those who have an attribute
''' listed in ExcludedAttributeTypes
''' </summary>
''' <param name="Source">Source config object</param>
''' <param name="Target">Target config object</param>
''' <param name="ExcludedAttributeTypes">List of Attribute type to exclude</param>
Private Sub CopyValues(Source As T, Target As T, Optional ExcludedAttributeTypes As List(Of Type) = Nothing)
Dim oType As Type = GetType(T)
Dim oExcludedAttributeTypes = IIf(IsNothing(ExcludedAttributeTypes), New List(Of Type), ExcludedAttributeTypes)
Dim oProperties = oType.GetProperties().
Where(Function(p)
Return p.CanRead And p.CanWrite
End Function).
Where(Function(p)
For Each oAttributeType As Type In oExcludedAttributeTypes
If Attribute.IsDefined(p, oAttributeType) Then
Return False
End If
Next
Return True
End Function)
For Each oProperty As PropertyInfo In oProperties
Dim oValue = oProperty.GetValue(Source, Nothing)
If Not IsNothing(oValue) Then
oProperty.SetValue(Target, oValue, Nothing)
End If
Next
End Sub
''' <summary>
''' Filters a config object by copying all values except `ExcludedAttributeTypes`
''' </summary>
''' <param name="Data">Config object</param>
''' <param name="ExcludedAttributeTypes">List of Attribute type to exclude</param>
''' <returns></returns>
Private Function FilterValues(ByVal Data As T, ExcludedAttributeTypes As List(Of Type)) As T
Dim oResult As T = Activator.CreateInstance(Of T)
CopyValues(Data, oResult, ExcludedAttributeTypes)
Return oResult
End Function
Private Function LoadConfig() As T
' first create an empty/default config object
Dim oConfig = Activator.CreateInstance(_BlueprintType)
' try to load the special app config
oConfig = LoadAppConfig(oConfig)
' try to load the computer config
oConfig = LoadComputerConfig(oConfig)
' now try to load userconfig
oConfig = LoadUserConfig(oConfig)
Return oConfig
End Function
Private Function LoadAppConfig(ByVal Config As T) As T
If Not String.IsNullOrEmpty(_AppConfigPath) AndAlso System.IO.File.Exists(_AppConfigPath) Then
Try
Dim oAppConfig = ReadFromFile(_AppConfigPath)
CopyValues(oAppConfig, Config)
Catch ex As Exception
_Logger.Error(ex)
_Logger.Warn("ApplicationConfig could not be loaded!")
End Try
_WriteAllValuesToUserConfig = False
Else
_Logger.Debug("ApplicationConfig does not exist.")
_WriteAllValuesToUserConfig = True
End If
Return Config
End Function
Private Function LoadComputerConfig(ByVal Config As T) As T
If System.IO.File.Exists(_ComputerConfigPath) Then
Try
Dim oComputerConfig = ReadFromFile(_ComputerConfigPath)
CopyValues(oComputerConfig, Config)
Catch ex As Exception
_Logger.Error(ex)
_Logger.Warn("Computer config could not be loaded!")
End Try
_WriteAllValuesToUserConfig = False
Else
_Logger.Debug("Computer config does not exist.")
_WriteAllValuesToUserConfig = True
End If
Return Config
End Function
Private Function LoadUserConfig(ByVal Config As T) As T
If System.IO.File.Exists(_UserConfigPath) Then
Try
Dim oUserConfig = ReadFromFile(_UserConfigPath)
' if user config exists
If Not IsNothing(oUserConfig) Then
Dim oExcludedAttributes As New List(Of Type)
' Copy values from user config to final config
If _WriteAllValuesToUserConfig Then
CopyValues(oUserConfig, Config, New List(Of Type))
Else
CopyValues(oUserConfig, Config, _ExcludedAttributes)
End If
End If
Catch ex As Exception
_Logger.Error(ex)
_Logger.Warn("User config could not be loaded!")
End Try
Else
_Logger.Debug("User config does not exist.")
End If
Return Config
End Function
Private Function TestHasAttribute(Config As T, AttributeType As Type) As Boolean
For Each oProperty As PropertyInfo In Config.GetType.GetProperties()
If Attribute.IsDefined(oProperty, GetType(ConnectionStringAttribute)) Then
Return True
End If
Next
Return False
End Function
''' <summary>
''' Serialize a config object to byte array
''' </summary>
''' <param name="Data"></param>
''' <returns></returns>
Private Function Serialize(Data As T) As Byte()
Try
_Logger.Debug("Serializing config object")
Using oStream = New MemoryStream()
_Serializer.Serialize(oStream, Data)
Return oStream.ToArray()
End Using
Catch ex As Exception
_Logger.Error(ex)
Throw ex
End Try
End Function
''' <summary>
''' Write an object to disk as xml
''' </summary>
''' <param name="Data">The object to write</param>
''' <param name="Path">The file name to write to</param>
Private Sub WriteToFile(Data As T, Path As String, ForceAll As Boolean)
Try
_Logger.Debug("Saving config to: {0}", Path)
' If config was loaded from computer config,
' DO NOT save connection string, etc. to user config
If _WriteAllValuesToUserConfig = False And ForceAll = False Then
Data = FilterValues(Data, _ExcludedAttributes)
End If
Dim oBytes = Serialize(Data)
Using oFileStream = New FileStream(Path, FileMode.Create, FileAccess.Write)
oFileStream.Write(oBytes, 0, oBytes.Length)
oFileStream.Flush()
End Using
Catch ex As Exception
_Logger.Warn("Could not save config to {0}", Path)
_Logger.Error(ex)
Throw ex
End Try
End Sub
''' <summary>
''' Reads an xml from disk and deserializes to object
''' </summary>
''' <returns></returns>
Private Function ReadFromFile(Path As String) As T
Try
_Logger.Debug("Loading config from: {0}", Path)
Dim oConfig As T
Using oReader As New StreamReader(Path)
oConfig = _Serializer.Deserialize(oReader)
End Using
' If oConfig is Nothing, a config file was created but nothing was written to it.
' In this case we need to create oConfig from defaults so we have at least some config object
If oConfig Is Nothing Then
_Logger.Debug("Config file is valid but empty. Loading default values")
oConfig = Activator.CreateInstance(_BlueprintType)
End If
Return oConfig
Catch ex As Exception
_Logger.Warn("Could not load config from {0}", Path)
_Logger.Error(ex)
Throw ex
End Try
End Function
End Class

View File

@ -0,0 +1,267 @@
Imports System.IO
Imports System.Text.RegularExpressions
Imports DigitalData.Modules.Logging
''' <module>File</module>
''' <version>0.0.0.1</version>
''' <date>11.10.2018</date>
''' <summary>
''' Module that provides variouse File operations
''' </summary>
''' <dependencies>
''' NLog, >= 4.5.8
''' </dependencies>
''' <params>
''' LogConfig, DigitalData.Module.Logging.LogConfig
''' A LogConfig object
''' </params>
''' <props>
''' </props>
''' <example>
''' </example>
''' <remarks>
''' </remarks>
Public Class File
Private ReadOnly _logger As Logger
Private ReadOnly _logConfig As LogConfig
Private ReadOnly _invalidFilenameChars As String
Private ReadOnly _invalidPathChars As String
Private Const REGEX_CLEAN_FILENAME As String = "[\\/:""<>|\b\0\r\n\t]"
Private Const REGEX_CLEAN_PATH As String = "[:""<>|\b\0\r\n\t]"
Private Const FILE_NAME_ACCESS_TEST = "accessTest.txt"
Public Sub New(LogConfig As LogConfig)
_logConfig = LogConfig
_logger = LogConfig.GetLogger()
_invalidFilenameChars = String.Join("", Path.GetInvalidFileNameChars())
_invalidPathChars = String.Join("", Path.GetInvalidPathChars())
End Sub
Public Function GetCleanFilename(FileName As String) As String
_logger.Debug("Filename before cleaning: [{0}]", FileName)
Dim oCleanName As String = FileName
oCleanName = Regex.Replace(oCleanName, _invalidFilenameChars, String.Empty)
oCleanName = Regex.Replace(oCleanName, REGEX_CLEAN_FILENAME, String.Empty, RegexOptions.Singleline)
_logger.Debug("Filename after cleaning: [{0}]", oCleanName)
Return oCleanName
End Function
Public Function GetCleanPath(FilePath As String) As String
_logger.Debug("Path before cleaning: [{0}]", FilePath)
Dim oCleanName As String = FilePath
oCleanName = Regex.Replace(oCleanName, _invalidPathChars, String.Empty)
oCleanName = Regex.Replace(oCleanName, REGEX_CLEAN_PATH, String.Empty, RegexOptions.Singleline)
_logger.Debug("Path after cleaning: [{0}]", oCleanName)
Return oCleanName
End Function
''' <summary>
''' Adds fileversions to given filename `Destination` if that file already exists.
''' </summary>
''' <param name="Destination"></param>
''' <returns></returns>
Public Function GetVersionedFilename(Destination As String) As String
Try
Dim oFileName As String = Destination
Dim oFinalFileName = oFileName
Dim oDestinationDir = Path.GetDirectoryName(oFileName)
Dim oExtension = Path.GetExtension(oFileName)
Dim oVersionSeparator As Char = "~"c
Dim oFileVersion As Integer = Nothing
' Split Filename without extension at version separator to:
' - Check if file is already versioned
' - Get the file version of an already versioned file
'
' Example:
' test1.pdf --> test1 --> ['test1'] --> no fileversion
' test1~2.pdf --> test1~2 --> ['test1', '2'] --> version 2
' test1~12345~2.pdf --> test1~12345~2 --> ['test1', '12345', '2'] --> still version 2
Dim oFileNameWithoutExtension = Path.GetFileNameWithoutExtension(oFileName)
Dim oSplitFilename = oFileNameWithoutExtension.Split(oVersionSeparator).ToList()
' if file is already versioned, extract file version
' else just use the filename and set version to 1
If oSplitFilename.Count > 1 Then
Dim oVersion As Integer = 1
Try
oVersion = Integer.Parse(oSplitFilename.Last())
oFileNameWithoutExtension = String.Join("", oSplitFilename.Take(oSplitFilename.Count - 1))
Catch ex As Exception
' oFilenameWithoutExtension does NOT change
oFileNameWithoutExtension = oFileNameWithoutExtension
Finally
oFileVersion = oVersion
End Try
Else
oFileVersion = 1
End If
' while file exists, increment version
Do
oFinalFileName = Path.Combine(oDestinationDir, GetFilenameWithVersion(oFileNameWithoutExtension, oVersionSeparator, oFileVersion, oExtension))
_logger.Debug("Intermediate Filename is {0}", oFinalFileName)
_logger.Debug("File version: {0}", oFileVersion)
oFileVersion += 1
Loop While (IO.File.Exists(oFinalFileName))
_logger.Debug("Final Filename is {0}", oFinalFileName)
Return oFinalFileName
Catch ex As Exception
_logger.Warn("Filename {0} could not be versioned. Original filename will be returned!", Destination)
_logger.Error(ex)
Return Destination
End Try
End Function
Private Function GetFilenameWithVersion(FileNameWithoutExtension As String, VersionSeparator As Char, FileVersion As Integer, Extension As String) As String
If FileVersion <= 1 Then
Return $"{FileNameWithoutExtension}{Extension}"
Else
Return $"{FileNameWithoutExtension}{VersionSeparator}{FileVersion}{Extension}"
End If
End Function
''' <summary>
''' Removes files in a directory filtered by filename, extension and last write date
''' </summary>
''' <param name="Path">The directory in which files will be deleted</param>
''' <param name="FileKeepTime">Only delete files which are older than x days. Must be between 0 and 1000 days.</param>
''' <param name="FileBaseName">A filename filter which will be checked</param>
''' <param name="FileExtension">A file extension which will be checked</param>
''' <param name="ContinueOnError">Should the function continue with deleting when a file could not be deleted?</param>
''' <returns>True if all files were deleted or if no files were deleted, otherwise false</returns>
Public Function RemoveFiles(Path As String, FileKeepTime As Integer, FileBaseName As String, Optional FileExtension As String = "log", Optional ContinueOnError As Boolean = True) As Boolean
If Not TestPathIsDirectory(Path) Then
Throw New ArgumentException($"Path {Path} is not a directory!")
End If
If Not Directory.Exists(Path) Then
Throw New DirectoryNotFoundException($"Path {Path} does not exist!")
End If
If FileKeepTime < 0 Or FileKeepTime > 1000 Then
Throw New ArgumentOutOfRangeException("FileKeepTime must be an integer between 0 and 1000!")
End If
Dim oUnableToDeleteCounter = 0
Dim oDirectory As New DirectoryInfo(Path)
Dim oDateLimit As DateTime = DateTime.Now.AddDays(FileKeepTime)
Dim oFiles As List(Of FileInfo) = oDirectory.
EnumerateFiles($"*{FileBaseName}*").
Where(Function(oFileInfo As FileInfo)
Return oFileInfo.Extension = FileExtension And oFileInfo.LastWriteTime < oDateLimit
End Function)
If oFiles.Count = 0 Then
_logger.Debug("No files found that match the criterias.")
Return True
End If
_logger.Debug("Deleting old files (Found {0}).", oFiles.Count)
For Each oFile As FileInfo In oFiles
Try
oFile.Delete()
Catch ex As Exception
If ContinueOnError = False Then
_logger.Warn("Deleting files was aborted at file {0}.", oFile.FullName)
Return False
End If
oUnableToDeleteCounter = oUnableToDeleteCounter + 1
_logger.Warn("File {0} could not be deleted!")
End Try
Next
If oUnableToDeleteCounter > 0 Then
_logger.Debug("Old files partially removed. {0} files could not be removed.", oUnableToDeleteCounter)
Else
_logger.Debug("Old files removed.")
End If
Return True
End Function
<DebuggerStepThrough>
Public Sub MoveTo(FilePath As String, Directory As String)
Dim oFileInfo As New FileInfo(FilePath)
IO.File.Move(FilePath, Path.Combine(Directory, oFileInfo.Name))
End Sub
<DebuggerStepThrough>
Public Sub MoveTo(FilePath As String, NewFileName As String, Directory As String)
IO.File.Move(FilePath, Path.Combine(Directory, NewFileName))
End Sub
''' <summary>
''' Tries to create a directory and returns its path.
''' Returns a temp path if `DirectoryPath` can not be created or written to.
''' </summary>
''' <param name="DirectoryPath">The directory to create</param>
''' <param name="TestWriteAccess">Should a write access test be performed?</param>
''' <returns>The used path</returns>
Public Function CreateDirectory(DirectoryPath As String, Optional TestWriteAccess As Boolean = True) As String
Dim oFinalPath As String
If Directory.Exists(DirectoryPath) Then
_logger.Debug("Directory {0} already exists. Skipping.", DirectoryPath)
oFinalPath = DirectoryPath
Else
Try
Directory.CreateDirectory(DirectoryPath)
oFinalPath = DirectoryPath
Catch ex As Exception
_logger.Error(ex)
_logger.Warn("Directory {0} could not be created. Temp path will be used instead.", DirectoryPath)
oFinalPath = Path.GetTempPath()
End Try
End If
If TestWriteAccess AndAlso Not TestPathIsWritable(DirectoryPath) Then
_logger.Warn("Directory {0} is not writable. Temp path will be used instead.", DirectoryPath)
oFinalPath = Path.GetTempPath()
Else
oFinalPath = DirectoryPath
End If
_logger.Debug("Using path {0}", oFinalPath)
Return oFinalPath
End Function
Public Function TestPathIsWritable(DirectoryPath As String) As Boolean
Try
Dim fileAccessPath = Path.Combine(DirectoryPath, FILE_NAME_ACCESS_TEST)
Using fs As FileStream = IO.File.Create(fileAccessPath)
fs.WriteByte(0)
End Using
IO.File.Delete(fileAccessPath)
Return True
Catch ex As Exception
Return False
End Try
End Function
Public Function TestPathIsDirectory(Path As String) As Boolean
If Not Directory.Exists(Path) Then
Return False
End If
Dim oIsDirectory As Boolean = (System.IO.File.GetAttributes(Path) And FileAttributes.Directory) = FileAttributes.Directory
Return oIsDirectory
End Function
End Class

View File

@ -0,0 +1,455 @@
Imports System.IO
Imports System.Reflection
Imports NLog
Imports NLog.Config
Imports NLog.Targets
''' <module>LogConfig</module>
''' <version>0.0.1.0</version>
''' <date>02.10.2018</date>
''' <summary>
''' Module that writes file-logs to different locations:
''' local application data, the current directory or a custom path.
''' Files and directories will be automatically created.
''' </summary>
''' <dependencies>
''' NLog, >= 4.5.8
''' </dependencies>
''' <example>
''' Imports DigitalData.Modules.Logging
'''
''' Class FooProgram
''' Private Logger as Logger
''' Private LogConfig as LogConfig
'''
''' Public Sub New()
''' LogConfig = new LogConfig(args)
''' Logger = LogConfig.GetLogger()
''' End Sub
'''
''' Public Sub Bar()
''' Logger.Info("Baz")
''' End Sub
''' End Class
'''
''' Class FooLib
''' Private Logger as NLog.Logger
'''
''' Public Sub New(LogConfig as LogConfig)
''' Logger = LogConfig.GetLogger()
''' End Sub
'''
''' Public Sub Bar()
''' Logger.Info("Baz")
''' End Sub
''' End Class
''' </example>
''' <remarks>
''' If logpath can not be written to, falls back to temp folder as defined in:
''' https://docs.microsoft.com/de-de/dotnet/api/system.io.path.gettemppath?view=netframework-4.7.2
'''
''' If used in a service, LogPath must be set to CustomPath, otherwise the Log will be written to System32!
'''
''' For NLog Troubleshooting, set the following Environment variables to write the NLog internal Log:
''' - NLOG_INTERNAL_LOG_LEVEL: Debug
''' - NLOG_INTERNAL_LOG_FILE: ex. C:\Temp\Nlog_Internal.log
''' </remarks>
Public Class LogConfig
#Region "Private Properties"
Private Const OPEN_FILE_CACHE_TIMEOUT As Integer = 5
Private Const OPEN_FILE_FLUSH_TIMEOUT As Integer = 5
Private Const AUTO_FLUSH As Boolean = True
Private Const KEEP_FILES_OPEN As Boolean = False
Private Const KEEP_FILES_OPEN_DEBUG As Boolean = True
' MAX_ARCHIVES_FILES works like this (in version 4.5.8):
' 0 = keep ALL archives files
' 1 = only keep latest logfile and NO archive files
' n = keep n archive files
Private Const MAX_ARCHIVE_FILES_DEFAULT As Integer = 0
Private Const MAX_ARCHIVE_FILES_DEBUG_DETAIL As Integer = 0
Private Const ARCHIVE_EVERY As FileArchivePeriod = FileArchivePeriod.Day
Private Const FILE_NAME_FORMAT_DEFAULT As String = "${shortdate}-${var:product}${var:suffix}.log"
Private Const FILE_NAME_FORMAT_DEBUG As String = "${shortdate}-${var:product}${var:suffix}-Debug.log"
Private Const FILE_NAME_FORMAT_ERROR As String = "${shortdate}-${var:product}${var:suffix}-Error.log"
Private Const TARGET_DEFAULT As String = "defaultTarget"
Private Const TARGET_ERROR_EX As String = "errorExceptionTarget"
Private Const TARGET_ERROR As String = "errorTarget"
Private Const TARGET_DEBUG As String = "debugTarget"
Private Const TARGET_MEMORY As String = "memoryTarget"
Private Const DATE_FORMAT_LONG As String = "${longdate}"
Private Const DATE_FORMAT_DEFAULT As String = "${date:format=yyyy-MM-dd HH\:mm\:ss}"
Private Const LOG_FORMAT_BASE As String = DATE_FORMAT_DEFAULT & "|${logger:shortName=True}|${level:uppercase=true}"
Private Const LOG_FORMAT_BASE_LONG_DATE As String = DATE_FORMAT_LONG & "|${logger:shortName=True}|${level:uppercase=true}"
Private Const LOG_FORMAT_CALLSITE As String = "${callsite:className=false:fileName=true:includeSourcePath=false:methodName=true}"
Private Const LOG_FORMAT_DEFAULT As String = LOG_FORMAT_BASE & " >> ${message}"
Private Const LOG_FORMAT_EXCEPTION As String = LOG_FORMAT_BASE & " >> ${exception:format=Message}${newline}${exception:format=StackTrace}"
Private Const LOG_FORMAT_DEBUG As String = LOG_FORMAT_BASE_LONG_DATE & " >> " & LOG_FORMAT_CALLSITE & " -> ${message}"
Private Const LOG_FORMAT_MEMORY As String = LOG_FORMAT_BASE_LONG_DATE & " >> ${message}${newline}${exception:format=Message}${newline}${exception:format=StackTrace}"
Private Const FILE_NAME_ACCESS_TEST = "accessTest.txt"
Private Const FOLDER_NAME_LOG = "Log"
Private ReadOnly failSafePath As String = Path.GetTempPath()
Private ReadOnly basePath As String = failSafePath
Private config As LoggingConfiguration
Private isDebug As Boolean = False
#End Region
#Region "Public Properties"
Public Enum PathType As Integer
AppData = 0
CurrentDirectory = 1
CustomPath = 2
Temp = 3
End Enum
''' <summary>
''' Returns the NLog.LogFactory object that is used to create Loggers
''' </summary>
''' <returns>LogFactory object</returns>
Public ReadOnly Property LogFactory As LogFactory
''' <summary>
''' Returns the path to the current default logfile
''' </summary>
''' <returns>Filepath to the logfile</returns>
Public ReadOnly Property LogFile As String
''' <summary>
''' Returns the path to the current log directory
''' </summary>
''' <returns>Directory path to the log directory</returns>
Public ReadOnly Property LogDirectory As String
''' <summary>
''' Determines if a debug log will be written
''' </summary>
''' <returns>True, if debug log will be written. False otherwise.</returns>
Public Property Debug As Boolean
Get
Return isDebug
End Get
Set(isDebug As Boolean)
Me.isDebug = isDebug
'GetLogger().Debug("=> Debug is now {0}", isDebug)
ReloadConfig(isDebug)
End Set
End Property
''' <summary>
''' Returns Logs in Memory as List(Of String) if Debug is enabled
''' Returns an empty list if debug is disabled
''' </summary>
''' <returns>A list of log messages</returns>
Public ReadOnly Property Logs As List(Of String)
Get
Dim oTarget = config.FindTargetByName(Of MemoryTarget)(TARGET_MEMORY)
Return oTarget?.Logs.ToList()
End Get
End Property
Public ReadOnly Property NLogConfig As LoggingConfiguration
Get
Return config
End Get
End Property
#End Region
''' <summary>
''' Initializes a new LogConfig object with a logpath and optinally a filename-suffix.
''' </summary>
''' <param name="LogPath">The basepath to write logs to. Can be AppData, CurrentDirectory or CustomPath.</param>
''' <param name="CustomLogPath">If `logPath` is set to custom, this defines the custom logPath.</param>
''' <param name="Suffix">If set to anything other than Nothing, extends the logfile name with this suffix.</param>
''' <param name="CompanyName">CompanyName is used to construct log-path in when LogPath is set to PathType:AppData</param>
''' <param name="ProductName">ProductName is used to construct log-path in when LogPath is set to PathType:AppData</param>
Public Sub New(LogPath As PathType,
Optional CustomLogPath As String = Nothing,
Optional Suffix As String = Nothing,
Optional CompanyName As String = Nothing,
Optional ProductName As String = Nothing)
If LogPath = PathType.AppData And (ProductName Is Nothing Or CompanyName Is Nothing) Then
Throw New ArgumentException("Modules.Logging: PathType is AppData and either CompanyName or ProductName was not supplied!")
End If
If LogPath = PathType.CurrentDirectory Then
Throw New ArgumentException("Modules.Logging: LogPath.CurrentDirectory is deprecated. Please use LogPath.CustomPath!")
End If
If LogPath = PathType.AppData Then
Dim appDataDir = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)
basePath = Path.Combine(appDataDir, CompanyName, ProductName, FOLDER_NAME_LOG)
ElseIf LogPath = PathType.Temp Then
basePath = failSafePath
Else 'Custom Path
basePath = CustomLogPath
End If
' If directory does not exist, try to create it!
If Not Directory.Exists(basePath) Then
Try
Directory.CreateDirectory(basePath)
Catch ex As Exception
' If creation fails, use failSafe path
basePath = failSafePath
End Try
End If
' Try to create a file in `basePath` to check write permissions
Try
Dim fileAccessPath = Path.Combine(basePath, FILE_NAME_ACCESS_TEST)
Using fs As FileStream = System.IO.File.Create(fileAccessPath)
fs.WriteByte(0)
End Using
IO.File.Delete(fileAccessPath)
Catch ex As Exception
' If creation fails, use failSafe path
basePath = failSafePath
End Try
' Set the suffix to the given string if it exists
Dim logFileSuffix As String = String.Empty
If Suffix IsNot Nothing AndAlso Suffix.Count > 0 Then
logFileSuffix = $"-{Suffix}"
End If
Dim oProductName As String = "Main"
If ProductName IsNot Nothing Then
oProductName = ProductName
End If
' Create config object and initalize it
config = GetConfig(oProductName, logFileSuffix)
' Save config
LogFactory = New LogFactory With {
.Configuration = config
}
' Save log paths for files/directory
LogDirectory = basePath
LogFile = GetCurrentLogFilePath()
End Sub
Private Sub CheckMyApplication()
Dim oAssembly = Assembly.GetEntryAssembly()
Dim oMyApp = Nothing
For Each oType As Type In oAssembly.DefinedTypes
If oType.Name = "MyApplication" Then
oMyApp = oType
Exit For
End If
Next
oMyApp.GetType().GetProperty("")
End Sub
''' <summary>
''' Returns the Logger for the calling class
''' </summary>
''' <returns>An object of Logging.Logger</returns>
<DebuggerStepThrough()>
Public Function GetLogger() As Logger
Dim oClassName As String = GetClassFullName()
Return LogFactory.GetLogger(Of Logger)(oClassName)
End Function
''' <summary>
''' Returns the Logger for a class specified by `ClassName`
''' </summary>
''' <param name="ClassName">The name of the class the logger belongs to</param>
''' <returns>An object of Logging.Logger</returns>
<DebuggerStepThrough()>
Public Function GetLogger(ClassName As String) As Logger
Return LogFactory.GetLogger(Of Logger)(ClassName)
End Function
''' <summary>
''' Clears the internal log
''' </summary>
Public Sub ClearLogs()
Dim oTarget = config.FindTargetByName(Of MemoryTarget)(TARGET_MEMORY)
oTarget?.Logs.Clear()
End Sub
''' <summary>
''' Gets the fully qualified name of the class invoking the calling method,
''' including the namespace but Not the assembly.
''' </summary>
''' <returns>The fully qualified class name</returns>
''' <remarks>This method is very resource-intensive!</remarks>
<DebuggerStepThrough()>
Public Shared Function GetClassFullName() As String
Dim oFramesToSkip As Integer = 2
Dim oClassName As String = String.Empty
Dim oStackTrace = Environment.StackTrace
Dim oStackTraceLines = oStackTrace.Replace(vbCr, "").Split({vbLf}, StringSplitOptions.RemoveEmptyEntries)
For i As Integer = 0 To oStackTraceLines.Length - 1
Dim oCallingClassAndMethod = oStackTraceLines(i).Split({" ", "<>", "(", ")"}, StringSplitOptions.RemoveEmptyEntries)(1)
Dim oMethodStartIndex As Integer = oCallingClassAndMethod.LastIndexOf(".", StringComparison.Ordinal)
If oMethodStartIndex > 0 Then
Dim oCallingClass = oCallingClassAndMethod.Substring(0, oMethodStartIndex)
oClassName = oCallingClass.TrimEnd("."c)
If Not oClassName.StartsWith("System.Environment") AndAlso oFramesToSkip <> 0 Then
i += oFramesToSkip - 1
oFramesToSkip = 0
Continue For
End If
If Not oClassName.StartsWith("System.") Then Exit For
End If
Next
Return oClassName
End Function
''' <summary>
''' Returns the initial log configuration
''' </summary>
''' <param name="productName">The chosen productname</param>
''' <param name="logFileSuffix">The chosen suffix</param>
''' <returns>A NLog.LoggingConfiguration object</returns>
Private Function GetConfig(productName As String, logFileSuffix As String) As LoggingConfiguration
config = New LoggingConfiguration()
config.Variables("product") = productName
config.Variables("suffix") = logFileSuffix
' Add default targets
config.AddTarget(TARGET_ERROR_EX, GetErrorExceptionLogTarget(basePath))
config.AddTarget(TARGET_ERROR, GetErrorLogTarget(basePath))
config.AddTarget(TARGET_DEFAULT, GetDefaultLogTarget(basePath))
config.AddTarget(TARGET_DEBUG, GetDebugLogTarget(basePath))
config.AddTarget(TARGET_MEMORY, GetMemoryDebugTarget())
' Add default rules
AddDefaultRules(config)
Return config
End Function
''' <summary>
''' Adds the default rules
''' </summary>
''' <param name="config">A NLog.LoggingConfiguration object</param>
Private Sub AddDefaultRules(ByRef config As LoggingConfiguration)
config.AddRuleForOneLevel(LogLevel.Error, TARGET_ERROR_EX)
config.AddRuleForOneLevel(LogLevel.Fatal, TARGET_ERROR_EX)
config.AddRuleForOneLevel(LogLevel.Warn, TARGET_ERROR)
config.AddRuleForOneLevel(LogLevel.Warn, TARGET_DEFAULT)
config.AddRuleForOneLevel(LogLevel.Info, TARGET_DEFAULT)
End Sub
''' <summary>
''' Returns the full path of the current default log file.
''' </summary>
''' <returns>Full path of the current default log file</returns>
Private Function GetCurrentLogFilePath()
Dim logEventInfo As New LogEventInfo() With {.TimeStamp = Date.Now}
Dim target As FileTarget = config.FindTargetByName(TARGET_DEFAULT)
Dim fileName As String = target.FileName.Render(logEventInfo)
Return fileName
End Function
''' <summary>
''' Reconfigures and re-adds all loggers, optionally adding the debug rule.
''' </summary>
''' <param name="Debug">Adds the Debug rule if true.</param>
Private Sub ReloadConfig(Optional Debug As Boolean = False)
' Clear Logging Rules
config.LoggingRules.Clear()
' Add default rules
AddDefaultRules(config)
' Add debug rule, if configured
If Debug Then
config.AddRuleForOneLevel(LogLevel.Debug, TARGET_DEBUG)
config.AddRuleForAllLevels(TARGET_MEMORY)
End If
' Reload all running loggers
LogFactory.ReconfigExistingLoggers()
End Sub
#Region "Log Targets"
Private Function GetDefaultLogTarget(basePath As String) As FileTarget
Dim defaultLog As New FileTarget() With {
.FileName = Path.Combine(basePath, FILE_NAME_FORMAT_DEFAULT),
.Name = TARGET_DEFAULT,
.Layout = LOG_FORMAT_DEFAULT,
.MaxArchiveFiles = MAX_ARCHIVE_FILES_DEFAULT,
.ArchiveEvery = ARCHIVE_EVERY,
.KeepFileOpen = KEEP_FILES_OPEN
}
Return defaultLog
End Function
Private Function GetErrorExceptionLogTarget(basePath As String) As FileTarget
Dim errorLogWithExceptions As New FileTarget() With {
.FileName = Path.Combine(basePath, FILE_NAME_FORMAT_ERROR),
.Name = TARGET_ERROR_EX,
.Layout = LOG_FORMAT_EXCEPTION,
.MaxArchiveFiles = MAX_ARCHIVE_FILES_DEFAULT,
.ArchiveEvery = ARCHIVE_EVERY,
.KeepFileOpen = KEEP_FILES_OPEN
}
Return errorLogWithExceptions
End Function
Private Function GetErrorLogTarget(basePath As String) As FileTarget
Dim errorLog As New FileTarget() With {
.FileName = Path.Combine(basePath, FILE_NAME_FORMAT_ERROR),
.Name = TARGET_ERROR,
.Layout = LOG_FORMAT_DEFAULT,
.MaxArchiveFiles = MAX_ARCHIVE_FILES_DEFAULT,
.ArchiveEvery = ARCHIVE_EVERY,
.KeepFileOpen = KEEP_FILES_OPEN
}
Return errorLog
End Function
Private Function GetDebugLogTarget(basePath As String) As FileTarget
Dim debugLog As New FileTarget() With {
.FileName = Path.Combine(basePath, FILE_NAME_FORMAT_DEBUG),
.Name = TARGET_DEBUG,
.Layout = LOG_FORMAT_DEBUG,
.MaxArchiveFiles = MAX_ARCHIVE_FILES_DEBUG_DETAIL,
.ArchiveEvery = ARCHIVE_EVERY,
.KeepFileOpen = KEEP_FILES_OPEN_DEBUG,
.OpenFileCacheTimeout = OPEN_FILE_CACHE_TIMEOUT,
.AutoFlush = AUTO_FLUSH,
.OpenFileFlushTimeout = OPEN_FILE_FLUSH_TIMEOUT
}
Return debugLog
End Function
Private Function GetMemoryDebugTarget() As MemoryTarget
Dim memoryLog As New MemoryTarget() With {
.Layout = LOG_FORMAT_MEMORY,
.Name = TARGET_MEMORY,
.OptimizeBufferReuse = True
}
Return memoryLog
End Function
#End Region
End Class

View File

@ -0,0 +1,28 @@
Imports NLog
Public Class Logger
Inherits NLog.Logger
Implements ILogger
''' <summary>
''' Prints a preformatted Block including a block identifier
''' </summary>
''' <param name="blockId">A unique Identifier for this block, eg. DocId, FullPath, ..</param>
<DebuggerStepThrough()>
Public Sub NewBlock(blockId As String)
Dim message As String = $"-----> Start of Block {blockId}"
Dim logEventInfo As New LogEventInfo(LogLevel.Info, Name, message)
Dim WrapperType As Type = GetType(Logger)
Log(WrapperType, logEventInfo)
End Sub
<DebuggerStepThrough()>
Public Sub EndBlock()
Dim message As String = $"<----- End of Block"
Dim logEventInfo As New LogEventInfo(LogLevel.Info, Name, message)
Dim WrapperType As Type = GetType(Logger)
Log(WrapperType, logEventInfo)
End Sub
End Class

View File

@ -0,0 +1,38 @@
'------------------------------------------------------------------------------
' <auto-generated>
' This code was generated by a tool.
' Runtime Version:4.0.30319.42000
'
' Changes to this file may cause incorrect behavior and will be lost if
' the code is regenerated.
' </auto-generated>
'------------------------------------------------------------------------------
Option Strict On
Option Explicit On
Namespace My
'NOTE: This file is auto-generated; do not modify it directly. To make changes,
' or if you encounter build errors in this file, go to the Project Designer
' (go to Project Properties or double-click the My Project node in
' Solution Explorer), and make changes on the Application tab.
'
Partial Friend Class MyApplication
<Global.System.Diagnostics.DebuggerStepThroughAttribute()> _
Public Sub New()
MyBase.New(Global.Microsoft.VisualBasic.ApplicationServices.AuthenticationMode.Windows)
Me.IsSingleInstance = false
Me.EnableVisualStyles = true
Me.SaveMySettingsOnExit = true
Me.ShutDownStyle = Global.Microsoft.VisualBasic.ApplicationServices.ShutdownMode.AfterMainFormCloses
End Sub
<Global.System.Diagnostics.DebuggerStepThroughAttribute()> _
Protected Overrides Sub OnCreateMainForm()
Me.MainForm = Global.WinLineArtikelnummerGenerator.frmMain
End Sub
End Class
End Namespace

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<MyApplicationData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<MySubMain>true</MySubMain>
<MainForm>Form1</MainForm>
<SingleInstance>false</SingleInstance>
<ShutdownMode>0</ShutdownMode>
<EnableVisualStyles>true</EnableVisualStyles>
<AuthenticationMode>0</AuthenticationMode>
<ApplicationType>0</ApplicationType>
<SaveMySettingsOnExit>true</SaveMySettingsOnExit>
</MyApplicationData>

View File

@ -0,0 +1,35 @@
Imports System
Imports System.Reflection
Imports System.Runtime.InteropServices
' Allgemeine Informationen über eine Assembly werden über die folgenden
' Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
' die einer Assembly zugeordnet sind.
' Werte der Assemblyattribute überprüfen
<Assembly: AssemblyTitle("WinLineProductNumberGenerator")>
<Assembly: AssemblyDescription("")>
<Assembly: AssemblyCompany("Digital Data")>
<Assembly: AssemblyProduct("WinLineProductNumberGenerator")>
<Assembly: AssemblyCopyright("Copyright © 2020")>
<Assembly: AssemblyTrademark("")>
<Assembly: ComVisible(False)>
'Die folgende GUID wird für die typelib-ID verwendet, wenn dieses Projekt für COM verfügbar gemacht wird.
<Assembly: Guid("aa20b96c-2e50-401e-8d60-c479898105f9")>
' Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
'
' Hauptversion
' Nebenversion
' Buildnummer
' Revision
'
' Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden,
' indem Sie "*" wie unten gezeigt eingeben:
' <Assembly: AssemblyVersion("1.0.*")>
<Assembly: AssemblyVersion("1.0.0.0")>
<Assembly: AssemblyFileVersion("1.0.0.0")>

View File

@ -0,0 +1,62 @@
'------------------------------------------------------------------------------
' <auto-generated>
' This code was generated by a tool.
' Runtime Version:4.0.30319.42000
'
' Changes to this file may cause incorrect behavior and will be lost if
' the code is regenerated.
' </auto-generated>
'------------------------------------------------------------------------------
Option Strict On
Option Explicit On
Namespace My.Resources
'This class was auto-generated by the StronglyTypedResourceBuilder
'class via a tool like ResGen or Visual Studio.
'To add or remove a member, edit your .ResX file then rerun ResGen
'with the /str option, or rebuild your VS project.
'''<summary>
''' A strongly-typed resource class, for looking up localized strings, etc.
'''</summary>
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0"), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _
Friend Module Resources
Private resourceMan As Global.System.Resources.ResourceManager
Private resourceCulture As Global.System.Globalization.CultureInfo
'''<summary>
''' Returns the cached ResourceManager instance used by this class.
'''</summary>
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager
Get
If Object.ReferenceEquals(resourceMan, Nothing) Then
Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("WinLineArtikelnummerGenerator.Resources", GetType(Resources).Assembly)
resourceMan = temp
End If
Return resourceMan
End Get
End Property
'''<summary>
''' Overrides the current thread's CurrentUICulture property for all
''' resource lookups using this strongly typed resource class.
'''</summary>
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Friend Property Culture() As Global.System.Globalization.CultureInfo
Get
Return resourceCulture
End Get
Set(ByVal value As Global.System.Globalization.CultureInfo)
resourceCulture = value
End Set
End Property
End Module
End Namespace

View File

@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,96 @@
'------------------------------------------------------------------------------
' <auto-generated>
' Dieser Code wurde von einem Tool generiert.
' Laufzeitversion:4.0.30319.42000
'
' Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
' der Code erneut generiert wird.
' </auto-generated>
'------------------------------------------------------------------------------
Option Strict On
Option Explicit On
Namespace My
<Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.4.0.0"), _
Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Partial Friend NotInheritable Class MySettings
Inherits Global.System.Configuration.ApplicationSettingsBase
Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings()),MySettings)
#Region "Automatische My.Settings-Speicherfunktion"
#If _MyType = "WindowsForms" Then
Private Shared addedHandler As Boolean
Private Shared addedHandlerLockObject As New Object
<Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Private Shared Sub AutoSaveSettings(sender As Global.System.Object, e As Global.System.EventArgs)
If My.Application.SaveMySettingsOnExit Then
My.Settings.Save()
End If
End Sub
#End If
#End Region
Public Shared ReadOnly Property [Default]() As MySettings
Get
#If _MyType = "WindowsForms" Then
If Not addedHandler Then
SyncLock addedHandlerLockObject
If Not addedHandler Then
AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings
addedHandler = True
End If
End SyncLock
End If
#End If
Return defaultInstance
End Get
End Property
<Global.System.Configuration.UserScopedSettingAttribute(), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Configuration.DefaultSettingValueAttribute("")> _
Public Property ConnectionString() As String
Get
Return CType(Me("ConnectionString"),String)
End Get
Set
Me("ConnectionString") = value
End Set
End Property
<Global.System.Configuration.ApplicationScopedSettingAttribute(), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Configuration.SpecialSettingAttribute(Global.System.Configuration.SpecialSetting.ConnectionString), _
Global.System.Configuration.DefaultSettingValueAttribute("Data Source=SDD-VMP04-SQL17\MEDACOM;Initial Catalog=CWLDATEN_MEDS;User ID=sa;Pass"& _
"word=dd")> _
Public ReadOnly Property MyConnectionString() As String
Get
Return CType(Me("MyConnectionString"),String)
End Get
End Property
End Class
End Namespace
Namespace My
<Global.Microsoft.VisualBasic.HideModuleNameAttribute(), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute()> _
Friend Module MySettingsProperty
<Global.System.ComponentModel.Design.HelpKeywordAttribute("My.Settings")> _
Friend ReadOnly Property Settings() As Global.WinLineArtikelnummerGenerator.My.MySettings
Get
Return Global.WinLineArtikelnummerGenerator.My.MySettings.Default
End Get
End Property
End Module
End Namespace

View File

@ -0,0 +1,17 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="My" GeneratedClassName="MySettings" UseMySettingsClassName="true">
<Profiles />
<Settings>
<Setting Name="ConnectionString" Type="System.String" Scope="User">
<Value Profile="(Default)" />
</Setting>
<Setting Name="MyConnectionString" Type="(Connection string)" Scope="Application">
<DesignTimeValue Profile="(Default)">&lt;?xml version="1.0" encoding="utf-16"?&gt;
&lt;SerializableConnectionString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;
&lt;ConnectionString&gt;Data Source=SDD-VMP04-SQL17\MEDACOM;Initial Catalog=CWLDATEN_MEDS;User ID=sa;Password=dd&lt;/ConnectionString&gt;
&lt;ProviderName&gt;System.Data.SqlClient&lt;/ProviderName&gt;
&lt;/SerializableConnectionString&gt;</DesignTimeValue>
<Value Profile="(Default)">Data Source=SDD-VMP04-SQL17\MEDACOM;Initial Catalog=CWLDATEN_MEDS;User ID=sa;Password=dd</Value>
</Setting>
</Settings>
</SettingsFile>

View File

@ -0,0 +1,2 @@
DevExpress.XtraGrid.GridControl, DevExpress.XtraGrid.v20.1, Version=20.1.3.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
DevExpress.XtraBars.Ribbon.RibbonControl, DevExpress.XtraBars.v20.1, Version=20.1.3.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a

View File

@ -0,0 +1,186 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{BA171D0B-6421-4294-B5DC-BF77D93C91E7}</ProjectGuid>
<OutputType>WinExe</OutputType>
<StartupObject>WinLineArtikelnummerGenerator.My.MyApplication</StartupObject>
<RootNamespace>WinLineArtikelnummerGenerator</RootNamespace>
<AssemblyName>WinLineArtikelnummerGenerator</AssemblyName>
<FileAlignment>512</FileAlignment>
<MyType>WindowsForms</MyType>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<DefineDebug>true</DefineDebug>
<DefineTrace>true</DefineTrace>
<OutputPath>bin\Debug\</OutputPath>
<DocumentationFile>WinLineArtikelnummerGenerator.xml</DocumentationFile>
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<DefineDebug>false</DefineDebug>
<DefineTrace>true</DefineTrace>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DocumentationFile>WinLineArtikelnummerGenerator.xml</DocumentationFile>
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
</PropertyGroup>
<PropertyGroup>
<OptionExplicit>On</OptionExplicit>
</PropertyGroup>
<PropertyGroup>
<OptionCompare>Binary</OptionCompare>
</PropertyGroup>
<PropertyGroup>
<OptionStrict>Off</OptionStrict>
</PropertyGroup>
<PropertyGroup>
<OptionInfer>On</OptionInfer>
</PropertyGroup>
<ItemGroup>
<Reference Include="DevExpress.Data.Desktop.v20.1, Version=20.1.3.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<Reference Include="DevExpress.Data.v20.1, Version=20.1.3.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<Reference Include="DevExpress.Printing.v20.1.Core, Version=20.1.3.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<Reference Include="DevExpress.Sparkline.v20.1.Core, Version=20.1.3.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<Reference Include="DevExpress.Utils.v20.1, Version=20.1.3.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<Reference Include="DevExpress.XtraBars.v20.1, Version=20.1.3.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a, processorArchitecture=MSIL" />
<Reference Include="DevExpress.XtraEditors.v20.1, Version=20.1.3.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a, processorArchitecture=MSIL" />
<Reference Include="DevExpress.XtraGrid.v20.1, Version=20.1.3.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a, processorArchitecture=MSIL" />
<Reference Include="DevExpress.XtraLayout.v20.1, Version=20.1.3.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<Reference Include="DevExpress.XtraPrinting.v20.1, Version=20.1.3.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<Reference Include="DigitalData.Modules.Config">
<HintPath>..\..\DDMonorepo\Modules.Config\bin\Debug\DigitalData.Modules.Config.dll</HintPath>
</Reference>
<Reference Include="DigitalData.Modules.Database">
<HintPath>..\..\DDMonorepo\Modules.Database\bin\Debug\DigitalData.Modules.Database.dll</HintPath>
</Reference>
<Reference Include="DigitalData.Modules.Filesystem">
<HintPath>..\..\DDMonorepo\Modules.Filesystem\bin\Debug\DigitalData.Modules.Filesystem.dll</HintPath>
</Reference>
<Reference Include="DigitalData.Modules.Language">
<HintPath>..\..\DDMonorepo\Modules.Language\bin\Debug\DigitalData.Modules.Language.dll</HintPath>
</Reference>
<Reference Include="DigitalData.Modules.Logging">
<HintPath>..\..\DDMonorepo\Modules.Logging\bin\Debug\DigitalData.Modules.Logging.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.7.4\lib\net45\NLog.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Configuration" />
<Reference Include="System.Data" />
<Reference Include="System.Data.Linq" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.IO.Compression" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.ServiceModel" />
<Reference Include="System.Transactions" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Net.Http" />
</ItemGroup>
<ItemGroup>
<Import Include="Microsoft.VisualBasic" />
<Import Include="System" />
<Import Include="System.Collections" />
<Import Include="System.Collections.Generic" />
<Import Include="System.Data" />
<Import Include="System.Drawing" />
<Import Include="System.Diagnostics" />
<Import Include="System.Windows.Forms" />
<Import Include="System.Linq" />
<Import Include="System.Xml.Linq" />
<Import Include="System.Threading.Tasks" />
</ItemGroup>
<ItemGroup>
<Compile Include="Config.vb" />
<Compile Include="Modules\ConfigManager.vb" />
<Compile Include="CWLDATEN_MEDSDataSet.Designer.vb">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>CWLDATEN_MEDSDataSet.xsd</DependentUpon>
</Compile>
<Compile Include="frmMain.Designer.vb">
<DependentUpon>frmMain.vb</DependentUpon>
</Compile>
<Compile Include="frmMain.vb">
<SubType>Form</SubType>
</Compile>
<Compile Include="Modules\File.vb" />
<Compile Include="Modules\LogConfig.vb" />
<Compile Include="Models\Article.vb" />
<Compile Include="Models\ProductGroup.vb" />
<Compile Include="Models\ProductVersion.vb" />
<Compile Include="Modules\Logger.vb" />
<Compile Include="My Project\AssemblyInfo.vb" />
<Compile Include="My Project\Application.Designer.vb">
<AutoGen>True</AutoGen>
<DependentUpon>Application.myapp</DependentUpon>
</Compile>
<Compile Include="My Project\Resources.Designer.vb">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="My Project\Settings.Designer.vb">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<Compile Include="Models\Vendor.vb" />
<Compile Include="Database.vb" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="frmMain.resx">
<DependentUpon>frmMain.vb</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="My Project\licenses.licx" />
<EmbeddedResource Include="My Project\Resources.resx">
<Generator>VbMyResourcesResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.vb</LastGenOutput>
<CustomToolNamespace>My.Resources</CustomToolNamespace>
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Include="CWLDATEN_MEDSDataSet.xsc">
<DependentUpon>CWLDATEN_MEDSDataSet.xsd</DependentUpon>
</None>
<None Include="CWLDATEN_MEDSDataSet.xsd">
<Generator>MSDataSetGenerator</Generator>
<LastGenOutput>CWLDATEN_MEDSDataSet.Designer.vb</LastGenOutput>
<SubType>Designer</SubType>
</None>
<None Include="CWLDATEN_MEDSDataSet.xss">
<DependentUpon>CWLDATEN_MEDSDataSet.xsd</DependentUpon>
</None>
<None Include="My Project\Application.myapp">
<Generator>MyApplicationCodeGenerator</Generator>
<LastGenOutput>Application.Designer.vb</LastGenOutput>
</None>
<None Include="My Project\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<CustomToolNamespace>My</CustomToolNamespace>
<LastGenOutput>Settings.Designer.vb</LastGenOutput>
</None>
<None Include="App.config" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
</Project>

View File

@ -0,0 +1,161 @@
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class frmMain
Inherits System.Windows.Forms.Form
'Das Formular überschreibt den Löschvorgang, um die Komponentenliste zu bereinigen.
<System.Diagnostics.DebuggerNonUserCode()> _
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
'Wird vom Windows Form-Designer benötigt.
Private components As System.ComponentModel.IContainer
'Hinweis: Die folgende Prozedur ist für den Windows Form-Designer erforderlich.
'Das Bearbeiten ist mit dem Windows Form-Designer möglich.
'Das Bearbeiten mit dem Code-Editor ist nicht möglich.
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
Me.listboxVendors = New System.Windows.Forms.ListBox()
Me.listboxProductGroups = New System.Windows.Forms.ListBox()
Me.Label1 = New System.Windows.Forms.Label()
Me.Label2 = New System.Windows.Forms.Label()
Me.Button1 = New System.Windows.Forms.Button()
Me.Button2 = New System.Windows.Forms.Button()
Me.listBoxProductVersion = New System.Windows.Forms.ListBox()
Me.Button3 = New System.Windows.Forms.Button()
Me.Label3 = New System.Windows.Forms.Label()
Me.SuspendLayout()
'
'listboxVendors
'
Me.listboxVendors.Font = New System.Drawing.Font("Consolas", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
Me.listboxVendors.FormattingEnabled = True
Me.listboxVendors.ItemHeight = 15
Me.listboxVendors.Location = New System.Drawing.Point(12, 67)
Me.listboxVendors.Margin = New System.Windows.Forms.Padding(3, 4, 3, 4)
Me.listboxVendors.Name = "listboxVendors"
Me.listboxVendors.Size = New System.Drawing.Size(327, 244)
Me.listboxVendors.TabIndex = 0
'
'listboxProductGroups
'
Me.listboxProductGroups.Font = New System.Drawing.Font("Consolas", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
Me.listboxProductGroups.FormattingEnabled = True
Me.listboxProductGroups.ItemHeight = 15
Me.listboxProductGroups.Location = New System.Drawing.Point(345, 67)
Me.listboxProductGroups.Margin = New System.Windows.Forms.Padding(3, 4, 3, 4)
Me.listboxProductGroups.Name = "listboxProductGroups"
Me.listboxProductGroups.Size = New System.Drawing.Size(327, 244)
Me.listboxProductGroups.TabIndex = 0
'
'Label1
'
Me.Label1.AutoSize = True
Me.Label1.Font = New System.Drawing.Font("Segoe UI Semibold", 9.0!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
Me.Label1.Location = New System.Drawing.Point(9, 18)
Me.Label1.Name = "Label1"
Me.Label1.Size = New System.Drawing.Size(69, 15)
Me.Label1.TabIndex = 1
Me.Label1.Text = "Lieferanten:"
'
'Label2
'
Me.Label2.AutoSize = True
Me.Label2.Font = New System.Drawing.Font("Segoe UI Semibold", 9.0!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
Me.Label2.Location = New System.Drawing.Point(342, 18)
Me.Label2.Name = "Label2"
Me.Label2.Size = New System.Drawing.Size(97, 15)
Me.Label2.TabIndex = 1
Me.Label2.Text = "Produktgruppen:"
'
'Button1
'
Me.Button1.Location = New System.Drawing.Point(345, 36)
Me.Button1.Name = "Button1"
Me.Button1.Size = New System.Drawing.Size(140, 23)
Me.Button1.TabIndex = 2
Me.Button1.TabStop = False
Me.Button1.Text = "Neue Produktgruppe"
Me.Button1.UseVisualStyleBackColor = True
'
'Button2
'
Me.Button2.Location = New System.Drawing.Point(12, 37)
Me.Button2.Name = "Button2"
Me.Button2.Size = New System.Drawing.Size(140, 23)
Me.Button2.TabIndex = 2
Me.Button2.TabStop = False
Me.Button2.Text = "Neuer Lieferant"
Me.Button2.UseVisualStyleBackColor = True
'
'listBoxProductVersion
'
Me.listBoxProductVersion.Font = New System.Drawing.Font("Consolas", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
Me.listBoxProductVersion.FormattingEnabled = True
Me.listBoxProductVersion.ItemHeight = 15
Me.listBoxProductVersion.Location = New System.Drawing.Point(678, 67)
Me.listBoxProductVersion.Margin = New System.Windows.Forms.Padding(3, 4, 3, 4)
Me.listBoxProductVersion.Name = "listBoxProductVersion"
Me.listBoxProductVersion.Size = New System.Drawing.Size(327, 244)
Me.listBoxProductVersion.TabIndex = 0
'
'Button3
'
Me.Button3.Location = New System.Drawing.Point(678, 36)
Me.Button3.Name = "Button3"
Me.Button3.Size = New System.Drawing.Size(140, 23)
Me.Button3.TabIndex = 2
Me.Button3.TabStop = False
Me.Button3.Text = "Neue Produktversion"
Me.Button3.UseVisualStyleBackColor = True
'
'Label3
'
Me.Label3.AutoSize = True
Me.Label3.Font = New System.Drawing.Font("Segoe UI Semibold", 9.0!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
Me.Label3.Location = New System.Drawing.Point(675, 18)
Me.Label3.Name = "Label3"
Me.Label3.Size = New System.Drawing.Size(90, 15)
Me.Label3.TabIndex = 1
Me.Label3.Text = "Produktversion:"
'
'frmMain
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(7.0!, 15.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(1105, 430)
Me.Controls.Add(Me.Button2)
Me.Controls.Add(Me.Button3)
Me.Controls.Add(Me.Button1)
Me.Controls.Add(Me.Label3)
Me.Controls.Add(Me.Label2)
Me.Controls.Add(Me.Label1)
Me.Controls.Add(Me.listBoxProductVersion)
Me.Controls.Add(Me.listboxProductGroups)
Me.Controls.Add(Me.listboxVendors)
Me.Font = New System.Drawing.Font("Segoe UI", 9.0!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
Me.Margin = New System.Windows.Forms.Padding(3, 4, 3, 4)
Me.Name = "frmMain"
Me.Text = "frmMain"
Me.ResumeLayout(False)
Me.PerformLayout()
End Sub
Friend WithEvents listboxVendors As ListBox
Friend WithEvents listboxProductGroups As ListBox
Friend WithEvents Label1 As Label
Friend WithEvents Label2 As Label
Friend WithEvents Button1 As Button
Friend WithEvents Button2 As Button
Friend WithEvents listBoxProductVersion As ListBox
Friend WithEvents Button3 As Button
Friend WithEvents Label3 As Label
End Class

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,60 @@
Public Class frmMain
Private _Logger As Logger
Private _LogConfig As LogConfig
Private _Config As ConfigManager(Of Config)
Private _Database As Database
Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
_LogConfig = New LogConfig(LogPath:=LogConfig.PathType.AppData, CompanyName:="Digital Data", ProductName:="WinLineProductNumberGenerator")
_Logger = _LogConfig.GetLogger()
_Config = New ConfigManager(Of Config)(_LogConfig, Application.UserAppDataPath)
_Database = New Database(_LogConfig, _Config)
listboxVendors.DataSource = Nothing
Dim oVendorDT = _Database.LoadVendors()
Dim oVendors = New List(Of Vendor)
listboxVendors.DataSource = oVendorDT
listboxVendors.DisplayMember = "c003"
listboxVendors.ValueMember = "c229"
End Sub
Private Sub frmMain_FormClosed(sender As Object, e As FormClosedEventArgs) Handles Me.FormClosed
_Config.Save()
End Sub
Private Sub listboxVendors_SelectedIndexChanged(sender As Object, e As EventArgs) Handles listboxVendors.SelectedIndexChanged
If listboxVendors.SelectedIndex >= 0 Then
Dim oVendor As DataRowView = listboxVendors.SelectedItem()
Dim oVendorCode = oVendor.Item("C229")
Dim oVendorId = _Database.LoadVendorIdByCode(oVendorCode)
listboxProductGroups.DataSource = Nothing
If oVendorId Is Nothing Then
_Logger.Warn("VendorId does not match any 'Artikeluntergruppen'.")
Exit Sub
End If
Dim oGroups = _Database.LoadGroupsByVendor(oVendorId)
listboxProductGroups.DataSource = oGroups
listboxProductGroups.DisplayMember = "C001"
listboxProductGroups.ValueMember = "C999"
End If
End Sub
Private Sub listboxProductGroups_SelectedIndexChanged(sender As Object, e As EventArgs) Handles listboxProductGroups.SelectedIndexChanged
If listboxProductGroups.SelectedIndex >= 0 Then
Dim oVendor As DataRowView = listboxVendors.SelectedItem()
Dim oGroup As DataRowView = listboxProductGroups.SelectedItem()
Dim oVendorCode = oVendor.Item("C229")
Dim oVendorId = _Database.LoadVendorIdByCode(oVendorCode)
Dim oGroupId = oGroup.Item("C999")
Dim Versions = _Database.LoadVersionsByVendorAndGroup(oVendorId, oGroupId)
End If
End Sub
End Class

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="NLog" version="4.7.4" targetFramework="net472" />
</packages>