Compare commits
298 Commits
222176dfca
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 32015e5439 | |||
|
|
ceb688fc3f | ||
|
|
aa5742a529 | ||
|
|
79267e6bd9 | ||
|
|
cf63fd8c39 | ||
|
|
ec3a677ca8 | ||
|
|
48406884ca | ||
| 204aaaeb4e | |||
| ec378ba3b4 | |||
| 35b19cde82 | |||
|
|
f7c0a29676 | ||
| 9ae5465c48 | |||
| 82139fc30d | |||
| f4ba4d9e1d | |||
| 0aabc12f49 | |||
| adbd0fe99b | |||
| 2d6a2df48a | |||
| e7ccb74828 | |||
| 05355c93a5 | |||
| 2007bb91f3 | |||
| d7d2ecf8a0 | |||
| 447c7ea600 | |||
| 32bb14db06 | |||
| a5226a8101 | |||
| b534c4c799 | |||
| dc80138311 | |||
| 477bb511c4 | |||
| 0b66b80591 | |||
| 5fd924d413 | |||
| e8ebc30225 | |||
| 262805d112 | |||
| 623807c55d | |||
| aee7997cb3 | |||
| 82a95faaaf | |||
| af7534df48 | |||
| fa2c2a6417 | |||
| 390a524736 | |||
| 0ed996100d | |||
| 2e0ae13a77 | |||
| 267e038725 | |||
| 2673755b14 | |||
| 5052ce4f14 | |||
| 717909d7e8 | |||
| 04a408ab97 | |||
| face3c76fb | |||
| 2d3a1cd25c | |||
| 43e95a20b9 | |||
| 05d0bd60ab | |||
| 7e70c059b6 | |||
|
|
0261d237b6 | ||
| ea7fe74e89 | |||
|
|
f7f4b05df5 | ||
|
|
766737b4b5 | ||
|
|
ffa8850bf1 | ||
|
|
2991b52c17 | ||
| df04b0a706 | |||
| ce65276084 | |||
| 17d5acee9d | |||
| c7afa2f754 | |||
| 4d5ab64904 | |||
| f4c3e9b3e1 | |||
| 9d76b17b1d | |||
| 2ec92511cb | |||
| 8e1b9d21f3 | |||
| 7ac596b930 | |||
| cf9650be50 | |||
|
|
fa00f2ab54 | ||
|
|
5774eb7686 | ||
|
|
ceb618dc57 | ||
|
|
66328bb243 | ||
|
|
ecfe669938 | ||
|
|
5af75cc553 | ||
|
|
c402467b38 | ||
|
|
a420c1a618 | ||
|
|
7ef808d221 | ||
|
|
d09d728f7f | ||
| 7602f2c870 | |||
|
|
c74b778227 | ||
|
|
11b7a196dd | ||
|
|
4c113f19e8 | ||
|
|
a6d3781781 | ||
|
|
d4ce8e2891 | ||
|
|
8c829d490f | ||
|
|
6fb82c20ee | ||
|
|
7c473b9a27 | ||
| b5c470e1b9 | |||
| 4ab924907a | |||
| 32f87e25f5 | |||
|
|
3d388362ec | ||
|
|
bbd97acfc5 | ||
| 35d8021278 | |||
| 7e9ed47ad9 | |||
| 13ff63d6e0 | |||
| 6bcb4dd609 | |||
| f3b370c26f | |||
|
|
bf8a2971ec | ||
|
|
67e6e68394 | ||
| 7100503c4f | |||
| 6c78d6bcc2 | |||
|
|
54ee51b0de | ||
|
|
70765af22b | ||
| c803b4532d | |||
| 47b54562c8 | |||
| 5290d442f9 | |||
| 83c2374b90 | |||
|
|
99f954d406 | ||
|
|
6515e1811b | ||
|
|
6a051f7a92 | ||
|
|
70febee15d | ||
| e420931351 | |||
| b7c172c382 | |||
| 3e2606a582 | |||
|
|
954df832ed | ||
|
|
ccba559f73 | ||
|
|
b572639805 | ||
| bb7ed1bdd8 | |||
| 9957465f59 | |||
| eab2fb0880 | |||
| 80d4efd8ba | |||
| b0bc5113ef | |||
| 976da9a153 | |||
| 3ddb98c3d8 | |||
| 4d7cb6ad4f | |||
| c9c6cc668d | |||
| d24ed1884f | |||
| 50e1cd0f1c | |||
|
|
34ffec6272 | ||
|
|
a17eccfb99 | ||
|
|
daadc7771a | ||
| f64ad40572 | |||
| ce7213146d | |||
|
|
6b92832dce | ||
|
|
41af4b0506 | ||
| 78667a83f1 | |||
| 9683ec9643 | |||
| 622538225c | |||
| b0d02497eb | |||
| c52c00ac04 | |||
| 237cad3a7a | |||
| 53768edb23 | |||
| 9ed521738b | |||
| acb7db6f9d | |||
| e911d97966 | |||
| 60ce9ab4f8 | |||
| 96c8ad7bf6 | |||
| 1aed9a51f7 | |||
| 5a9a30d6f1 | |||
| 30a6356565 | |||
| 3046b7d203 | |||
| 09b52f441b | |||
| 5fb0b2b817 | |||
| 03b374ba17 | |||
| d54001d73b | |||
| 948c499b9d | |||
| b7f7cd7e91 | |||
| 516f5040f6 | |||
| 80712801b3 | |||
| 82a4ddee1a | |||
| 3d01f24c1f | |||
| 7c93fa62fb | |||
| a478636ded | |||
| 3987634848 | |||
| a1609ee3c7 | |||
| 1784f69041 | |||
| 6d60327489 | |||
| fb801297c5 | |||
| 99b2a5a53b | |||
| c0d2e25437 | |||
| 93a3051027 | |||
| 15e67f1e4c | |||
| 35aa5a8975 | |||
| 7254ca24c8 | |||
| 32346c075a | |||
| f07fe32131 | |||
| c8d0cb184a | |||
| ed0fc3539d | |||
| 95a40c9f4d | |||
| 4814758a49 | |||
| cb0f32f809 | |||
| 6be92ae0f2 | |||
| c79707f1e1 | |||
| 76ce9c075d | |||
| 42b08eba7a | |||
| c83d24a086 | |||
| 36e8c8a9b9 | |||
| c30f11b82e | |||
| e22b108514 | |||
| 8d672b4b49 | |||
| ec876ca518 | |||
| cf2e2161cf | |||
| 180642bfb9 | |||
| 2350620223 | |||
|
|
21ec149baa | ||
|
|
6e5706acba | ||
|
|
9ac9895ed4 | ||
| 3a1678e742 | |||
| c968831209 | |||
|
|
c3fccc3c20 | ||
|
|
97c1fb4803 | ||
|
|
808cdea86a | ||
|
|
c048b6ad6b | ||
| a5b9579b79 | |||
| c2d87c3e25 | |||
|
|
0a6a2093d5 | ||
| c4df4a2f5c | |||
|
|
d040da3277 | ||
|
|
64e92f7a39 | ||
|
|
1d2aecf4fb | ||
|
|
b38a88d5f9 | ||
|
|
e85379dcf5 | ||
|
|
9f9feff2fd | ||
|
|
8362e1885d | ||
|
|
f3eef04a09 | ||
|
|
b55e045cca | ||
|
|
a3e1d34a7a | ||
|
|
a53c5154b0 | ||
|
|
6e5b192fb6 | ||
| efdbed58df | |||
|
|
dc6ad9afac | ||
| 38f330b94b | |||
|
|
9f11b2b7bc | ||
|
|
4a2b64f73d | ||
|
|
12eef1de61 | ||
|
|
bdceababcf | ||
| 07d26cf70c | |||
| 0810983f86 | |||
|
|
9deeb35ad7 | ||
|
|
63ddbaeacf | ||
|
|
71e9fe7cd2 | ||
|
|
726c3481e5 | ||
|
|
30c602a9bf | ||
|
|
5b2ba2eff2 | ||
|
|
04577f3b61 | ||
|
|
8da8bd18a7 | ||
|
|
8ab32a4d2b | ||
|
|
130281b602 | ||
|
|
02272f980f | ||
|
|
e402cdaf5c | ||
|
|
348d054e16 | ||
|
|
011b78472b | ||
|
|
4f3d8e0c7d | ||
|
|
7b01ef788a | ||
|
|
a64823ae5e | ||
|
|
c187bdbe5e | ||
|
|
3c149a32e9 | ||
|
|
2153e83426 | ||
|
|
278dda42a8 | ||
|
|
1556f8bc45 | ||
|
|
b3b3e80509 | ||
|
|
441f65915f | ||
|
|
aa27dd8c1c | ||
|
|
20ec64c21d | ||
|
|
7a6537d529 | ||
|
|
e2d67ab6d7 | ||
|
|
79e10ef2f6 | ||
|
|
da8ba360ca | ||
|
|
fac8762888 | ||
|
|
ddffb9c4f8 | ||
|
|
b16050cfc6 | ||
|
|
a415f90906 | ||
|
|
e8974376c5 | ||
|
|
6f33261101 | ||
|
|
af90bb9efe | ||
|
|
e12b087c94 | ||
|
|
3cb625c921 | ||
|
|
70bb33f823 | ||
|
|
e63d1ea557 | ||
|
|
2b80e8fa97 | ||
|
|
9cab65f941 | ||
|
|
4c8bdb27fd | ||
|
|
b604ffcba2 | ||
|
|
6ef1e97deb | ||
|
|
60bcf26379 | ||
|
|
a4a3dc4536 | ||
|
|
86d61e720f | ||
|
|
002931d6dd | ||
|
|
77d8a0825f | ||
|
|
f6046aec54 | ||
|
|
72f7211d63 | ||
|
|
7fea3dc1ff | ||
|
|
ec309b5afb | ||
|
|
681c561a7d | ||
|
|
22a30533c2 | ||
|
|
de418bcca4 | ||
|
|
7b2b37a870 | ||
|
|
28538bcf41 | ||
|
|
d73fa2a1c5 | ||
|
|
2288bc3fb9 | ||
|
|
05a590b169 | ||
|
|
03f81938ae | ||
|
|
89ee1caf36 | ||
|
|
73f95de4c8 | ||
|
|
5ec049ff61 | ||
|
|
56b0fedbe2 | ||
|
|
902231ff86 | ||
|
|
e5b5c259d7 | ||
|
|
c5b6498f1b | ||
|
|
39a406bfaf |
@@ -45,6 +45,9 @@
|
||||
<OptionInfer>On</OptionInfer>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="DigitalData.Modules.Logging">
|
||||
<HintPath>..\Logging\bin\Debug\DigitalData.Modules.Logging.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="NLog, Version=5.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NLog.5.0.5\lib\net46\NLog.dll</HintPath>
|
||||
@@ -57,6 +60,7 @@
|
||||
<Reference Include="System.Runtime.Serialization" />
|
||||
<Reference Include="System.ServiceModel" />
|
||||
<Reference Include="System.Transactions" />
|
||||
<Reference Include="System.Web" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Core" />
|
||||
@@ -76,17 +80,26 @@
|
||||
<Import Include="System.Threading.Tasks" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="BaseClass.vb" />
|
||||
<Compile Include="BaseUtils.vb" />
|
||||
<Compile Include="DatabaseEx.vb" />
|
||||
<Compile Include="Base\BaseClass.vb" />
|
||||
<Compile Include="Base\BaseUtils.vb" />
|
||||
<Compile Include="ECM\ECM.vb" />
|
||||
<Compile Include="Encryption\Compression.vb" />
|
||||
<Compile Include="Encryption\Encryption.vb" />
|
||||
<Compile Include="Encryption\EncryptionLegacy.vb" />
|
||||
<Compile Include="DatabaseEx.vb" />
|
||||
<Compile Include="FilesystemEx.vb" />
|
||||
<Compile Include="FileWatcher\FileWatcher.vb" />
|
||||
<Compile Include="FileWatcher\FileWatcherFilters.vb" />
|
||||
<Compile Include="FileWatcher\FileWatcherProperties.vb" />
|
||||
<Compile Include="IDB\Constants.vb" />
|
||||
<Compile Include="MimeEx.vb" />
|
||||
<Compile Include="StringFunctions.vb" />
|
||||
<Compile Include="WindowsEx.vb" />
|
||||
<Compile Include="ModuleExtensions.vb" />
|
||||
<Compile Include="FileEx.vb" />
|
||||
<Compile Include="NativeMethods.vb" />
|
||||
<Compile Include="ObjectEx.vb" />
|
||||
<Compile Include="GraphicsEx.vb" />
|
||||
<Compile Include="IDB\Attributes.vb" />
|
||||
<Compile Include="IDB\Database.vb" />
|
||||
<Compile Include="IDB\FileStore.vb" />
|
||||
<Compile Include="LanguageEx.vb" />
|
||||
<Compile Include="My Project\AssemblyInfo.vb" />
|
||||
<Compile Include="My Project\Application.Designer.vb">
|
||||
@@ -104,7 +117,6 @@
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
<Compile Include="PerformanceEx.vb" />
|
||||
<Compile Include="ScreenEx.vb" />
|
||||
<Compile Include="StringEx.vb" />
|
||||
</ItemGroup>
|
||||
@@ -131,11 +143,9 @@
|
||||
<ItemGroup>
|
||||
<Content Include="README.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Logging\Logging.vbproj">
|
||||
<Project>{903b2d7d-3b80-4be9-8713-7447b704e1b0}</Project>
|
||||
<Name>Logging</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>powershell.exe -command "& { &'$(SolutionDir)copy-binary.ps1' '$(TargetPath)' '$(TargetFileName)' '$(ConfigurationName)' '$(ProjectName)' }"</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -1,16 +1,17 @@
|
||||
Public Class DatabaseEx
|
||||
''' <summary>
|
||||
''' TODO: Deprecate
|
||||
''' Checks a Row value for three different `null` values,
|
||||
''' Nothing, Empty String, DBNull
|
||||
'''
|
||||
''' Returns the original value if the value is not null, or `defaultValue`
|
||||
''' </summary>
|
||||
''' <typeparam name="T">The type of the value</typeparam>
|
||||
''' <param name="Row">The DataRow that contains the value</param>
|
||||
''' <param name="Column">The column name</param>
|
||||
''' <param name="DefaultValue">The default value</param>
|
||||
''' <param name="pRow">The DataRow that contains the value</param>
|
||||
''' <param name="pColumn">The column name</param>
|
||||
''' <param name="pDefaultValue">The default value</param>
|
||||
''' <returns>The original value or the default value</returns>
|
||||
Public Shared Function NotNull(Of T)(ByVal Row As DataRow, Column As String, DefaultValue As T) As T
|
||||
Return ObjectEx.NotNull(Row.Item(Column), DefaultValue)
|
||||
Public Shared Function NotNull(Of T)(ByVal pRow As DataRow, pColumn As String, pDefaultValue As T) As T
|
||||
Return ObjectEx.NotNull(pRow.Item(pColumn), pDefaultValue)
|
||||
End Function
|
||||
End Class
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
Public Class ECM
|
||||
Public Enum Product
|
||||
ProcessManager
|
||||
GlobalIndexer
|
||||
ClipboardWatcher
|
||||
taskFLOW
|
||||
easyFLOW
|
||||
fileFLOW
|
||||
signFLOW
|
||||
End Enum
|
||||
End Class
|
||||
|
||||
70
Base/Encryption/Compression.vb
Normal file
70
Base/Encryption/Compression.vb
Normal file
@@ -0,0 +1,70 @@
|
||||
Imports System.IO
|
||||
Imports System.IO.Compression
|
||||
Imports DigitalData.Modules.Logging
|
||||
|
||||
Public Class Compression
|
||||
Private ReadOnly _logger As Logger
|
||||
|
||||
Public Sub New(LogConfig As LogConfig)
|
||||
_logger = LogConfig.GetLogger()
|
||||
End Sub
|
||||
|
||||
Public Async Function CompressAsync(data As Byte()) As Task(Of Byte())
|
||||
Return Await Task.Run(Function() As Byte()
|
||||
Return Compress(data)
|
||||
End Function)
|
||||
End Function
|
||||
|
||||
Public Function Compress(data As Byte()) As Byte()
|
||||
Try
|
||||
' ByteArray in Stream umwandeln
|
||||
Using originalStream As New MemoryStream(data)
|
||||
' Ziel Stream erstellen
|
||||
Using compressedStream As New MemoryStream()
|
||||
' Gzip-Stream erstellen, der alle Daten komprimiert und zu compressedStream durchleitet
|
||||
'
|
||||
' > MemoryStream > GzipStream > MemoryStream
|
||||
' originalStream --> compressionStream --> compressedFileStream
|
||||
'
|
||||
Using compressionStream As New GZipStream(compressedStream, CompressionMode.Compress)
|
||||
originalStream.CopyTo(compressionStream)
|
||||
compressionStream.Close()
|
||||
Return compressedStream.ToArray()
|
||||
End Using
|
||||
End Using
|
||||
End Using
|
||||
Catch ex As Exception
|
||||
_logger.Error(ex)
|
||||
Throw ex
|
||||
End Try
|
||||
End Function
|
||||
|
||||
Public Async Function DecompressAsync(data As Byte()) As Task(Of Byte())
|
||||
Return Await Task.Run(Function() As Byte()
|
||||
Return Decompress(data)
|
||||
End Function)
|
||||
End Function
|
||||
|
||||
Public Function Decompress(data As Byte()) As Byte()
|
||||
Try
|
||||
' ByteArray in Stream umwandeln
|
||||
Using compressedStream As New MemoryStream(data)
|
||||
' Ziel Stream erstellen
|
||||
Using decompressedStream As New MemoryStream()
|
||||
' Gzip-Stream erstellen, der alle Daten komprimiert und zu compressedStream durchleitet
|
||||
'
|
||||
' > MemoryStream > GzipStream > MemoryStream
|
||||
' compressedStream --> decompressionStream --> decompressedStream
|
||||
'
|
||||
Using decompressionStream As New GZipStream(compressedStream, CompressionMode.Decompress)
|
||||
decompressionStream.CopyTo(decompressedStream)
|
||||
Return decompressedStream.ToArray()
|
||||
End Using
|
||||
End Using
|
||||
End Using
|
||||
Catch ex As Exception
|
||||
_logger.Error(ex)
|
||||
Throw ex
|
||||
End Try
|
||||
End Function
|
||||
End Class
|
||||
148
Base/Encryption/Encryption.vb
Normal file
148
Base/Encryption/Encryption.vb
Normal file
@@ -0,0 +1,148 @@
|
||||
Imports System.IO
|
||||
Imports System.Security.Cryptography
|
||||
Imports System.Text.Encoding
|
||||
Imports DigitalData.Modules.Logging
|
||||
|
||||
''' <summary>
|
||||
''' https://stackoverflow.com/questions/10168240/encrypting-decrypting-a-string-in-c-sharp
|
||||
''' </summary>
|
||||
Public Class Encryption
|
||||
' This constant is used to determine the keysize of the encryption algorithm in bits.
|
||||
' We divide this by 8 within the code below to get the equivalent number of bytes.
|
||||
Private Const KEY_SIZE As Integer = 256
|
||||
' This constant determines the number of iterations for the password bytes generation function.
|
||||
Private Const DERIVATION_ITERATIONS As Integer = 1000
|
||||
Private Const BLOCK_SIZE As Integer = 256
|
||||
|
||||
Private _paddingMode As PaddingMode = PaddingMode.Zeros
|
||||
Private _cipherMode As CipherMode = CipherMode.CBC
|
||||
|
||||
Private ReadOnly _password As String
|
||||
Private _logger As Logger
|
||||
|
||||
Public Sub New(LogConfig As LogConfig, Password As String)
|
||||
_logger = LogConfig.GetLogger()
|
||||
|
||||
If IsNothing(Password) Then
|
||||
Throw New ArgumentNullException("Password")
|
||||
End If
|
||||
|
||||
_password = Password
|
||||
End Sub
|
||||
|
||||
Public Async Function EncryptAsync(PlainTextBytes As Byte()) As Task(Of Byte())
|
||||
Return Await Task.Run(Function() As Byte()
|
||||
Return Encrypt(PlainTextBytes)
|
||||
End Function)
|
||||
End Function
|
||||
|
||||
Public Function Encrypt(PlainText As String) As String
|
||||
Try
|
||||
Dim oBytes As Byte() = UTF8.GetBytes(PlainText)
|
||||
Dim oEncrypted As Byte() = Encrypt(oBytes)
|
||||
Return UTF8.GetString(oEncrypted)
|
||||
Catch ex As Exception
|
||||
_logger.Error(ex)
|
||||
Throw ex
|
||||
End Try
|
||||
End Function
|
||||
|
||||
Public Function Encrypt(PlainTextBytes As Byte()) As Byte()
|
||||
Try
|
||||
' Salt and IV is randomly generated each time, but is preprended to encrypted cipher text
|
||||
' so that the same Salt and IV values can be used when decrypting.
|
||||
Dim oSaltStringBytes = Generate256BitsOfRandomEntropy()
|
||||
Dim oIvStringBytes = Generate256BitsOfRandomEntropy()
|
||||
Using oPassword = New Rfc2898DeriveBytes(_password, oSaltStringBytes, DERIVATION_ITERATIONS)
|
||||
Dim oKeyBytes = oPassword.GetBytes(KEY_SIZE / 8)
|
||||
Using oSymmetricKey = New RijndaelManaged()
|
||||
oSymmetricKey.BlockSize = BLOCK_SIZE
|
||||
oSymmetricKey.Mode = _cipherMode
|
||||
oSymmetricKey.Padding = _paddingMode
|
||||
|
||||
Using oEncryptor = oSymmetricKey.CreateEncryptor(oKeyBytes, oIvStringBytes)
|
||||
Using oMemoryStream = New MemoryStream()
|
||||
Using oCryptoStream = New CryptoStream(oMemoryStream, oEncryptor, CryptoStreamMode.Write)
|
||||
oCryptoStream.Write(PlainTextBytes, 0, PlainTextBytes.Length)
|
||||
oCryptoStream.FlushFinalBlock()
|
||||
' Create the final bytes as a concatenation of the random salt bytes, the random iv bytes and the cipher bytes.
|
||||
Dim oCipherTextBytes = oSaltStringBytes
|
||||
oCipherTextBytes = oCipherTextBytes.Concat(oIvStringBytes).ToArray()
|
||||
oCipherTextBytes = oCipherTextBytes.Concat(oMemoryStream.ToArray()).ToArray()
|
||||
oMemoryStream.Close()
|
||||
oCryptoStream.Close()
|
||||
Return oCipherTextBytes
|
||||
End Using
|
||||
End Using
|
||||
End Using
|
||||
End Using
|
||||
End Using
|
||||
Catch ex As Exception
|
||||
_logger.Error(ex)
|
||||
Throw ex
|
||||
End Try
|
||||
End Function
|
||||
|
||||
Public Async Function DecryptAsync(CipherTextBytesWithSaltAndIv As Byte()) As Task(Of Byte())
|
||||
Return Await Task.Run(Function() As Byte()
|
||||
Return Decrypt(CipherTextBytesWithSaltAndIv)
|
||||
End Function)
|
||||
End Function
|
||||
|
||||
Public Function Decrypt(CipherTextPlainWithSaltAndIv As String) As String
|
||||
Try
|
||||
Dim oBytes As Byte() = UTF8.GetBytes(CipherTextPlainWithSaltAndIv)
|
||||
Dim oDecrypted As Byte() = Decrypt(oBytes)
|
||||
Return UTF8.GetString(oDecrypted)
|
||||
Catch ex As Exception
|
||||
_logger.Error(ex)
|
||||
Throw ex
|
||||
End Try
|
||||
End Function
|
||||
|
||||
Public Function Decrypt(CipherTextBytesWithSaltAndIv As Byte()) As Byte()
|
||||
Try
|
||||
' Get the complete stream of bytes that represent:
|
||||
' [32 bytes of Salt] + [32 bytes of IV] + [n bytes of CipherText]
|
||||
' Get the saltbytes by extracting the first 32 bytes from the supplied cipherText bytes.
|
||||
Dim oSaltStringBytes = CipherTextBytesWithSaltAndIv.Take(KEY_SIZE / 8).ToArray()
|
||||
' Get the IV bytes by extracting the next 32 bytes from the supplied cipherText bytes.
|
||||
Dim oIvStringBytes = CipherTextBytesWithSaltAndIv.Skip(KEY_SIZE / 8).Take(KEY_SIZE / 8).ToArray()
|
||||
' Get the actual cipher text bytes by removing the first 64 bytes from the cipherText string.
|
||||
Dim oCipherTextBytes = CipherTextBytesWithSaltAndIv.Skip((KEY_SIZE / 8) * 2).Take(CipherTextBytesWithSaltAndIv.Length - ((KEY_SIZE / 8) * 2)).ToArray()
|
||||
|
||||
Using oPassword = New Rfc2898DeriveBytes(_password, oSaltStringBytes, DERIVATION_ITERATIONS)
|
||||
Dim oKeyBytes = oPassword.GetBytes(KEY_SIZE / 8)
|
||||
Using oSymmetricKey = New RijndaelManaged()
|
||||
oSymmetricKey.BlockSize = BLOCK_SIZE
|
||||
oSymmetricKey.Mode = _cipherMode
|
||||
oSymmetricKey.Padding = _paddingMode
|
||||
Using oDecryptor = oSymmetricKey.CreateDecryptor(oKeyBytes, oIvStringBytes)
|
||||
Using oMemoryStream = New MemoryStream(oCipherTextBytes)
|
||||
Using oCryptoStream = New CryptoStream(oMemoryStream, oDecryptor, CryptoStreamMode.Read)
|
||||
Dim oPlainTextBytes = New Byte(oCipherTextBytes.Length - 1) {}
|
||||
Dim oDecryptedByteCount = oCryptoStream.Read(oPlainTextBytes, 0, oPlainTextBytes.Length)
|
||||
oMemoryStream.Close()
|
||||
oCryptoStream.Close()
|
||||
Return oPlainTextBytes
|
||||
End Using
|
||||
End Using
|
||||
End Using
|
||||
End Using
|
||||
End Using
|
||||
Catch ex As Exception
|
||||
_logger.Error(ex)
|
||||
Throw ex
|
||||
End Try
|
||||
End Function
|
||||
|
||||
Private Shared Function Generate256BitsOfRandomEntropy() As Byte()
|
||||
Dim oRandomBytes = New Byte(31) {}
|
||||
' 32 Bytes will give us 256 bits.
|
||||
Using oRNGCsp = New RNGCryptoServiceProvider()
|
||||
' Fill the array with cryptographically secure random bytes.
|
||||
oRNGCsp.GetBytes(oRandomBytes)
|
||||
End Using
|
||||
Return oRandomBytes
|
||||
End Function
|
||||
End Class
|
||||
85
Base/Encryption/EncryptionLegacy.vb
Normal file
85
Base/Encryption/EncryptionLegacy.vb
Normal file
@@ -0,0 +1,85 @@
|
||||
Imports System.Security.Cryptography
|
||||
Imports System.Data
|
||||
Imports System.Data.SqlClient
|
||||
|
||||
Public Class EncryptionLegacy
|
||||
Private TripleDes As New TripleDESCryptoServiceProvider
|
||||
Private DEFAULT_KEY As String = "!35452didalog="
|
||||
Private SALT_VALUE As String = "!Didalog35452Heuchelheim="
|
||||
|
||||
Sub New()
|
||||
TripleDes.Key = TruncateHash(DEFAULT_KEY, TripleDes.KeySize \ 8)
|
||||
TripleDes.IV = TruncateHash("", TripleDes.BlockSize \ 8)
|
||||
End Sub
|
||||
|
||||
Sub New(key As String)
|
||||
' Initialize the crypto provider.
|
||||
TripleDes.Key = TruncateHash(key, TripleDes.KeySize \ 8)
|
||||
TripleDes.IV = TruncateHash("", TripleDes.BlockSize \ 8)
|
||||
End Sub
|
||||
|
||||
Private Function TruncateHash(ByVal key As String, ByVal length As Integer) As Byte()
|
||||
Dim sha1 As New SHA1CryptoServiceProvider
|
||||
|
||||
' Hash the key.
|
||||
Dim keyBytes() As Byte =
|
||||
System.Text.Encoding.Unicode.GetBytes(key)
|
||||
Dim hash() As Byte = sha1.ComputeHash(keyBytes)
|
||||
|
||||
' Truncate or pad the hash.
|
||||
ReDim Preserve hash(length - 1)
|
||||
Return hash
|
||||
End Function
|
||||
|
||||
<DebuggerStepThrough>
|
||||
Public Function EncryptData(ByVal plaintext As String) As String
|
||||
Try
|
||||
' Convert the plaintext string to a byte array.
|
||||
Dim plaintextBytes() As Byte =
|
||||
System.Text.Encoding.Unicode.GetBytes(SALT_VALUE & plaintext)
|
||||
|
||||
' Create the stream.
|
||||
Dim ms As New System.IO.MemoryStream
|
||||
' Create the encoder to write to the stream.
|
||||
Dim encStream As New CryptoStream(ms,
|
||||
TripleDes.CreateEncryptor(),
|
||||
System.Security.Cryptography.CryptoStreamMode.Write)
|
||||
|
||||
' Use the crypto stream to write the byte array to the stream.
|
||||
encStream.Write(plaintextBytes, 0, plaintextBytes.Length)
|
||||
encStream.FlushFinalBlock()
|
||||
|
||||
' Convert the encrypted stream to a printable string.
|
||||
Return Convert.ToBase64String(ms.ToArray)
|
||||
Catch ex As Exception
|
||||
Return plaintext
|
||||
End Try
|
||||
End Function
|
||||
|
||||
'Entschlüsselt die Zeichenfolge
|
||||
<DebuggerStepThrough>
|
||||
Public Function DecryptData(ByVal EncryptedText As String) As String
|
||||
Try
|
||||
' Convert the encrypted text string to a byte array.
|
||||
Dim oEncryptedBytes() As Byte = Convert.FromBase64String(EncryptedText)
|
||||
|
||||
' Create the stream.
|
||||
Dim oMemoryStream As New System.IO.MemoryStream
|
||||
' Create the decoder to write to the stream.
|
||||
Dim oCryptoStream As New CryptoStream(oMemoryStream,
|
||||
TripleDes.CreateDecryptor(),
|
||||
System.Security.Cryptography.CryptoStreamMode.Write)
|
||||
|
||||
' Use the crypto stream to write the byte array to the stream.
|
||||
oCryptoStream.Write(oEncryptedBytes, 0, oEncryptedBytes.Length)
|
||||
oCryptoStream.FlushFinalBlock()
|
||||
Dim oResult = System.Text.Encoding.Unicode.GetString(oMemoryStream.ToArray)
|
||||
oResult = oResult.Replace(SALT_VALUE, "")
|
||||
' Convert the plaintext stream to a string.
|
||||
Return oResult
|
||||
Catch ex As Exception
|
||||
Return EncryptedText
|
||||
End Try
|
||||
End Function
|
||||
End Class
|
||||
|
||||
@@ -7,7 +7,7 @@ Public Class FileEx
|
||||
''' </summary>
|
||||
''' <param name="pFilePath"></param>
|
||||
''' <returns></returns>
|
||||
Public Function GetChecksumFromFileContents(pFilePath As String) As String
|
||||
Public Shared Function GetChecksumFromFileContents(pFilePath As String) As String
|
||||
Try
|
||||
Using oFileStream = IO.File.OpenRead(pFilePath)
|
||||
Using oStream As New BufferedStream(oFileStream, 1200000)
|
||||
@@ -20,7 +20,59 @@ Public Class FileEx
|
||||
End Try
|
||||
End Function
|
||||
|
||||
Public Function GetHashFromFileContents(pFilePath As String) As String
|
||||
Public Shared Function GetHashFromFileContents(pFilePath As String) As String
|
||||
Return GetChecksumFromFileContents(pFilePath)
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Returns a Dictionary path in the form of [Base]\[Year]\[Month]\[Day]
|
||||
''' </summary>
|
||||
''' <param name="pBaseDirectory">The basedirectory</param>
|
||||
''' <param name="pDate">The date to be used</param>
|
||||
''' <returns>The final directory path</returns>
|
||||
Public Shared Function GetDateDirectory(pBaseDirectory As String, pDate As Date) As String
|
||||
Dim oDateDirectory = StringEx.GetDateString(pDate)
|
||||
Dim oFinalDirectory As String = Path.Combine(pBaseDirectory, oDateDirectory)
|
||||
Return oFinalDirectory
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Returns a Dictionary path in the form of [Base]\[Year]\[Month]\[Day] based on the current date
|
||||
''' </summary>
|
||||
''' <param name="pBaseDirectory">The basedirectory</param>
|
||||
''' <returns>The final directory path</returns>
|
||||
Public Shared Function GetDateDirectory(pBaseDirectory As String) As String
|
||||
Return GetDateDirectory(pBaseDirectory, Now)
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Creates a Dictionary in the form of [Base]\[Year]\[Month]\[Day]
|
||||
''' </summary>
|
||||
''' <param name="pBaseDirectory">The basedirectory</param>
|
||||
''' <param name="pDate">The date to be used</param>
|
||||
''' <returns>The created path. If the directory cannot be created, Nothing.</returns>
|
||||
Public Shared Function CreateDateDirectory(pBaseDirectory As String, pDate As Date) As String
|
||||
Dim oDateDirectory = StringEx.GetDateString(pDate)
|
||||
Dim oFinalDirectory As String = Path.Combine(pBaseDirectory, oDateDirectory)
|
||||
|
||||
If Directory.Exists(oFinalDirectory) = False Then
|
||||
Try
|
||||
Directory.CreateDirectory(oFinalDirectory)
|
||||
Catch ex As Exception
|
||||
Return Nothing
|
||||
End Try
|
||||
End If
|
||||
|
||||
Return oFinalDirectory
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Creates a Dictionary in the form of [Base]\[Year]\[Month]\[Day] based on the current date
|
||||
''' </summary>
|
||||
''' <param name="pBaseDirectory">The basedirectory</param>
|
||||
''' <returns>The created path. If the directory cannot be created, Nothing.</returns>
|
||||
Public Shared Function CreateDateDirectory(pBaseDirectory As String) As String
|
||||
Return CreateDateDirectory(pBaseDirectory, Now)
|
||||
End Function
|
||||
|
||||
End Class
|
||||
|
||||
131
Base/FileWatcher/FileWatcher.vb
Normal file
131
Base/FileWatcher/FileWatcher.vb
Normal file
@@ -0,0 +1,131 @@
|
||||
Imports System.IO
|
||||
Imports DigitalData.Modules.Base.FileWatcherFilters
|
||||
Imports DigitalData.Modules.Logging
|
||||
|
||||
|
||||
Public Class FileWatcher
|
||||
' Internals
|
||||
Private ReadOnly _Logger As Logger
|
||||
Private ReadOnly _Watchers As List(Of FileSystemWatcher)
|
||||
Private ReadOnly _Files As Dictionary(Of String, FileWatcherProperties)
|
||||
Private ReadOnly _Filters As List(Of BaseFileFilter)
|
||||
|
||||
' Options
|
||||
Private _Path As String
|
||||
|
||||
' Public Events
|
||||
Public Event FileSaved(ByVal FullName As String, ByVal IsSpecial As Boolean)
|
||||
|
||||
Public Sub New(LogConfig As LogConfig, Path As String, Optional Filters As List(Of BaseFileFilter) = Nothing)
|
||||
_Logger = LogConfig.GetLogger()
|
||||
_Files = New Dictionary(Of String, FileWatcherProperties)
|
||||
_Watchers = New List(Of FileSystemWatcher)
|
||||
_Filters = IIf(IsNothing(Filters), GetDefaultFilters(), Filters)
|
||||
_Path = Path
|
||||
|
||||
For Each oFilePath In Directory.EnumerateFiles(_Path)
|
||||
Try
|
||||
If IO.File.Exists(oFilePath) Then
|
||||
_Files.Add(oFilePath, New FileWatcherProperties With {
|
||||
.CreatedAt = DateTime.Now,
|
||||
.ChangedAt = Nothing
|
||||
})
|
||||
End If
|
||||
Catch ex As Exception
|
||||
_Logger.Error(ex)
|
||||
_Logger.Warn("File {0} cannot be watched!")
|
||||
End Try
|
||||
Next
|
||||
End Sub
|
||||
|
||||
Public Sub Add(Filter As String)
|
||||
_Watchers.Add(CreateWatcher(Filter))
|
||||
End Sub
|
||||
|
||||
Public Sub Start()
|
||||
For Each oWatcher In _Watchers
|
||||
oWatcher.EnableRaisingEvents = True
|
||||
Next
|
||||
End Sub
|
||||
|
||||
Public Sub [Stop]()
|
||||
For Each oWatcher In _Watchers
|
||||
If Not IsNothing(oWatcher) Then
|
||||
oWatcher.EnableRaisingEvents = False
|
||||
oWatcher.Dispose()
|
||||
End If
|
||||
Next
|
||||
End Sub
|
||||
|
||||
Private Function GetDefaultFilters()
|
||||
Return New List(Of BaseFileFilter) From {
|
||||
New TempFileFilter,
|
||||
New OfficeFileFilter
|
||||
}
|
||||
End Function
|
||||
|
||||
Private Function CreateWatcher(Filter As String)
|
||||
Dim oWatcher = New FileSystemWatcher() With {
|
||||
.Path = _Path,
|
||||
.Filter = Filter,
|
||||
.NotifyFilter = NotifyFilters.LastAccess _
|
||||
Or NotifyFilters.LastWrite _
|
||||
Or NotifyFilters.FileName _
|
||||
Or NotifyFilters.Size _
|
||||
Or NotifyFilters.FileName _
|
||||
Or NotifyFilters.Attributes
|
||||
}
|
||||
|
||||
AddHandler oWatcher.Created, AddressOf HandleFileCreated
|
||||
AddHandler oWatcher.Changed, AddressOf HandleFileChanged
|
||||
AddHandler oWatcher.Deleted, AddressOf HandleFileDeleted
|
||||
AddHandler oWatcher.Renamed, AddressOf HandleFileRenamed
|
||||
|
||||
Return oWatcher
|
||||
End Function
|
||||
|
||||
Private Sub HandleFileCreated(sender As Object, e As FileSystemEventArgs)
|
||||
_Files.Add(e.FullPath, New FileWatcherProperties())
|
||||
_Logger.Debug("[Created] " & e.FullPath)
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' This may fire twice for a single save operation,
|
||||
''' see: https://blogs.msdn.microsoft.com/oldnewthing/20140507-00/?p=1053/
|
||||
''' </summary>
|
||||
Private Sub HandleFileChanged(sender As Object, e As FileSystemEventArgs)
|
||||
_Files.Item(e.FullPath).ChangedAt = DateTime.Now
|
||||
_Logger.Debug("[Changed] " & e.FullPath)
|
||||
|
||||
Dim oShouldRaiseSave As Boolean = Not _Filters.Any(Function(oFilter)
|
||||
Return oFilter.ShouldFilter(e)
|
||||
End Function)
|
||||
|
||||
If oShouldRaiseSave Then
|
||||
RaiseEvent FileSaved(e.FullPath, False)
|
||||
End If
|
||||
End Sub
|
||||
Private Sub HandleFileDeleted(sender As Object, e As FileSystemEventArgs)
|
||||
_Files.Remove(e.FullPath)
|
||||
_Logger.Debug("[Removed] " & e.FullPath)
|
||||
End Sub
|
||||
|
||||
Private Sub HandleFileRenamed(sender As Object, e As RenamedEventArgs)
|
||||
Dim oProperties = _Files.Item(e.OldFullPath)
|
||||
_Files.Remove(e.OldFullPath)
|
||||
_Files.Add(e.FullPath, oProperties)
|
||||
' Soll eine umbenannte datei als NEU gelten?
|
||||
|
||||
Dim oShouldRaiseSave = _Filters.Any(Function(oFilter)
|
||||
Return oFilter.ShouldRaiseSave(e)
|
||||
End Function)
|
||||
|
||||
If oShouldRaiseSave Then
|
||||
RaiseEvent FileSaved(e.OldFullPath, True)
|
||||
End If
|
||||
|
||||
_Logger.Debug("[Renamed] {0} --> {1}", e.OldFullPath, e.FullPath)
|
||||
End Sub
|
||||
|
||||
|
||||
End Class
|
||||
61
Base/FileWatcher/FileWatcherFilters.vb
Normal file
61
Base/FileWatcher/FileWatcherFilters.vb
Normal file
@@ -0,0 +1,61 @@
|
||||
Imports System.IO
|
||||
|
||||
''' <summary>
|
||||
''' Built-in filters for FileWatcher that are useful for correctly detecting changes on Office documents (currently Office 2016)
|
||||
''' </summary>
|
||||
Public Class FileWatcherFilters
|
||||
''' <summary>
|
||||
''' Base Filter that all filters must inherit from
|
||||
''' Provides two functions that may be overridden and some useful file extension lists
|
||||
''' </summary>
|
||||
Public MustInherit Class BaseFileFilter
|
||||
Public TempFiles As New List(Of String) From {".tmp", ""}
|
||||
|
||||
Public Overridable Function ShouldFilter(e As FileSystemEventArgs) As Boolean
|
||||
Return False
|
||||
End Function
|
||||
Public Overridable Function ShouldRaiseSave(e As RenamedEventArgs) As Boolean
|
||||
Return False
|
||||
End Function
|
||||
End Class
|
||||
|
||||
''' <summary>
|
||||
''' Simple Filter that filters changes made on temporary files
|
||||
''' </summary>
|
||||
Public Class TempFileFilter
|
||||
Inherits BaseFileFilter
|
||||
|
||||
Public Overrides Function ShouldFilter(e As FileSystemEventArgs) As Boolean
|
||||
Dim oFileInfo As New FileInfo(e.FullPath)
|
||||
Return TempFiles.Contains(oFileInfo.Extension)
|
||||
End Function
|
||||
End Class
|
||||
|
||||
''' <summary>
|
||||
''' Filter to detect changes on Office files
|
||||
''' </summary>
|
||||
Public Class OfficeFileFilter
|
||||
Inherits BaseFileFilter
|
||||
|
||||
Public OfficeFiles As New List(Of String) From {".docx", ".pptx", ".xlsx"}
|
||||
|
||||
Public Overrides Function ShouldFilter(e As FileSystemEventArgs) As Boolean
|
||||
Dim oFileInfo As New FileInfo(e.FullPath)
|
||||
Return OfficeFiles.Contains(oFileInfo.Extension) And oFileInfo.Name.StartsWith("~")
|
||||
End Function
|
||||
|
||||
Public Overrides Function ShouldRaiseSave(e As RenamedEventArgs) As Boolean
|
||||
Dim oIsTransform = OfficeFiles.Any(Function(Extension As String)
|
||||
Return e.OldName.EndsWith(Extension)
|
||||
End Function)
|
||||
|
||||
' Check if it is renamed to a temp file
|
||||
Dim oIsTempFile = TempFiles.Any(Function(Extension)
|
||||
Return e.Name.EndsWith(Extension)
|
||||
End Function)
|
||||
|
||||
|
||||
Return oIsTransform And oIsTempFile
|
||||
End Function
|
||||
End Class
|
||||
End Class
|
||||
10
Base/FileWatcher/FileWatcherProperties.vb
Normal file
10
Base/FileWatcher/FileWatcherProperties.vb
Normal file
@@ -0,0 +1,10 @@
|
||||
Public Class FileWatcherProperties
|
||||
Public Property CreatedAt As DateTime
|
||||
Public Property ChangedAt As DateTime
|
||||
Public ReadOnly Property HasChanged As Boolean
|
||||
Public Sub New()
|
||||
CreatedAt = DateTime.Now
|
||||
ChangedAt = Nothing
|
||||
HasChanged = False
|
||||
End Sub
|
||||
End Class
|
||||
494
Base/FilesystemEx.vb
Normal file
494
Base/FilesystemEx.vb
Normal file
@@ -0,0 +1,494 @@
|
||||
Imports DigitalData.Modules.Logging
|
||||
Imports System.IO
|
||||
Imports System.Security.Cryptography
|
||||
Imports System.Text
|
||||
Imports System.Text.RegularExpressions
|
||||
|
||||
Public Class FilesystemEx
|
||||
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]"
|
||||
|
||||
' The limit enforced by windows for filenpaths is 260,
|
||||
' so we use a slightly smaller number to have some Error margin.
|
||||
'
|
||||
' Source: https://docs.microsoft.com/de-de/windows/win32/fileio/naming-a-file?redirectedfrom=MSDN#maximum-path-length-limitation
|
||||
Private Const MAX_FILE_PATH_LENGTH = 250
|
||||
|
||||
' This prevents an infinite loop when no file can be created in a location
|
||||
Private Const MAX_FILE_VERSION = 100
|
||||
Private Const VERSION_SEPARATOR As Char = "~"c
|
||||
|
||||
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)
|
||||
oCleanName = Regex.Replace(oCleanName, "\s{2,}", " ")
|
||||
oCleanName = Regex.Replace(oCleanName, "\.{2,}", ".")
|
||||
|
||||
_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>
|
||||
''' Reads the file at `FilePath` and computes a SHA256 Hash from its contents
|
||||
''' </summary>
|
||||
''' <param name="FilePath"></param>
|
||||
''' <returns></returns>
|
||||
Public Function GetChecksum(FilePath As String) As String
|
||||
Try
|
||||
Using oFileStream = IO.File.OpenRead(FilePath)
|
||||
Using oStream As New BufferedStream(oFileStream, 1200000)
|
||||
Dim oChecksum() As Byte = SHA256.Create.ComputeHash(oStream)
|
||||
Return FormatHash(oChecksum)
|
||||
End Using
|
||||
End Using
|
||||
Catch ex As Exception
|
||||
_Logger.Error(ex)
|
||||
Return Nothing
|
||||
End Try
|
||||
End Function
|
||||
|
||||
Public Function GetChecksumFromString(pStringToCheck As String) As String
|
||||
Dim oBytes() As Byte = Encoding.UTF8.GetBytes(pStringToCheck)
|
||||
Dim oChecksum() As Byte = SHA256.Create.ComputeHash(oBytes)
|
||||
Return FormatHash(oChecksum)
|
||||
End Function
|
||||
|
||||
Public Function GetHash(FilePath As String) As String
|
||||
Return GetChecksum(FilePath)
|
||||
End Function
|
||||
|
||||
Public Function GetHashFromString(pStringToCheck As String) As String
|
||||
Return GetChecksumFromString(pStringToCheck)
|
||||
End Function
|
||||
|
||||
Private Function FormatHash(pChecksum)
|
||||
Return BitConverter.
|
||||
ToString(pChecksum).
|
||||
Replace("-", String.Empty)
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Adds file version string to given filename `Destination` if that file already exists.
|
||||
''' </summary>
|
||||
''' <param name="pFilePath">Filepath to check</param>
|
||||
''' <returns>Versioned string</returns>
|
||||
Public Function GetVersionedFilename(pFilePath As String) As String
|
||||
Return GetVersionedFilenameWithFilecheck(pFilePath, Function(pPath As String) IO.File.Exists(pPath))
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Adds file version string to given filename `Destination` if that file already exists.
|
||||
''' </summary>
|
||||
''' <param name="pFilePath">Filepath to check</param>
|
||||
''' <param name="pFileExistsAction">Custom action to check for file existence</param>
|
||||
''' <returns>Versioned string</returns>
|
||||
Public Function GetVersionedFilenameWithFilecheck(pFilePath As String, pFileExistsAction As Func(Of String, Boolean)) As String
|
||||
Try
|
||||
Dim oFileName As String = pFilePath
|
||||
Dim oFinalFileName = oFileName
|
||||
|
||||
Dim oDestinationDir = Path.GetDirectoryName(oFileName)
|
||||
Dim oExtension = Path.GetExtension(oFileName)
|
||||
|
||||
Dim oFileNameWithoutExtension = Path.GetFileNameWithoutExtension(oFileName)
|
||||
Dim oSplitResult = GetVersionedString(oFileNameWithoutExtension)
|
||||
|
||||
oFileNameWithoutExtension = oSplitResult.Item1
|
||||
Dim oFileVersion As Integer = oSplitResult.Item2
|
||||
|
||||
' Shorten the filename (only filename, without extension or version)
|
||||
' by cutting the length in half. This should work no matter how long the path and/or filename are.
|
||||
' The initial check operates on the full path to catch all scenarios.
|
||||
If pFilePath.Length > MAX_FILE_PATH_LENGTH Then
|
||||
_Logger.Info("Filename is too long. Filename will be cut to prevent further errors.")
|
||||
_Logger.Info("Original Filename is: {0}", oFileNameWithoutExtension)
|
||||
Dim oNewLength As Integer = CInt(Math.Floor(oFileNameWithoutExtension.Length / 2.0))
|
||||
Dim oNewFileNameWithoutExtension = oFileNameWithoutExtension.Substring(0, oNewLength)
|
||||
_Logger.Info("New Filename will be: {0}", oNewFileNameWithoutExtension)
|
||||
|
||||
oFileNameWithoutExtension = oNewFileNameWithoutExtension
|
||||
End If
|
||||
|
||||
' while file exists, increment version.
|
||||
' version cannot go above MAX_FILE_VERSION, to prevent infinite loop
|
||||
Do
|
||||
oFinalFileName = Path.Combine(oDestinationDir, GetFilenameWithVersion(oFileNameWithoutExtension, oFileVersion, oExtension))
|
||||
_Logger.Debug("Intermediate Filename is {0}", oFinalFileName)
|
||||
_Logger.Debug("File version: {0}", oFileVersion)
|
||||
oFileVersion += 1
|
||||
Loop While pFileExistsAction(oFinalFileName) = True And oFileVersion < MAX_FILE_VERSION
|
||||
|
||||
If oFileVersion >= MAX_FILE_VERSION Then
|
||||
Throw New OverflowException($"Tried '{MAX_FILE_VERSION}' times to version filename before giving up. Sorry.")
|
||||
End If
|
||||
|
||||
_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!", pFilePath)
|
||||
_Logger.Error(ex)
|
||||
Return pFilePath
|
||||
End Try
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Split String at version separator to:
|
||||
''' check if string is already versioned,
|
||||
''' get the string version of an already versioned string
|
||||
''' </summary>
|
||||
''' <example>
|
||||
''' Examples:
|
||||
''' 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
|
||||
''' somestring~3 --> somestring~3 --> ['somestring', '3'] --> version 3
|
||||
''' </example>
|
||||
''' <param name="pString">The string to versioned</param>
|
||||
''' <returns>Tuple of string and version</returns>
|
||||
Public Function GetVersionedString(pString As String) As Tuple(Of String, Integer)
|
||||
Dim oSplitString = pString.Split(VERSION_SEPARATOR).ToList()
|
||||
Dim oStringVersion As Integer
|
||||
|
||||
' if string is already versioned, extract string version
|
||||
' else just use the string and set version to 1
|
||||
If oSplitString.Count > 1 Then
|
||||
Dim oVersion As Integer = 1
|
||||
Try
|
||||
oVersion = Integer.Parse(oSplitString.Last())
|
||||
pString = String.Join("", oSplitString.Take(oSplitString.Count - 1))
|
||||
Catch ex As Exception
|
||||
' pString does NOT change
|
||||
pString = pString
|
||||
Finally
|
||||
oStringVersion = oVersion
|
||||
End Try
|
||||
Else
|
||||
oStringVersion = 1
|
||||
End If
|
||||
|
||||
_Logger.Debug("Versioned: String [{0}], Version [{1}]", pString, oStringVersion)
|
||||
|
||||
Return New Tuple(Of String, Integer)(pString, oStringVersion)
|
||||
End Function
|
||||
|
||||
Public Function GetAppDataPath(CompanyName As String, ProductName As String)
|
||||
Dim oLocalAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)
|
||||
Return Path.Combine(oLocalAppData, CompanyName, ProductName)
|
||||
End Function
|
||||
|
||||
Private Function GetFilenameWithVersion(FileNameWithoutExtension As String, FileVersion As Integer, Extension As String) As String
|
||||
If FileVersion <= 1 Then
|
||||
Return $"{FileNameWithoutExtension}{Extension}"
|
||||
Else
|
||||
Return $"{FileNameWithoutExtension}{VERSION_SEPARATOR}{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).
|
||||
ToList()
|
||||
|
||||
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 += 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>
|
||||
''' Copied from https://docs.microsoft.com/en-us/dotnet/standard/io/how-to-copy-directories
|
||||
''' </summary>
|
||||
''' <param name="SourceDirName"></param>
|
||||
''' <param name="DestDirName"></param>
|
||||
''' <param name="CopySubDirs"></param>
|
||||
Public Sub CopyDirectory(ByVal SourceDirName As String, ByVal DestDirName As String, ByVal CopySubDirs As Boolean)
|
||||
Dim oDirectory As New DirectoryInfo(SourceDirName)
|
||||
|
||||
If Not oDirectory.Exists Then
|
||||
Throw New DirectoryNotFoundException("Source directory does not exist or could not be found: " & SourceDirName)
|
||||
End If
|
||||
|
||||
Dim oDirectories As DirectoryInfo() = oDirectory.GetDirectories()
|
||||
Directory.CreateDirectory(DestDirName)
|
||||
Dim oFiles As FileInfo() = oDirectory.GetFiles()
|
||||
|
||||
For Each oFile As FileInfo In oFiles
|
||||
Dim tempPath As String = Path.Combine(DestDirName, oFile.Name)
|
||||
oFile.CopyTo(tempPath, False)
|
||||
Next
|
||||
|
||||
If CopySubDirs Then
|
||||
For Each oSubDirectory As DirectoryInfo In oDirectories
|
||||
Dim oTempPath As String = Path.Combine(DestDirName, oSubDirectory.Name)
|
||||
CopyDirectory(oSubDirectory.FullName, oTempPath, CopySubDirs)
|
||||
Next
|
||||
End If
|
||||
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
|
||||
|
||||
''' <summary>
|
||||
''' Checks if a file is locked, ie. in use by another process.
|
||||
''' </summary>
|
||||
''' <remarks>
|
||||
''' https://docs.microsoft.com/en-us/dotnet/standard/io/handling-io-errors
|
||||
''' https://stackoverflow.com/questions/876473/is-there-a-way-to-check-if-a-file-is-in-use
|
||||
''' </remarks>
|
||||
Public Function TestFileIsLocked(pFilePath As String) As Boolean
|
||||
Try
|
||||
Using stream As FileStream = IO.File.Open(pFilePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None)
|
||||
stream.Close()
|
||||
End Using
|
||||
Catch ex As Exception When ((ex.HResult And &HFFFF) = 32)
|
||||
Return True
|
||||
Catch ex As Exception
|
||||
Return True
|
||||
End Try
|
||||
|
||||
Return False
|
||||
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
|
||||
|
||||
''' <summary>
|
||||
''' Checks the size of the supplied file.
|
||||
''' </summary>
|
||||
''' <param name="pFilePath"></param>
|
||||
''' <param name="pMaxFileSizeInMegaBytes"></param>
|
||||
''' <returns></returns>
|
||||
Public Function TestFileSizeIsLessThanMaxFileSize(pFilePath As String, pMaxFileSizeInMegabytes As Integer) As Boolean
|
||||
Dim oFileInfo As New FileInfo(pFilePath)
|
||||
|
||||
_Logger.Info("Checking Filesize of {0}", oFileInfo.Name)
|
||||
_Logger.Debug("Filesize threshold is {0} MB.", pMaxFileSizeInMegabytes)
|
||||
|
||||
If pMaxFileSizeInMegabytes <= 0 Then
|
||||
_Logger.Debug("Filesize is not configured. Skipping check.")
|
||||
Return True
|
||||
End If
|
||||
|
||||
Dim oMaxSize = pMaxFileSizeInMegabytes * 1024 * 1024
|
||||
|
||||
If oMaxSize > 0 And oFileInfo.Length > oMaxSize Then
|
||||
_Logger.Debug("Filesize is bigger than threshold.")
|
||||
Return False
|
||||
Else
|
||||
_Logger.Debug("Filesize is smaller than threshold. All fine.")
|
||||
Return True
|
||||
End If
|
||||
End Function
|
||||
|
||||
Public Function GetDateDirectory(pBaseDirectory As String, pDate As Date) As String
|
||||
Dim oDateDirectory = GetDateString(pDate)
|
||||
Dim oFinalDirectory As String = IO.Path.Combine(pBaseDirectory, oDateDirectory)
|
||||
Return oFinalDirectory
|
||||
End Function
|
||||
|
||||
Public Function GetDateDirectory(pBaseDirectory As String) As String
|
||||
Return GetDateDirectory(pBaseDirectory, Now)
|
||||
End Function
|
||||
|
||||
Public Function CreateDateDirectory(pBaseDirectory As String, pDate As Date) As String
|
||||
Dim oDateDirectory = GetDateString(pDate)
|
||||
Dim oFinalDirectory As String = IO.Path.Combine(pBaseDirectory, oDateDirectory)
|
||||
|
||||
If IO.Directory.Exists(oFinalDirectory) = False Then
|
||||
_Logger.Debug("Path does not exist, creating: [{0}]", oFinalDirectory)
|
||||
Try
|
||||
Directory.CreateDirectory(oFinalDirectory)
|
||||
_Logger.Debug("Created folder [{0}]", oFinalDirectory)
|
||||
Catch ex As Exception
|
||||
_Logger.Warn("Final path [{0}] could not be created!", oFinalDirectory)
|
||||
_Logger.Error(ex)
|
||||
End Try
|
||||
End If
|
||||
|
||||
Return oFinalDirectory
|
||||
End Function
|
||||
|
||||
Public Function CreateDateDirectory(pBaseDirectory As String) As String
|
||||
Return CreateDateDirectory(pBaseDirectory, Now)
|
||||
End Function
|
||||
|
||||
Public Function GetDateString() As String
|
||||
Return $"{Now:yyyy\\MM\\dd}"
|
||||
End Function
|
||||
|
||||
Public Function GetDateString(pDate As Date) As String
|
||||
Return $"{pDate:yyyy\\MM\\dd}"
|
||||
End Function
|
||||
|
||||
Public Function GetDateTimeString() As String
|
||||
Return $"{Now:yyyy-MM-dd_hh-mm-ffff}"
|
||||
End Function
|
||||
|
||||
Public Function GetDateTimeString(pDate As Date) As String
|
||||
Return $"{pDate:yyyy-MM-dd_hh-mm-ffff}"
|
||||
End Function
|
||||
|
||||
Public Function GetFilenameWithSuffix(pFilePath As String, pSuffix As String)
|
||||
Dim oFileInfo = New IO.FileInfo(pFilePath)
|
||||
Return GetFilenameWithSuffix(IO.Path.GetFileNameWithoutExtension(pFilePath), pSuffix, oFileInfo.Extension.Substring(1))
|
||||
End Function
|
||||
|
||||
Public Function GetFilenameWithSuffix(pBaseString As String, pSuffix As String, pExtension As String)
|
||||
Return $"{pBaseString}-{pSuffix}.{pExtension}"
|
||||
End Function
|
||||
|
||||
Public Function GetFilenameWithPrefix(pFilePath As String, pPrefix As String)
|
||||
Dim oFileInfo = New IO.FileInfo(pFilePath)
|
||||
Return GetFilenameWithSuffix(IO.Path.GetFileNameWithoutExtension(pFilePath), pPrefix, oFileInfo.Extension.Substring(1))
|
||||
End Function
|
||||
|
||||
Public Function GetFilenameWithPrefix(pBaseString As String, pPrefix As String, pExtension As String)
|
||||
Return $"{pPrefix}-{pBaseString}.{pExtension}"
|
||||
End Function
|
||||
End Class
|
||||
@@ -2,10 +2,20 @@
|
||||
|
||||
Public Class GraphicsEx
|
||||
|
||||
Public Shared Function GetBrightness(c As Color) As Single
|
||||
Return (c.R * 0.299F + c.G * 0.587F + c.B * 0.114F) / 256.0F
|
||||
''' <summary>
|
||||
''' Returns the brightness of a color as a number between 0 and 1
|
||||
''' </summary>
|
||||
''' <param name="pColor">The color to check</param>
|
||||
''' <returns>Low values for dark colors, high values for bright colors.</returns>
|
||||
Public Shared Function GetBrightness(pColor As Color) As Single
|
||||
Return (pColor.R * 0.299F + pColor.G * 0.587F + pColor.B * 0.114F) / 256.0F
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Returns a foreground/text color of either black or white, depending on the brightness of `pOtherColor`
|
||||
''' </summary>
|
||||
''' <param name="pOtherColor">The Background color whose brightness is determined</param>
|
||||
''' <returns>A text color which is either white or black</returns>
|
||||
Public Shared Function GetContrastedColor(pOtherColor As Color) As Color
|
||||
If GetBrightness(pOtherColor) < 0.55 Then
|
||||
Return Color.White
|
||||
@@ -13,4 +23,21 @@ Public Class GraphicsEx
|
||||
Return Color.Black
|
||||
End If
|
||||
End Function
|
||||
|
||||
Public Sub DrawRectangle(Bounds As Rectangle)
|
||||
Dim oContext As IntPtr
|
||||
oContext = NativeMethods.GetDC(IntPtr.Zero)
|
||||
|
||||
Try
|
||||
Dim g As Graphics
|
||||
g = Graphics.FromHdc(oContext)
|
||||
Try
|
||||
g.DrawRectangle(Pens.Red, Bounds)
|
||||
Finally
|
||||
g.Dispose()
|
||||
End Try
|
||||
Finally
|
||||
NativeMethods.ReleaseDC(IntPtr.Zero, oContext)
|
||||
End Try
|
||||
End Sub
|
||||
End Class
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
Namespace IDB
|
||||
Public Class Attributes
|
||||
Public Const ATTRIBUTE_DOCTYPE = "Doctype"
|
||||
Public Const ATTRIBUTE_DYNAMIC_FOLDER = "Dynamic Folder"
|
||||
|
||||
Public Const ATTRIBUTE_ORIGIN_FILENAME = "OriginFileName"
|
||||
Public Const ATTRIBUTE_ORIGIN_CHANGED = "OriginChangedDatetime"
|
||||
Public Const ATTRIBUTE_ORIGIN_CREATED = "OriginCreationDatetime"
|
||||
|
||||
Public Const ATTRIBUTE_DISPLAY_FILENAME = "DisplayFileName"
|
||||
Public Const ATTRIBUTE_DISPLAY_FILENAME1 = "DisplayFileName1"
|
||||
|
||||
End Class
|
||||
|
||||
End Namespace
|
||||
43
Base/IDB/Constants.vb
Normal file
43
Base/IDB/Constants.vb
Normal file
@@ -0,0 +1,43 @@
|
||||
Namespace IDB
|
||||
|
||||
Public Class Constants
|
||||
Public Class FileStore
|
||||
Public Const FILE_STORE_INVALID_OBEJCT_ID = 0
|
||||
|
||||
Public Const FILE_CHANGED_QUESTION = "QUESTION VERSION"
|
||||
Public Const FILE_CHANGED_OVERWRITE = "AUTO REPLACE"
|
||||
Public Const FILE_CHANGED_VERSION = "AUTO VERSION"
|
||||
|
||||
Public Const OBJECT_STATE_FILE_ADDED = "File added"
|
||||
Public Const OBJECT_STATE_FILE_VERSIONED = "File versioned"
|
||||
Public Const OBJECT_STATE_FILE_CHANGED = "File changed"
|
||||
Public Const OBJECT_STATE_FILE_OPENED = "File opened"
|
||||
Public Const OBJECT_STATE_FILE_DELETED = "File deleted"
|
||||
Public Const OBJECT_STATE_METADATA_CHANGED = "Metadata changed"
|
||||
Public Const OBJECT_STATE_ATTRIBUTEVALUE_DELETED = "Attributevalue deleted"
|
||||
Public Const OBJECT_STATE_FILE_CHECKED_OUT = "File Checked Out"
|
||||
Public Const OBJECT_STATE_FILE_CHECKED_IN = "File Checked In"
|
||||
End Class
|
||||
|
||||
Public Class Database
|
||||
Public Enum NamedDatabase
|
||||
ECM
|
||||
IDB
|
||||
End Enum
|
||||
End Class
|
||||
|
||||
Public Class Attributes
|
||||
Public Const ATTRIBUTE_DOCTYPE = "Doctype"
|
||||
Public Const ATTRIBUTE_DYNAMIC_FOLDER = "Dynamic Folder"
|
||||
|
||||
Public Const ATTRIBUTE_ORIGIN_FILENAME = "OriginFileName"
|
||||
Public Const ATTRIBUTE_ORIGIN_CHANGED = "OriginChangedDatetime"
|
||||
Public Const ATTRIBUTE_ORIGIN_CREATED = "OriginCreationDatetime"
|
||||
|
||||
Public Const ATTRIBUTE_DISPLAY_FILENAME = "DisplayFileName"
|
||||
Public Const ATTRIBUTE_DISPLAY_FILENAME1 = "DisplayFileName1"
|
||||
|
||||
End Class
|
||||
End Class
|
||||
|
||||
End Namespace
|
||||
@@ -1,11 +0,0 @@
|
||||
|
||||
Namespace IDB
|
||||
Public Class Database
|
||||
Public Enum NamedDatabase
|
||||
ECM
|
||||
IDB
|
||||
End Enum
|
||||
End Class
|
||||
|
||||
End Namespace
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
Namespace IDB
|
||||
Public Class FileStore
|
||||
Public Const FILE_STORE_INVALID_OBEJCT_ID = 0
|
||||
|
||||
Public Const FILE_CHANGED_QUESTION = "QUESTION VERSION"
|
||||
Public Const FILE_CHANGED_OVERWRITE = "AUTO REPLACE"
|
||||
Public Const FILE_CHANGED_VERSION = "AUTO VERSION"
|
||||
|
||||
Public Const OBJECT_STATE_FILE_ADDED = "File added"
|
||||
Public Const OBJECT_STATE_FILE_VERSIONED = "File versioned"
|
||||
Public Const OBJECT_STATE_FILE_CHANGED = "File changed"
|
||||
Public Const OBJECT_STATE_FILE_OPENED = "File opened"
|
||||
Public Const OBJECT_STATE_FILE_DELETED = "File deleted"
|
||||
Public Const OBJECT_STATE_METADATA_CHANGED = "Metadata changed"
|
||||
Public Const OBJECT_STATE_ATTRIBUTEVALUE_DELETED = "Attributevalue deleted"
|
||||
Public Const OBJECT_STATE_FILE_CHECKED_OUT = "File Checked Out"
|
||||
Public Const OBJECT_STATE_FILE_CHECKED_IN = "File Checked In"
|
||||
End Class
|
||||
|
||||
End Namespace
|
||||
685
Base/MimeEx.vb
Normal file
685
Base/MimeEx.vb
Normal file
@@ -0,0 +1,685 @@
|
||||
Imports DigitalData.Modules.Logging
|
||||
|
||||
Public Class MimeEx
|
||||
Inherits BaseClass
|
||||
|
||||
Public Sub New(pLogConfig As LogConfig)
|
||||
MyBase.New(pLogConfig)
|
||||
End Sub
|
||||
|
||||
Public Function GetMimeType(ByVal extension As String) As String
|
||||
If extension Is Nothing Then
|
||||
Throw New ArgumentNullException("extension")
|
||||
End If
|
||||
|
||||
If Not extension.StartsWith(".") Then
|
||||
extension = "." & extension
|
||||
End If
|
||||
|
||||
Dim value = Nothing
|
||||
|
||||
If Not _mappings.Value.TryGetValue(extension, value) Then
|
||||
Return "application/octet-stream"
|
||||
End If
|
||||
|
||||
Return value
|
||||
End Function
|
||||
|
||||
Public Function GetExtension(ByVal mimeType As String) As String
|
||||
If mimeType Is Nothing Then
|
||||
Throw New ArgumentNullException("mimeType")
|
||||
End If
|
||||
|
||||
If mimeType.StartsWith(".") Then
|
||||
Throw New ArgumentException("Requested mime type is not valid: " & mimeType)
|
||||
End If
|
||||
|
||||
Dim value = Nothing
|
||||
|
||||
If _mappings.Value.TryGetValue(mimeType, value) Then
|
||||
Return value
|
||||
End If
|
||||
|
||||
Throw New ArgumentException("Requested mime type is not registered: " & mimeType)
|
||||
End Function
|
||||
|
||||
Private ReadOnly _mappings As New Lazy(Of IDictionary(Of String, String))(AddressOf BuildMappings)
|
||||
|
||||
Private Function BuildMappings() As IDictionary(Of String, String)
|
||||
Dim dictionary As New Dictionary(Of String, String)(StringComparer.InvariantCultureIgnoreCase) From {
|
||||
{".323", "text/h323"},
|
||||
{".3g2", "video/3gpp2"},
|
||||
{".3gp", "video/3gpp"},
|
||||
{".3gp2", "video/3gpp2"},
|
||||
{".3gpp", "video/3gpp"},
|
||||
{".7z", "application/x-7z-compressed"},
|
||||
{".aa", "audio/audible"},
|
||||
{".AAC", "audio/aac"},
|
||||
{".aaf", "application/octet-stream"},
|
||||
{".aax", "audio/vnd.audible.aax"},
|
||||
{".ac3", "audio/ac3"},
|
||||
{".aca", "application/octet-stream"},
|
||||
{".accda", "application/msaccess.addin"},
|
||||
{".accdb", "application/msaccess"},
|
||||
{".accdc", "application/msaccess.cab"},
|
||||
{".accde", "application/msaccess"},
|
||||
{".accdr", "application/msaccess.runtime"},
|
||||
{".accdt", "application/msaccess"},
|
||||
{".accdw", "application/msaccess.webapplication"},
|
||||
{".accft", "application/msaccess.ftemplate"},
|
||||
{".acx", "application/internet-property-stream"},
|
||||
{".AddIn", "text/xml"},
|
||||
{".ade", "application/msaccess"},
|
||||
{".adobebridge", "application/x-bridge-url"},
|
||||
{".adp", "application/msaccess"},
|
||||
{".ADT", "audio/vnd.dlna.adts"},
|
||||
{".ADTS", "audio/aac"},
|
||||
{".afm", "application/octet-stream"},
|
||||
{".ai", "application/postscript"},
|
||||
{".aif", "audio/x-aiff"},
|
||||
{".aifc", "audio/aiff"},
|
||||
{".aiff", "audio/aiff"},
|
||||
{".air", "application/vnd.adobe.air-application-installer-package+zip"},
|
||||
{".amc", "application/x-mpeg"},
|
||||
{".application", "application/x-ms-application"},
|
||||
{".art", "image/x-jg"},
|
||||
{".asa", "application/xml"},
|
||||
{".asax", "application/xml"},
|
||||
{".ascx", "application/xml"},
|
||||
{".asd", "application/octet-stream"},
|
||||
{".asf", "video/x-ms-asf"},
|
||||
{".ashx", "application/xml"},
|
||||
{".asi", "application/octet-stream"},
|
||||
{".asm", "text/plain"},
|
||||
{".asmx", "application/xml"},
|
||||
{".aspx", "application/xml"},
|
||||
{".asr", "video/x-ms-asf"},
|
||||
{".asx", "video/x-ms-asf"},
|
||||
{".atom", "application/atom+xml"},
|
||||
{".au", "audio/basic"},
|
||||
{".avi", "video/x-msvideo"},
|
||||
{".axs", "application/olescript"},
|
||||
{".bas", "text/plain"},
|
||||
{".bcpio", "application/x-bcpio"},
|
||||
{".bin", "application/octet-stream"},
|
||||
{".bmp", "image/bmp"},
|
||||
{".c", "text/plain"},
|
||||
{".cab", "application/octet-stream"},
|
||||
{".caf", "audio/x-caf"},
|
||||
{".calx", "application/vnd.ms-office.calx"},
|
||||
{".cat", "application/vnd.ms-pki.seccat"},
|
||||
{".cc", "text/plain"},
|
||||
{".cd", "text/plain"},
|
||||
{".cdda", "audio/aiff"},
|
||||
{".cdf", "application/x-cdf"},
|
||||
{".cer", "application/x-x509-ca-cert"},
|
||||
{".chm", "application/octet-stream"},
|
||||
{".class", "application/x-java-applet"},
|
||||
{".clp", "application/x-msclip"},
|
||||
{".cmx", "image/x-cmx"},
|
||||
{".cnf", "text/plain"},
|
||||
{".cod", "image/cis-cod"},
|
||||
{".config", "application/xml"},
|
||||
{".contact", "text/x-ms-contact"},
|
||||
{".coverage", "application/xml"},
|
||||
{".cpio", "application/x-cpio"},
|
||||
{".cpp", "text/plain"},
|
||||
{".crd", "application/x-mscardfile"},
|
||||
{".crl", "application/pkix-crl"},
|
||||
{".crt", "application/x-x509-ca-cert"},
|
||||
{".cs", "text/plain"},
|
||||
{".csdproj", "text/plain"},
|
||||
{".csh", "application/x-csh"},
|
||||
{".csproj", "text/plain"},
|
||||
{".css", "text/css"},
|
||||
{".csv", "text/csv"},
|
||||
{".cur", "application/octet-stream"},
|
||||
{".cxx", "text/plain"},
|
||||
{".dat", "application/octet-stream"},
|
||||
{".datasource", "application/xml"},
|
||||
{".dbproj", "text/plain"},
|
||||
{".dcr", "application/x-director"},
|
||||
{".def", "text/plain"},
|
||||
{".deploy", "application/octet-stream"},
|
||||
{".der", "application/x-x509-ca-cert"},
|
||||
{".dgml", "application/xml"},
|
||||
{".dib", "image/bmp"},
|
||||
{".dif", "video/x-dv"},
|
||||
{".dir", "application/x-director"},
|
||||
{".disco", "text/xml"},
|
||||
{".divx", "video/divx"},
|
||||
{".dll", "application/x-msdownload"},
|
||||
{".dll.config", "text/xml"},
|
||||
{".dlm", "text/dlm"},
|
||||
{".doc", "application/msword"},
|
||||
{".docm", "application/vnd.ms-word.document.macroEnabled.12"},
|
||||
{".docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"},
|
||||
{".dot", "application/msword"},
|
||||
{".dotm", "application/vnd.ms-word.template.macroEnabled.12"},
|
||||
{".dotx", "application/vnd.openxmlformats-officedocument.wordprocessingml.template"},
|
||||
{".dsp", "application/octet-stream"},
|
||||
{".dsw", "text/plain"},
|
||||
{".dtd", "text/xml"},
|
||||
{".dtsConfig", "text/xml"},
|
||||
{".dv", "video/x-dv"},
|
||||
{".dvi", "application/x-dvi"},
|
||||
{".dwf", "drawing/x-dwf"},
|
||||
{".dwp", "application/octet-stream"},
|
||||
{".dxr", "application/x-director"},
|
||||
{".eml", "message/rfc822"},
|
||||
{".emz", "application/octet-stream"},
|
||||
{".eot", "application/octet-stream"},
|
||||
{".eps", "application/postscript"},
|
||||
{".etl", "application/etl"},
|
||||
{".etx", "text/x-setext"},
|
||||
{".evy", "application/envoy"},
|
||||
{".exe", "application/octet-stream"},
|
||||
{".exe.config", "text/xml"},
|
||||
{".fdf", "application/vnd.fdf"},
|
||||
{".fif", "application/fractals"},
|
||||
{".filters", "application/xml"},
|
||||
{".fla", "application/octet-stream"},
|
||||
{".flr", "x-world/x-vrml"},
|
||||
{".flv", "video/x-flv"},
|
||||
{".fsscript", "application/fsharp-script"},
|
||||
{".fsx", "application/fsharp-script"},
|
||||
{".generictest", "application/xml"},
|
||||
{".gif", "image/gif"},
|
||||
{".group", "text/x-ms-group"},
|
||||
{".gsm", "audio/x-gsm"},
|
||||
{".gtar", "application/x-gtar"},
|
||||
{".gz", "application/x-gzip"},
|
||||
{".h", "text/plain"},
|
||||
{".hdf", "application/x-hdf"},
|
||||
{".hdml", "text/x-hdml"},
|
||||
{".hhc", "application/x-oleobject"},
|
||||
{".hhk", "application/octet-stream"},
|
||||
{".hhp", "application/octet-stream"},
|
||||
{".hlp", "application/winhlp"},
|
||||
{".hpp", "text/plain"},
|
||||
{".hqx", "application/mac-binhex40"},
|
||||
{".hta", "application/hta"},
|
||||
{".htc", "text/x-component"},
|
||||
{".htm", "text/html"},
|
||||
{".html", "text/html"},
|
||||
{".htt", "text/webviewhtml"},
|
||||
{".hxa", "application/xml"},
|
||||
{".hxc", "application/xml"},
|
||||
{".hxd", "application/octet-stream"},
|
||||
{".hxe", "application/xml"},
|
||||
{".hxf", "application/xml"},
|
||||
{".hxh", "application/octet-stream"},
|
||||
{".hxi", "application/octet-stream"},
|
||||
{".hxk", "application/xml"},
|
||||
{".hxq", "application/octet-stream"},
|
||||
{".hxr", "application/octet-stream"},
|
||||
{".hxs", "application/octet-stream"},
|
||||
{".hxt", "text/html"},
|
||||
{".hxv", "application/xml"},
|
||||
{".hxw", "application/octet-stream"},
|
||||
{".hxx", "text/plain"},
|
||||
{".i", "text/plain"},
|
||||
{".ico", "image/x-icon"},
|
||||
{".ics", "application/octet-stream"},
|
||||
{".idl", "text/plain"},
|
||||
{".ief", "image/ief"},
|
||||
{".iii", "application/x-iphone"},
|
||||
{".inc", "text/plain"},
|
||||
{".inf", "application/octet-stream"},
|
||||
{".inl", "text/plain"},
|
||||
{".ins", "application/x-internet-signup"},
|
||||
{".ipa", "application/x-itunes-ipa"},
|
||||
{".ipg", "application/x-itunes-ipg"},
|
||||
{".ipproj", "text/plain"},
|
||||
{".ipsw", "application/x-itunes-ipsw"},
|
||||
{".iqy", "text/x-ms-iqy"},
|
||||
{".isp", "application/x-internet-signup"},
|
||||
{".ite", "application/x-itunes-ite"},
|
||||
{".itlp", "application/x-itunes-itlp"},
|
||||
{".itms", "application/x-itunes-itms"},
|
||||
{".itpc", "application/x-itunes-itpc"},
|
||||
{".IVF", "video/x-ivf"},
|
||||
{".jar", "application/java-archive"},
|
||||
{".java", "application/octet-stream"},
|
||||
{".jck", "application/liquidmotion"},
|
||||
{".jcz", "application/liquidmotion"},
|
||||
{".jfif", "image/pjpeg"},
|
||||
{".jnlp", "application/x-java-jnlp-file"},
|
||||
{".jpb", "application/octet-stream"},
|
||||
{".jpe", "image/jpeg"},
|
||||
{".jpeg", "image/jpeg"},
|
||||
{".jpg", "image/jpeg"},
|
||||
{".js", "application/x-javascript"},
|
||||
{".json", "application/json"},
|
||||
{".jsx", "text/jscript"},
|
||||
{".jsxbin", "text/plain"},
|
||||
{".latex", "application/x-latex"},
|
||||
{".library-ms", "application/windows-library+xml"},
|
||||
{".lit", "application/x-ms-reader"},
|
||||
{".loadtest", "application/xml"},
|
||||
{".lpk", "application/octet-stream"},
|
||||
{".lsf", "video/x-la-asf"},
|
||||
{".lst", "text/plain"},
|
||||
{".lsx", "video/x-la-asf"},
|
||||
{".lzh", "application/octet-stream"},
|
||||
{".m13", "application/x-msmediaview"},
|
||||
{".m14", "application/x-msmediaview"},
|
||||
{".m1v", "video/mpeg"},
|
||||
{".m2t", "video/vnd.dlna.mpeg-tts"},
|
||||
{".m2ts", "video/vnd.dlna.mpeg-tts"},
|
||||
{".m2v", "video/mpeg"},
|
||||
{".m3u", "audio/x-mpegurl"},
|
||||
{".m3u8", "audio/x-mpegurl"},
|
||||
{".m4a", "audio/m4a"},
|
||||
{".m4b", "audio/m4b"},
|
||||
{".m4p", "audio/m4p"},
|
||||
{".m4r", "audio/x-m4r"},
|
||||
{".m4v", "video/x-m4v"},
|
||||
{".mac", "image/x-macpaint"},
|
||||
{".mak", "text/plain"},
|
||||
{".man", "application/x-troff-man"},
|
||||
{".manifest", "application/x-ms-manifest"},
|
||||
{".map", "text/plain"},
|
||||
{".master", "application/xml"},
|
||||
{".mda", "application/msaccess"},
|
||||
{".mdb", "application/x-msaccess"},
|
||||
{".mde", "application/msaccess"},
|
||||
{".mdp", "application/octet-stream"},
|
||||
{".me", "application/x-troff-me"},
|
||||
{".mfp", "application/x-shockwave-flash"},
|
||||
{".mht", "message/rfc822"},
|
||||
{".mhtml", "message/rfc822"},
|
||||
{".mid", "audio/mid"},
|
||||
{".midi", "audio/mid"},
|
||||
{".mix", "application/octet-stream"},
|
||||
{".mk", "text/plain"},
|
||||
{".mmf", "application/x-smaf"},
|
||||
{".mno", "text/xml"},
|
||||
{".mny", "application/x-msmoney"},
|
||||
{".mod", "video/mpeg"},
|
||||
{".mov", "video/quicktime"},
|
||||
{".movie", "video/x-sgi-movie"},
|
||||
{".mp2", "video/mpeg"},
|
||||
{".mp2v", "video/mpeg"},
|
||||
{".mp3", "audio/mpeg"},
|
||||
{".mp4", "video/mp4"},
|
||||
{".mp4v", "video/mp4"},
|
||||
{".mpa", "video/mpeg"},
|
||||
{".mpe", "video/mpeg"},
|
||||
{".mpeg", "video/mpeg"},
|
||||
{".mpf", "application/vnd.ms-mediapackage"},
|
||||
{".mpg", "video/mpeg"},
|
||||
{".mpp", "application/vnd.ms-project"},
|
||||
{".mpv2", "video/mpeg"},
|
||||
{".mqv", "video/quicktime"},
|
||||
{".ms", "application/x-troff-ms"},
|
||||
{".msg", "application/vnd.ms-outlook"},
|
||||
{".msi", "application/octet-stream"},
|
||||
{".mso", "application/octet-stream"},
|
||||
{".mts", "video/vnd.dlna.mpeg-tts"},
|
||||
{".mtx", "application/xml"},
|
||||
{".mvb", "application/x-msmediaview"},
|
||||
{".mvc", "application/x-miva-compiled"},
|
||||
{".mxp", "application/x-mmxp"},
|
||||
{".nc", "application/x-netcdf"},
|
||||
{".nsc", "video/x-ms-asf"},
|
||||
{".nws", "message/rfc822"},
|
||||
{".ocx", "application/octet-stream"},
|
||||
{".oda", "application/oda"},
|
||||
{".odb", "application/vnd.oasis.opendocument.database"},
|
||||
{".odc", "application/vnd.oasis.opendocument.chart"},
|
||||
{".odf", "application/vnd.oasis.opendocument.formula"},
|
||||
{".odg", "application/vnd.oasis.opendocument.graphics"},
|
||||
{".odh", "text/plain"},
|
||||
{".odi", "application/vnd.oasis.opendocument.image"},
|
||||
{".odl", "text/plain"},
|
||||
{".odm", "application/vnd.oasis.opendocument.text-master"},
|
||||
{".odp", "application/vnd.oasis.opendocument.presentation"},
|
||||
{".ods", "application/vnd.oasis.opendocument.spreadsheet"},
|
||||
{".odt", "application/vnd.oasis.opendocument.text"},
|
||||
{".ogv", "video/ogg"},
|
||||
{".one", "application/onenote"},
|
||||
{".onea", "application/onenote"},
|
||||
{".onepkg", "application/onenote"},
|
||||
{".onetmp", "application/onenote"},
|
||||
{".onetoc", "application/onenote"},
|
||||
{".onetoc2", "application/onenote"},
|
||||
{".orderedtest", "application/xml"},
|
||||
{".osdx", "application/opensearchdescription+xml"},
|
||||
{".otg", "application/vnd.oasis.opendocument.graphics-template"},
|
||||
{".oth", "application/vnd.oasis.opendocument.text-web"},
|
||||
{".otp", "application/vnd.oasis.opendocument.presentation-template"},
|
||||
{".ots", "application/vnd.oasis.opendocument.spreadsheet-template"},
|
||||
{".ott", "application/vnd.oasis.opendocument.text-template"},
|
||||
{".oxt", "application/vnd.openofficeorg.extension"},
|
||||
{".p10", "application/pkcs10"},
|
||||
{".p12", "application/x-pkcs12"},
|
||||
{".p7b", "application/x-pkcs7-certificates"},
|
||||
{".p7c", "application/pkcs7-mime"},
|
||||
{".p7m", "application/pkcs7-mime"},
|
||||
{".p7r", "application/x-pkcs7-certreqresp"},
|
||||
{".p7s", "application/pkcs7-signature"},
|
||||
{".pbm", "image/x-portable-bitmap"},
|
||||
{".pcast", "application/x-podcast"},
|
||||
{".pct", "image/pict"},
|
||||
{".pcx", "application/octet-stream"},
|
||||
{".pcz", "application/octet-stream"},
|
||||
{".pdf", "application/pdf"},
|
||||
{".pfb", "application/octet-stream"},
|
||||
{".pfm", "application/octet-stream"},
|
||||
{".pfx", "application/x-pkcs12"},
|
||||
{".pgm", "image/x-portable-graymap"},
|
||||
{".pic", "image/pict"},
|
||||
{".pict", "image/pict"},
|
||||
{".pkgdef", "text/plain"},
|
||||
{".pkgundef", "text/plain"},
|
||||
{".pko", "application/vnd.ms-pki.pko"},
|
||||
{".pls", "audio/scpls"},
|
||||
{".pma", "application/x-perfmon"},
|
||||
{".pmc", "application/x-perfmon"},
|
||||
{".pml", "application/x-perfmon"},
|
||||
{".pmr", "application/x-perfmon"},
|
||||
{".pmw", "application/x-perfmon"},
|
||||
{".png", "image/png"},
|
||||
{".pnm", "image/x-portable-anymap"},
|
||||
{".pnt", "image/x-macpaint"},
|
||||
{".pntg", "image/x-macpaint"},
|
||||
{".pnz", "image/png"},
|
||||
{".pot", "application/vnd.ms-powerpoint"},
|
||||
{".potm", "application/vnd.ms-powerpoint.template.macroEnabled.12"},
|
||||
{".potx", "application/vnd.openxmlformats-officedocument.presentationml.template"},
|
||||
{".ppa", "application/vnd.ms-powerpoint"},
|
||||
{".ppam", "application/vnd.ms-powerpoint.addin.macroEnabled.12"},
|
||||
{".ppm", "image/x-portable-pixmap"},
|
||||
{".pps", "application/vnd.ms-powerpoint"},
|
||||
{".ppsm", "application/vnd.ms-powerpoint.slideshow.macroEnabled.12"},
|
||||
{".ppsx", "application/vnd.openxmlformats-officedocument.presentationml.slideshow"},
|
||||
{".ppt", "application/vnd.ms-powerpoint"},
|
||||
{".pptm", "application/vnd.ms-powerpoint.presentation.macroEnabled.12"},
|
||||
{".pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation"},
|
||||
{".prf", "application/pics-rules"},
|
||||
{".prm", "application/octet-stream"},
|
||||
{".prx", "application/octet-stream"},
|
||||
{".ps", "application/postscript"},
|
||||
{".psc1", "application/PowerShell"},
|
||||
{".psd", "application/octet-stream"},
|
||||
{".psess", "application/xml"},
|
||||
{".psm", "application/octet-stream"},
|
||||
{".psp", "application/octet-stream"},
|
||||
{".pub", "application/x-mspublisher"},
|
||||
{".pwz", "application/vnd.ms-powerpoint"},
|
||||
{".qht", "text/x-html-insertion"},
|
||||
{".qhtm", "text/x-html-insertion"},
|
||||
{".qt", "video/quicktime"},
|
||||
{".qti", "image/x-quicktime"},
|
||||
{".qtif", "image/x-quicktime"},
|
||||
{".qtl", "application/x-quicktimeplayer"},
|
||||
{".qxd", "application/octet-stream"},
|
||||
{".ra", "audio/x-pn-realaudio"},
|
||||
{".ram", "audio/x-pn-realaudio"},
|
||||
{".rar", "application/octet-stream"},
|
||||
{".ras", "image/x-cmu-raster"},
|
||||
{".rat", "application/rat-file"},
|
||||
{".rc", "text/plain"},
|
||||
{".rc2", "text/plain"},
|
||||
{".rct", "text/plain"},
|
||||
{".rdlc", "application/xml"},
|
||||
{".resx", "application/xml"},
|
||||
{".rf", "image/vnd.rn-realflash"},
|
||||
{".rgb", "image/x-rgb"},
|
||||
{".rgs", "text/plain"},
|
||||
{".rm", "application/vnd.rn-realmedia"},
|
||||
{".rmi", "audio/mid"},
|
||||
{".rmp", "application/vnd.rn-rn_music_package"},
|
||||
{".roff", "application/x-troff"},
|
||||
{".rpm", "audio/x-pn-realaudio-plugin"},
|
||||
{".rqy", "text/x-ms-rqy"},
|
||||
{".rtf", "application/rtf"},
|
||||
{".rtx", "text/richtext"},
|
||||
{".ruleset", "application/xml"},
|
||||
{".s", "text/plain"},
|
||||
{".safariextz", "application/x-safari-safariextz"},
|
||||
{".scd", "application/x-msschedule"},
|
||||
{".sct", "text/scriptlet"},
|
||||
{".sd2", "audio/x-sd2"},
|
||||
{".sdp", "application/sdp"},
|
||||
{".sea", "application/octet-stream"},
|
||||
{".searchConnector-ms", "application/windows-search-connector+xml"},
|
||||
{".setpay", "application/set-payment-initiation"},
|
||||
{".setreg", "application/set-registration-initiation"},
|
||||
{".settings", "application/xml"},
|
||||
{".sgimb", "application/x-sgimb"},
|
||||
{".sgml", "text/sgml"},
|
||||
{".sh", "application/x-sh"},
|
||||
{".shar", "application/x-shar"},
|
||||
{".shtml", "text/html"},
|
||||
{".sit", "application/x-stuffit"},
|
||||
{".sitemap", "application/xml"},
|
||||
{".skin", "application/xml"},
|
||||
{".sldm", "application/vnd.ms-powerpoint.slide.macroEnabled.12"},
|
||||
{".sldx", "application/vnd.openxmlformats-officedocument.presentationml.slide"},
|
||||
{".slk", "application/vnd.ms-excel"},
|
||||
{".sln", "text/plain"},
|
||||
{".slupkg-ms", "application/x-ms-license"},
|
||||
{".smd", "audio/x-smd"},
|
||||
{".smi", "application/octet-stream"},
|
||||
{".smx", "audio/x-smd"},
|
||||
{".smz", "audio/x-smd"},
|
||||
{".snd", "audio/basic"},
|
||||
{".snippet", "application/xml"},
|
||||
{".snp", "application/octet-stream"},
|
||||
{".sol", "text/plain"},
|
||||
{".sor", "text/plain"},
|
||||
{".spc", "application/x-pkcs7-certificates"},
|
||||
{".spl", "application/futuresplash"},
|
||||
{".src", "application/x-wais-source"},
|
||||
{".srf", "text/plain"},
|
||||
{".SSISDeploymentManifest", "text/xml"},
|
||||
{".ssm", "application/streamingmedia"},
|
||||
{".sst", "application/vnd.ms-pki.certstore"},
|
||||
{".stl", "application/vnd.ms-pki.stl"},
|
||||
{".sv4cpio", "application/x-sv4cpio"},
|
||||
{".sv4crc", "application/x-sv4crc"},
|
||||
{".svc", "application/xml"},
|
||||
{".svg", "image/svg+xml"},
|
||||
{".swf", "application/x-shockwave-flash"},
|
||||
{".t", "application/x-troff"},
|
||||
{".tar", "application/x-tar"},
|
||||
{".tcl", "application/x-tcl"},
|
||||
{".testrunconfig", "application/xml"},
|
||||
{".testsettings", "application/xml"},
|
||||
{".tex", "application/x-tex"},
|
||||
{".texi", "application/x-texinfo"},
|
||||
{".texinfo", "application/x-texinfo"},
|
||||
{".tgz", "application/x-compressed"},
|
||||
{".thmx", "application/vnd.ms-officetheme"},
|
||||
{".thn", "application/octet-stream"},
|
||||
{".tif", "image/tiff"},
|
||||
{".tiff", "image/tiff"},
|
||||
{".tlh", "text/plain"},
|
||||
{".tli", "text/plain"},
|
||||
{".toc", "application/octet-stream"},
|
||||
{".tr", "application/x-troff"},
|
||||
{".trm", "application/x-msterminal"},
|
||||
{".trx", "application/xml"},
|
||||
{".ts", "video/vnd.dlna.mpeg-tts"},
|
||||
{".tsv", "text/tab-separated-values"},
|
||||
{".ttf", "application/octet-stream"},
|
||||
{".tts", "video/vnd.dlna.mpeg-tts"},
|
||||
{".txt", "text/plain"},
|
||||
{".u32", "application/octet-stream"},
|
||||
{".uls", "text/iuls"},
|
||||
{".user", "text/plain"},
|
||||
{".ustar", "application/x-ustar"},
|
||||
{".vb", "text/plain"},
|
||||
{".vbdproj", "text/plain"},
|
||||
{".vbk", "video/mpeg"},
|
||||
{".vbproj", "text/plain"},
|
||||
{".vbs", "text/vbscript"},
|
||||
{".vcf", "text/x-vcard"},
|
||||
{".vcproj", "application/xml"},
|
||||
{".vcs", "text/plain"},
|
||||
{".vcxproj", "application/xml"},
|
||||
{".vddproj", "text/plain"},
|
||||
{".vdp", "text/plain"},
|
||||
{".vdproj", "text/plain"},
|
||||
{".vdx", "application/vnd.ms-visio.viewer"},
|
||||
{".vml", "text/xml"},
|
||||
{".vscontent", "application/xml"},
|
||||
{".vsct", "text/xml"},
|
||||
{".vsd", "application/vnd.visio"},
|
||||
{".vsi", "application/ms-vsi"},
|
||||
{".vsix", "application/vsix"},
|
||||
{".vsixlangpack", "text/xml"},
|
||||
{".vsixmanifest", "text/xml"},
|
||||
{".vsmdi", "application/xml"},
|
||||
{".vspscc", "text/plain"},
|
||||
{".vss", "application/vnd.visio"},
|
||||
{".vsscc", "text/plain"},
|
||||
{".vssettings", "text/xml"},
|
||||
{".vssscc", "text/plain"},
|
||||
{".vst", "application/vnd.visio"},
|
||||
{".vstemplate", "text/xml"},
|
||||
{".vsto", "application/x-ms-vsto"},
|
||||
{".vsw", "application/vnd.visio"},
|
||||
{".vsx", "application/vnd.visio"},
|
||||
{".vtx", "application/vnd.visio"},
|
||||
{".wav", "audio/wav"},
|
||||
{".wave", "audio/wav"},
|
||||
{".wax", "audio/x-ms-wax"},
|
||||
{".wbk", "application/msword"},
|
||||
{".wbmp", "image/vnd.wap.wbmp"},
|
||||
{".wcm", "application/vnd.ms-works"},
|
||||
{".wdb", "application/vnd.ms-works"},
|
||||
{".wdp", "image/vnd.ms-photo"},
|
||||
{".webarchive", "application/x-safari-webarchive"},
|
||||
{".webm", "video/webm"},
|
||||
{".webp", "image/webp"},
|
||||
{".webtest", "application/xml"},
|
||||
{".wiq", "application/xml"},
|
||||
{".wiz", "application/msword"},
|
||||
{".wks", "application/vnd.ms-works"},
|
||||
{".WLMP", "application/wlmoviemaker"},
|
||||
{".wlpginstall", "application/x-wlpg-detect"},
|
||||
{".wlpginstall3", "application/x-wlpg3-detect"},
|
||||
{".wm", "video/x-ms-wm"},
|
||||
{".wma", "audio/x-ms-wma"},
|
||||
{".wmd", "application/x-ms-wmd"},
|
||||
{".wmf", "application/x-msmetafile"},
|
||||
{".wml", "text/vnd.wap.wml"},
|
||||
{".wmlc", "application/vnd.wap.wmlc"},
|
||||
{".wmls", "text/vnd.wap.wmlscript"},
|
||||
{".wmlsc", "application/vnd.wap.wmlscriptc"},
|
||||
{".wmp", "video/x-ms-wmp"},
|
||||
{".wmv", "video/x-ms-wmv"},
|
||||
{".wmx", "video/x-ms-wmx"},
|
||||
{".wmz", "application/x-ms-wmz"},
|
||||
{".wpl", "application/vnd.ms-wpl"},
|
||||
{".wps", "application/vnd.ms-works"},
|
||||
{".wri", "application/x-mswrite"},
|
||||
{".wrl", "x-world/x-vrml"},
|
||||
{".wrz", "x-world/x-vrml"},
|
||||
{".wsc", "text/scriptlet"},
|
||||
{".wsdl", "text/xml"},
|
||||
{".wvx", "video/x-ms-wvx"},
|
||||
{".x", "application/directx"},
|
||||
{".xaf", "x-world/x-vrml"},
|
||||
{".xaml", "application/xaml+xml"},
|
||||
{".xap", "application/x-silverlight-app"},
|
||||
{".xbap", "application/x-ms-xbap"},
|
||||
{".xbm", "image/x-xbitmap"},
|
||||
{".xdr", "text/plain"},
|
||||
{".xht", "application/xhtml+xml"},
|
||||
{".xhtml", "application/xhtml+xml"},
|
||||
{".xla", "application/vnd.ms-excel"},
|
||||
{".xlam", "application/vnd.ms-excel.addin.macroEnabled.12"},
|
||||
{".xlc", "application/vnd.ms-excel"},
|
||||
{".xld", "application/vnd.ms-excel"},
|
||||
{".xlk", "application/vnd.ms-excel"},
|
||||
{".xll", "application/vnd.ms-excel"},
|
||||
{".xlm", "application/vnd.ms-excel"},
|
||||
{".xls", "application/vnd.ms-excel"},
|
||||
{".xlsb", "application/vnd.ms-excel.sheet.binary.macroEnabled.12"},
|
||||
{".xlsm", "application/vnd.ms-excel.sheet.macroEnabled.12"},
|
||||
{".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"},
|
||||
{".xlt", "application/vnd.ms-excel"},
|
||||
{".xltm", "application/vnd.ms-excel.template.macroEnabled.12"},
|
||||
{".xltx", "application/vnd.openxmlformats-officedocument.spreadsheetml.template"},
|
||||
{".xlw", "application/vnd.ms-excel"},
|
||||
{".xml", "text/xml"},
|
||||
{".xmta", "application/xml"},
|
||||
{".xof", "x-world/x-vrml"},
|
||||
{".XOML", "text/plain"},
|
||||
{".xpm", "image/x-xpixmap"},
|
||||
{".xps", "application/vnd.ms-xpsdocument"},
|
||||
{".xrm-ms", "text/xml"},
|
||||
{".xsc", "application/xml"},
|
||||
{".xsd", "text/xml"},
|
||||
{".xsf", "text/xml"},
|
||||
{".xsl", "text/xml"},
|
||||
{".xslt", "text/xml"},
|
||||
{".xsn", "application/octet-stream"},
|
||||
{".xss", "application/xml"},
|
||||
{".xtp", "application/octet-stream"},
|
||||
{".xwd", "image/x-xwindowdump"},
|
||||
{".z", "application/x-compress"},
|
||||
{".zip", "application/x-zip-compressed"},
|
||||
{"application/fsharp-script", ".fsx"},
|
||||
{"application/msaccess", ".adp"},
|
||||
{"application/msword", ".doc"},
|
||||
{"application/octet-stream", ".bin"},
|
||||
{"application/onenote", ".one"},
|
||||
{"application/postscript", ".eps"},
|
||||
{"application/vnd.ms-excel", ".xls"},
|
||||
{"application/vnd.ms-powerpoint", ".ppt"},
|
||||
{"application/vnd.ms-works", ".wks"},
|
||||
{"application/vnd.visio", ".vsd"},
|
||||
{"application/x-director", ".dir"},
|
||||
{"application/x-shockwave-flash", ".swf"},
|
||||
{"application/x-x509-ca-cert", ".cer"},
|
||||
{"application/xhtml+xml", ".xhtml"},
|
||||
{"application/xml", ".xml"},
|
||||
{"audio/aac", ".AAC"},
|
||||
{"audio/aiff", ".aiff"},
|
||||
{"audio/basic", ".snd"},
|
||||
{"audio/mid", ".midi"},
|
||||
{"audio/wav", ".wav"},
|
||||
{"audio/x-mpegurl", ".m3u"},
|
||||
{"audio/x-pn-realaudio", ".ra"},
|
||||
{"audio/x-smd", ".smd"},
|
||||
{"image/bmp", ".bmp"},
|
||||
{"image/jpeg", ".jpg"},
|
||||
{"image/pict", ".pic"},
|
||||
{"image/png", ".png"},
|
||||
{"image/tiff", ".tiff"},
|
||||
{"image/x-macpaint", ".mac"},
|
||||
{"image/x-quicktime", ".qti"},
|
||||
{"message/rfc822", ".eml"},
|
||||
{"text/html", ".html"},
|
||||
{"text/plain", ".txt"},
|
||||
{"text/scriptlet", ".wsc"},
|
||||
{"text/xml", ".xml"},
|
||||
{"video/3gpp", ".3gp"},
|
||||
{"video/3gpp2", ".3gp2"},
|
||||
{"video/mp4", ".mp4"},
|
||||
{"video/mpeg", ".mpg"},
|
||||
{"video/quicktime", ".mov"},
|
||||
{"video/vnd.dlna.mpeg-tts", ".m2t"},
|
||||
{"video/x-dv", ".dv"},
|
||||
{"video/x-la-asf", ".lsf"},
|
||||
{"video/x-ms-asf", ".asf"},
|
||||
{"x-world/x-vrml", ".xof"}
|
||||
}
|
||||
Dim dictionary2 As Dictionary(Of String, String) = dictionary
|
||||
Dim list As List(Of KeyValuePair(Of String, String)) = dictionary2.ToList()
|
||||
|
||||
For Each item As KeyValuePair(Of String, String) In list
|
||||
|
||||
If Not dictionary2.ContainsKey(item.Value) Then
|
||||
dictionary2.Add(item.Value, item.Key)
|
||||
End If
|
||||
Next
|
||||
|
||||
Return dictionary2
|
||||
End Function
|
||||
End Class
|
||||
@@ -1,4 +1,5 @@
|
||||
Imports System.Runtime.CompilerServices
|
||||
Imports System.Web
|
||||
|
||||
Public Module ModuleExtensions
|
||||
Const UnixEraStartTicks As Long = 621355968000000000
|
||||
@@ -18,6 +19,15 @@ Public Module ModuleExtensions
|
||||
Return New Date(UnixEraStartTicks + pTimestamp * 10000)
|
||||
End Function
|
||||
|
||||
' ======================================================
|
||||
' === LIST
|
||||
' ======================================================
|
||||
|
||||
<Extension()>
|
||||
Public Function JoinToString(pList As IEnumerable(Of String), pSeparator As Char)
|
||||
Return String.Join(pSeparator, pList)
|
||||
End Function
|
||||
|
||||
' ======================================================
|
||||
' === STRING
|
||||
' ======================================================
|
||||
@@ -55,6 +65,45 @@ Public Module ModuleExtensions
|
||||
Return (pString.Trim().ToLower() = "true") OrElse (pString.Trim() = "1")
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Checks if a string is null or empty
|
||||
''' </summary>
|
||||
''' <param name="pString">The input string</param>
|
||||
''' <returns>True string is null or empty, otherwise false.</returns>
|
||||
<Extension()>
|
||||
Public Function IsNullOrEmpty(pString As String) As Boolean
|
||||
Return String.IsNullOrEmpty(pString)
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Checks if a string is NOT null or empty
|
||||
''' </summary>
|
||||
''' <param name="pString">The input string</param>
|
||||
''' <returns>True string is null or empty, otherwise false.</returns>
|
||||
<Extension()>
|
||||
Public Function IsNotNullOrEmpty(pString As String) As Boolean
|
||||
If String.IsNullOrEmpty(pString) Then
|
||||
Return False
|
||||
Else
|
||||
Return True
|
||||
End If
|
||||
End Function
|
||||
|
||||
' ======================================================
|
||||
' === DICTIONARY
|
||||
' ======================================================
|
||||
|
||||
<Extension()>
|
||||
Public Function ToURLQueryString(pDictionary As IDictionary(Of String, String)) As String
|
||||
Dim oQueryString = HttpUtility.ParseQueryString(String.Empty)
|
||||
|
||||
For Each oItem As KeyValuePair(Of String, String) In pDictionary
|
||||
oQueryString.Add(oItem.Key, oItem.Value)
|
||||
Next
|
||||
|
||||
Return oQueryString.ToString()
|
||||
End Function
|
||||
|
||||
' ======================================================
|
||||
' === DATATABLE
|
||||
' ======================================================
|
||||
@@ -62,6 +111,7 @@ Public Module ModuleExtensions
|
||||
<Extension()>
|
||||
Public Function ItemEx(Of T)(pRow As DataRow, pFieldName As String, Optional pDefaultValue As T = Nothing) As T
|
||||
Try
|
||||
If TableContainsColumn(pRow.Table, pFieldName) = False Then Return pDefaultValue
|
||||
Return ObjectEx.NotNull(pRow.Item(pFieldName), pDefaultValue)
|
||||
Catch ex As Exception
|
||||
Return Nothing
|
||||
@@ -71,6 +121,7 @@ Public Module ModuleExtensions
|
||||
<Extension()>
|
||||
Public Function ItemEx(Of T)(pRow As DataRow, pFieldIndex As Integer, Optional pDefaultValue As T = Nothing) As T
|
||||
Try
|
||||
If TableContainsColumn(pRow.Table, pFieldIndex) = False Then Return pDefaultValue
|
||||
Return ObjectEx.NotNull(pRow.Item(pFieldIndex), pDefaultValue)
|
||||
Catch ex As Exception
|
||||
Return Nothing
|
||||
@@ -98,4 +149,26 @@ Public Module ModuleExtensions
|
||||
Return Nothing
|
||||
End Try
|
||||
End Function
|
||||
|
||||
Private Function TableContainsColumn(pTable As DataTable, pColumnName As String) As Boolean
|
||||
Try
|
||||
If pTable Is Nothing Then Return False
|
||||
If String.IsNullOrEmpty(pColumnName) Then Return False
|
||||
|
||||
Return pTable.Columns.Contains(pColumnName)
|
||||
Catch ex As Exception
|
||||
Return False
|
||||
End Try
|
||||
End Function
|
||||
|
||||
Private Function TableContainsColumn(pTable As DataTable, pColumnIndex As Integer) As Boolean
|
||||
Try
|
||||
If pTable Is Nothing Then Return False
|
||||
If String.IsNullOrEmpty(pColumnIndex) Then Return False
|
||||
|
||||
Return pTable.Columns.Count > pColumnIndex
|
||||
Catch ex As Exception
|
||||
Return False
|
||||
End Try
|
||||
End Function
|
||||
End Module
|
||||
|
||||
@@ -8,12 +8,12 @@ Imports System.Runtime.InteropServices
|
||||
|
||||
' Werte der Assemblyattribute überprüfen
|
||||
|
||||
<Assembly: AssemblyTitle("Base")>
|
||||
<Assembly: AssemblyDescription("")>
|
||||
<Assembly: AssemblyCompany("")>
|
||||
<Assembly: AssemblyProduct("Base")>
|
||||
<Assembly: AssemblyCopyright("Copyright © 2023")>
|
||||
<Assembly: AssemblyTrademark("1.3.1.0")>
|
||||
<Assembly: AssemblyTitle("Modules.Base")>
|
||||
<Assembly: AssemblyDescription("basisfunktionalitäten für DigitalData Anwendungen")>
|
||||
<Assembly: AssemblyCompany("Digital Data GmbH")>
|
||||
<Assembly: AssemblyProduct("Modules.")>
|
||||
<Assembly: AssemblyCopyright("Copyright © 2025")>
|
||||
<Assembly: AssemblyTrademark("1.3.9.0")>
|
||||
|
||||
<Assembly: ComVisible(False)>
|
||||
|
||||
@@ -31,5 +31,5 @@ Imports System.Runtime.InteropServices
|
||||
' indem Sie "*" wie unten gezeigt eingeben:
|
||||
' <Assembly: AssemblyVersion("1.0.*")>
|
||||
|
||||
<Assembly: AssemblyVersion("1.3.1.0")>
|
||||
<Assembly: AssemblyFileVersion("1.3.1.0")>
|
||||
<Assembly: AssemblyVersion("1.3.9.0")>
|
||||
<Assembly: AssemblyFileVersion("1.3.9.0")>
|
||||
|
||||
237
Base/NativeMethods.vb
Normal file
237
Base/NativeMethods.vb
Normal file
@@ -0,0 +1,237 @@
|
||||
Imports System.Runtime.InteropServices
|
||||
Imports System.Text
|
||||
Imports DigitalData.Modules.Base.ScreenEx
|
||||
|
||||
Public Class NativeMethods
|
||||
Public Declare Function GetWindowTextLength Lib "user32.dll" Alias "GetWindowTextLengthA" (ByVal hwnd As Int32) As Integer
|
||||
Public Declare Function GetWindowText Lib "user32.dll" Alias "GetWindowTextA" (ByVal hWnd As IntPtr, ByVal WinTitle As String, ByVal MaxLength As Integer) As Integer
|
||||
<DllImport("Shell32", CharSet:=CharSet.Auto, SetLastError:=True)>
|
||||
Public Shared Function ShellExecuteEx(ByRef lpExecInfo As ShellExecuteInfo) As Boolean
|
||||
End Function
|
||||
<DllImport("user32", EntryPoint:="SetClipboardViewer")>
|
||||
Public Shared Function SetClipboardViewer(ByVal hWnd As IntPtr) As IntPtr
|
||||
End Function
|
||||
<DllImport("user32.dll")>
|
||||
Public Shared Function GetDC(ByVal hwnd As IntPtr) As IntPtr
|
||||
End Function
|
||||
<DllImport("user32.dll")>
|
||||
Public Shared Function ReleaseDC(ByVal hwnd As IntPtr, ByVal hdc As IntPtr) As IntPtr
|
||||
End Function
|
||||
<DllImport("User32.dll")>
|
||||
Public Shared Function ReleaseCapture() As Boolean
|
||||
End Function
|
||||
<DllImport("user32.dll")>
|
||||
Public Shared Function GetWindowRect(ByVal hWnd As HandleRef, ByRef lpRect As RectangleAPI) As Boolean
|
||||
End Function
|
||||
<DllImport("user32.dll")>
|
||||
Public Shared Function AttachThreadInput(ByVal idAttach As IntPtr, ByVal idAttachTo As IntPtr, fAttach As Boolean) As Boolean
|
||||
End Function
|
||||
<DllImport("user32.dll")>
|
||||
Public Shared Function GetFocus() As IntPtr
|
||||
End Function
|
||||
<DllImport("user32.dll")>
|
||||
Public Shared Function WindowFromPoint(ByVal p As PointAPI) As IntPtr
|
||||
End Function
|
||||
<DllImport("user32.dll")>
|
||||
Public Shared Function GetForegroundWindow() As IntPtr
|
||||
End Function
|
||||
<DllImport("user32.dll")>
|
||||
Public Shared Function GetWindowThreadProcessId(ByVal hwnd As IntPtr, ByRef lpdwProcessID As Integer) As Integer
|
||||
End Function
|
||||
<DllImport("user32.dll")>
|
||||
Public Shared Function GetClassName(ByVal hwnd As Integer, ByVal lpClassName As StringBuilder, ByVal nMaxCount As Integer) As Integer
|
||||
End Function
|
||||
<DllImport("kernel32.dll")>
|
||||
Public Shared Function OpenProcess(ByVal dwDesiredAccess As UInteger, ByVal bInheritHandle As Boolean, ByVal dwProcessId As UInteger) As IntPtr
|
||||
End Function
|
||||
<DllImport("kernel32.dll")>
|
||||
Public Shared Function VirtualAllocEx(ByVal hProcess As IntPtr, ByVal lpAddress As IntPtr, ByVal dwSize As UIntPtr, ByVal flAllocationType As UInteger, ByVal flProtect As PageProtection) As IntPtr
|
||||
End Function
|
||||
<DllImport("user32.dll", SetLastError:=True)>
|
||||
Public Shared Function GetWindowThreadProcessId(ByVal hWnd As IntPtr, <Out> ByRef lpdwProcessId As UInteger) As UInteger
|
||||
End Function
|
||||
<DllImport("kernel32.dll")>
|
||||
Public Shared Function VirtualFreeEx(ByVal hProcess As IntPtr, ByVal lpAddress As IntPtr, ByVal dwSize As UIntPtr, ByVal dwFreeType As UInteger) As Boolean
|
||||
End Function
|
||||
<DllImport("kernel32.dll")>
|
||||
Public Shared Function CloseHandle(ByVal hObject As IntPtr) As Boolean
|
||||
End Function
|
||||
<DllImport("kernel32.dll")>
|
||||
Public Shared Function MapViewOfFile(ByVal hFileMappingObject As IntPtr, ByVal dwDesiredAccess As UInteger, ByVal dwFileOffsetHigh As UInteger, ByVal dwFileOffsetLow As UInteger, ByVal dwNumberOfBytesToMap As UIntPtr) As IntPtr
|
||||
End Function
|
||||
<DllImport("kernel32.dll")>
|
||||
Public Shared Function UnmapViewOfFile(ByVal lpBaseAddress As IntPtr) As Boolean
|
||||
End Function
|
||||
<DllImport("kernel32.dll", SetLastError:=True)>
|
||||
Public Shared Function CreateFileMapping(ByVal hFile As IntPtr, ByVal lpFileMappingAttributes As IntPtr, ByVal flProtect As PageProtection, ByVal dwMaximumSizeHigh As Integer, ByVal dwMaximumSizeLow As Integer, ByVal lpName As String) As IntPtr
|
||||
End Function
|
||||
<DllImport("user32.dll")>
|
||||
Public Shared Function SendMessage(ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
|
||||
End Function
|
||||
<DllImport("kernel32.dll")>
|
||||
Public Shared Function ReadProcessMemory(ByVal hProcess As IntPtr, ByVal lpBaseAddress As IntPtr,
|
||||
<Out> ByVal lpBuffer As Byte(), ByVal nSize As UIntPtr, ByVal lpNumberOfBytesRead As IntPtr) As Boolean
|
||||
End Function
|
||||
<DllImport("Kernel32.dll", EntryPoint:="RtlMoveMemory", SetLastError:=False)>
|
||||
Public Shared Sub MoveMemoryFromByte(ByVal dest As IntPtr, ByRef src As Byte, ByVal size As Integer)
|
||||
End Sub
|
||||
<DllImport("Kernel32.dll", EntryPoint:="RtlMoveMemory", SetLastError:=False)>
|
||||
Public Shared Sub MoveMemoryToByte(ByRef dest As Byte, ByVal src As IntPtr, ByVal size As Integer)
|
||||
End Sub
|
||||
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
|
||||
Public Shared Function RegisterWindowMessage(ByVal lpString As String) As Integer
|
||||
End Function
|
||||
<DllImport("user32.dll", ExactSpelling:=True, SetLastError:=True)>
|
||||
Public Shared Function GetCursorPos(ByRef lpPoint As PointAPI) As <MarshalAs(UnmanagedType.Bool)> Boolean
|
||||
End Function
|
||||
<DllImport("User32.dll", SetLastError:=True)>
|
||||
Friend Shared Function MonitorFromWindow(ByVal hwnd As IntPtr,
|
||||
ByVal dwFlags As Integer) As IntPtr
|
||||
End Function
|
||||
<DllImport("Shcore.dll", SetLastError:=True)>
|
||||
Friend Shared Function GetDpiForMonitor(ByVal hmonitor As IntPtr,
|
||||
ByVal dpiType As Monitor_DPI_Type,
|
||||
ByRef dpiX As UInteger,
|
||||
ByRef dpiY As UInteger) As Integer
|
||||
End Function
|
||||
<DllImport("gdi32.dll")>
|
||||
Friend Shared Function GetDeviceCaps(ByVal hdc As IntPtr, ByVal nIndex As Integer) As Integer
|
||||
End Function
|
||||
|
||||
Public Declare Function RegisterHotKey Lib "user32" (
|
||||
ByVal Hwnd As IntPtr,
|
||||
ByVal ID As Integer,
|
||||
ByVal Modifiers As Integer,
|
||||
ByVal Key As Integer
|
||||
) As Integer
|
||||
|
||||
Public Declare Function UnregisterHotKey Lib "user32" (
|
||||
ByVal Hwnd As IntPtr,
|
||||
ByVal ID As Integer
|
||||
) As Integer
|
||||
|
||||
Public Declare Auto Function GetWindowText Lib "user32" (
|
||||
ByVal hWnd As IntPtr,
|
||||
ByVal lpString As StringBuilder,
|
||||
ByVal cch As Integer
|
||||
) As Integer
|
||||
|
||||
Public Declare Function GlobalAddAtom Lib "kernel32" Alias "GlobalAddAtomA" (ByVal IDString As String) As Short
|
||||
Public Declare Function GlobalDeleteAtom Lib "kernel32" (ByVal Atom As Short) As Short
|
||||
|
||||
Public Const STANDARD_RIGHTS_REQUIRED As Integer = &HF0000
|
||||
|
||||
Public Const SECTION_QUERY As Short = &H1
|
||||
Public Const SECTION_MAP_WRITE As Short = &H2
|
||||
Public Const SECTION_MAP_READ As Short = &H4
|
||||
Public Const SECTION_MAP_EXECUTE As Short = &H8
|
||||
Public Const SECTION_EXTEND_SIZE As Short = &H10
|
||||
Public Const SECTION_ALL_ACCESS As Integer = STANDARD_RIGHTS_REQUIRED Or SECTION_QUERY Or SECTION_MAP_WRITE Or SECTION_MAP_READ Or SECTION_MAP_EXECUTE Or SECTION_EXTEND_SIZE
|
||||
Public Const FILE_MAP_ALL_ACCESS As Integer = SECTION_ALL_ACCESS
|
||||
|
||||
Public Const PROCESS_VM_OPERATION As Short = &H8
|
||||
Public Const PROCESS_VM_READ As Short = &H10
|
||||
Public Const PROCESS_VM_WRITE As Short = &H20
|
||||
Public Const PROCESS_ALL_ACCESS As Long = &H1F0FFF
|
||||
|
||||
Public Const MEM_COMMIT As Short = &H1000
|
||||
Public Const MEM_RESERVE As Short = &H2000
|
||||
Public Const MEM_DECOMMIT As Short = &H4000
|
||||
Public Const MEM_RELEASE As Integer = &H8000
|
||||
Public Const MEM_FREE As Integer = &H10000
|
||||
Public Const MEM_PRIVATE As Integer = &H20000
|
||||
Public Const MEM_MAPPED As Integer = &H40000
|
||||
Public Const MEM_TOP_DOWN As Integer = &H100000
|
||||
|
||||
Public Const INVALID_HANDLE_VALUE As Integer = -1
|
||||
Public Const SW_SHOW As Short = 5
|
||||
|
||||
Public Const SEE_MASK_INVOKEIDLIST = &HC
|
||||
Public Const SEE_MASK_NOCLOSEPROCESS = &H40
|
||||
Public Const SEE_MASK_FLAG_NO_UI = &H400
|
||||
|
||||
Public Const ULW_COLORKEY As Integer = &H1
|
||||
Public Const ULW_ALPHA As Integer = &H2
|
||||
Public Const ULW_OPAQUE As Integer = &H4
|
||||
|
||||
Public Const AC_SRC_OVER As Byte = &H0
|
||||
Public Const AC_SRC_ALPHA As Byte = &H1
|
||||
|
||||
Public Const HTCAPTION As Integer = &H2
|
||||
|
||||
Public Const WM_NCLBUTTONDOWN As Integer = &HA1
|
||||
Public Const WM_HOTKEY As Integer = &H312
|
||||
Public Const WM_DRAWCLIPBOARD As Integer = &H308
|
||||
|
||||
Public Enum PageProtection As UInteger
|
||||
NoAccess = &H1
|
||||
[Readonly] = &H2
|
||||
ReadWrite = &H4
|
||||
WriteCopy = &H8
|
||||
Execute = &H10
|
||||
ExecuteRead = &H20
|
||||
ExecuteReadWrite = &H40
|
||||
ExecuteWriteCopy = &H80
|
||||
Guard = &H100
|
||||
NoCache = &H200
|
||||
WriteCombine = &H400
|
||||
End Enum
|
||||
|
||||
Public Enum ChildWindowFromPointFlags As UInteger
|
||||
CWP_ALL
|
||||
CWP_SKIPINVISIBLE
|
||||
CWP_SKIPDISABLED
|
||||
CWP_SKIPTRANSPARENT
|
||||
End Enum
|
||||
|
||||
<StructLayout(LayoutKind.Sequential)>
|
||||
Public Structure WINDOWPOS
|
||||
Public hwnd As IntPtr
|
||||
Public hwndInsertAfter As IntPtr
|
||||
Public x As Integer
|
||||
Public y As Integer
|
||||
Public cx As Integer
|
||||
Public cy As Integer
|
||||
Public flags As Integer
|
||||
End Structure
|
||||
|
||||
Public Structure RectangleAPI
|
||||
Public Left As Integer
|
||||
Public Top As Integer
|
||||
Public Right As Integer
|
||||
Public Bottom As Integer
|
||||
|
||||
Public Overrides Function ToString() As String
|
||||
Return String.Format("Top: {0}, Bottom: {1}, Left: {2}, Right: {3}", Top, Bottom, Left, Right)
|
||||
End Function
|
||||
End Structure
|
||||
|
||||
Public Structure ShellExecuteInfo
|
||||
Public cbSize As Integer
|
||||
Public fMask As Integer
|
||||
Public hwnd As IntPtr
|
||||
<MarshalAs(UnmanagedType.LPTStr)> Public lpVerb As String
|
||||
<MarshalAs(UnmanagedType.LPTStr)> Public lpFile As String
|
||||
<MarshalAs(UnmanagedType.LPTStr)> Public lpParameters As String
|
||||
<MarshalAs(UnmanagedType.LPTStr)> Public lpDirectory As String
|
||||
Dim nShow As Integer
|
||||
Dim hInstApp As IntPtr
|
||||
Dim lpIDList As IntPtr
|
||||
<MarshalAs(UnmanagedType.LPTStr)> Public lpClass As String
|
||||
Public hkeyClass As IntPtr
|
||||
Public dwHotKey As Integer
|
||||
Public hIcon As IntPtr
|
||||
Public hProcess As IntPtr
|
||||
End Structure
|
||||
|
||||
<System.Runtime.InteropServices.StructLayout(Runtime.InteropServices.LayoutKind.Sequential)>
|
||||
Public Structure PointAPI
|
||||
Public X As Integer
|
||||
Public Y As Integer
|
||||
|
||||
Public Sub New(ByVal X As Integer, ByVal Y As Integer)
|
||||
Me.X = X
|
||||
Me.Y = Y
|
||||
End Sub
|
||||
End Structure
|
||||
End Class
|
||||
@@ -1,44 +0,0 @@
|
||||
Imports System.IO
|
||||
Imports System.Reflection
|
||||
Imports System.Runtime.InteropServices
|
||||
Imports System.Security.Cryptography
|
||||
Imports DigitalData.Modules.Logging
|
||||
|
||||
Public Class PerformanceEx
|
||||
Public Sub New(pLogConfig As LogConfig, pAppDataPath As String)
|
||||
Dim savedHash = String.Empty
|
||||
Dim assemblyLocation = Assembly.GetEntryAssembly().Location
|
||||
|
||||
Dim hashPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "hash.txt")
|
||||
If Not File.Exists(hashPath) Then
|
||||
File.Create(hashPath)
|
||||
Else
|
||||
savedHash = File.ReadAllText(hashPath)
|
||||
End If
|
||||
|
||||
Dim hash = String.Concat(SHA1.Create().ComputeHash(File.ReadAllBytes(assemblyLocation)).Select(Function(x) x.ToString("x2")))
|
||||
If hash.Equals(savedHash) Then
|
||||
Return
|
||||
End If
|
||||
|
||||
Dim dotNetRuntimePath = RuntimeEnvironment.GetRuntimeDirectory()
|
||||
Dim ngenPath = Path.Combine(dotNetRuntimePath, "ngen.exe")
|
||||
|
||||
Dim process = New Process With {
|
||||
.StartInfo = New ProcessStartInfo With {
|
||||
.FileName = ngenPath,
|
||||
.Arguments = $"install ""{assemblyLocation}"" /nologo",
|
||||
.CreateNoWindow = True,
|
||||
.UseShellExecute = True,
|
||||
.Verb = "runas"
|
||||
}
|
||||
}
|
||||
Try
|
||||
process.Start()
|
||||
process.WaitForExit()
|
||||
File.WriteAllText(hashPath, hash)
|
||||
Catch
|
||||
' ...
|
||||
End Try
|
||||
End Sub
|
||||
End Class
|
||||
@@ -1,11 +1,30 @@
|
||||
Imports System
|
||||
Imports System.Drawing
|
||||
Imports System.Runtime.InteropServices
|
||||
Imports System.Windows.Forms
|
||||
Imports DigitalData.Modules.Base.NativeMethods
|
||||
|
||||
Public Class ScreenEx
|
||||
Public Const DEFAULT_WINDOW_HEIGHT = 480
|
||||
Public Const DEFAULT_WINDOW_WIDTH = 640
|
||||
|
||||
Friend Const MONITORINFOF_PRIMARY As Integer = &H1
|
||||
Friend Const MONITOR_DEFAULTTONEAREST As Integer = &H2
|
||||
Friend Const MONITOR_DEFAULTTONULL As Integer = &H0
|
||||
Friend Const MONITOR_DEFAULTTOPRIMARY As Integer = &H1
|
||||
|
||||
Friend Enum Monitor_DPI_Type As Integer
|
||||
MDT_Effective_DPI = 0
|
||||
MDT_Angular_DPI = 1
|
||||
MDT_Raw_DPI = 2
|
||||
MDT_Default = MDT_Effective_DPI
|
||||
End Enum
|
||||
|
||||
Private Enum DeviceCap
|
||||
VERTRES = 10
|
||||
DESKTOPVERTRES = 117
|
||||
End Enum
|
||||
|
||||
Public Shared Function GetLocationWithinScreen(pLocation As Point) As Point?
|
||||
For Each screen As Screen In Screen.AllScreens
|
||||
If screen.Bounds.Contains(pLocation) Then
|
||||
@@ -100,4 +119,45 @@ Public Class ScreenEx
|
||||
|
||||
Return False
|
||||
End Function
|
||||
|
||||
Public Function GetScreenScaling(Form As Form) As Single
|
||||
Dim oHandle As IntPtr = Form.Handle
|
||||
Dim oFactor1, oFactor2 As Single
|
||||
|
||||
oFactor1 = GetFactorFromDeviceCaps(oHandle)
|
||||
oFactor2 = GetDPIFromMonitor(oHandle)
|
||||
|
||||
If oFactor1 > 1 Then
|
||||
Return oFactor1
|
||||
Else
|
||||
Return oFactor2
|
||||
End If
|
||||
End Function
|
||||
|
||||
Private Function GetFactorFromDeviceCaps(Handle As IntPtr) As Single
|
||||
Dim g As Graphics = Graphics.FromHwnd(Handle)
|
||||
Dim desktop As IntPtr = g.GetHdc()
|
||||
Dim LogicalScreenHeight As Integer = GetDeviceCaps(desktop, DeviceCap.VERTRES)
|
||||
Dim PhysicalScreenHeight As Integer = GetDeviceCaps(desktop, DeviceCap.DESKTOPVERTRES)
|
||||
Dim oScreenScalingFactor As Single = CSng(PhysicalScreenHeight) / CSng(LogicalScreenHeight)
|
||||
Return oScreenScalingFactor
|
||||
End Function
|
||||
|
||||
Private Function GetDPIFromMonitor(Handle As IntPtr) As Single
|
||||
'Get handle to monitor that contains this window.
|
||||
Dim monitorHandle As IntPtr = MonitorFromWindow(Handle, MONITOR_DEFAULTTONEAREST)
|
||||
|
||||
'Get DPI (If the OS is not Windows 8.1 or newer, calling GetDpiForMonitor will cause exception).
|
||||
Dim dpiX As UInteger
|
||||
Dim dpiY As UInteger
|
||||
|
||||
Dim result As Integer = GetDpiForMonitor(monitorHandle, Monitor_DPI_Type.MDT_Default, dpiX, dpiY)
|
||||
|
||||
|
||||
If (result = 0) Then 'If S_OK (= 0)
|
||||
Return dpiX / 96.0F
|
||||
Else
|
||||
Return -1
|
||||
End If
|
||||
End Function
|
||||
End Class
|
||||
|
||||
@@ -12,7 +12,7 @@ Public Class StringEx
|
||||
''' And consecutive hyphens.
|
||||
''' </summary>
|
||||
''' <param name="s">The string to convert</param>
|
||||
Public Shared Function ConvertTextToSlug(ByVal s As String) As String
|
||||
Public Shared Function ConvertTextToSlug(s As String) As String
|
||||
Dim oBuilder As New StringBuilder()
|
||||
Dim oWasHyphen As Boolean = True
|
||||
|
||||
@@ -21,8 +21,13 @@ Public Class StringEx
|
||||
If Char.IsLetterOrDigit(oChar) Then
|
||||
oBuilder.Append(Char.ToLower(oChar))
|
||||
oWasHyphen = False
|
||||
|
||||
ElseIf oChar = "_"c Or oChar = "-"c Then
|
||||
oBuilder.Append(oChar)
|
||||
oWasHyphen = True
|
||||
|
||||
ElseIf Char.IsWhiteSpace(oChar) AndAlso Not oWasHyphen Then
|
||||
oBuilder.Append("-"c)
|
||||
oBuilder.Append("_"c)
|
||||
oWasHyphen = True
|
||||
End If
|
||||
Next
|
||||
@@ -107,6 +112,26 @@ Public Class StringEx
|
||||
Return GetChecksum(pStringToCheck)
|
||||
End Function
|
||||
|
||||
Public Shared Function GetShortHash(pStringToCheck As String) As String
|
||||
Return GetChecksum(pStringToCheck).Substring(0, 32)
|
||||
End Function
|
||||
|
||||
Public Shared Function GetDateString() As String
|
||||
Return $"{Now:yyyy\\MM\\dd}"
|
||||
End Function
|
||||
|
||||
Public Shared Function GetDateString(pDate As Date) As String
|
||||
Return $"{pDate:yyyy\\MM\\dd}"
|
||||
End Function
|
||||
|
||||
Public Shared Function GetDateTimeString() As String
|
||||
Return $"{Now:yyyy-MM-dd_hh-mm-ffff}"
|
||||
End Function
|
||||
|
||||
Public Shared Function GetDateTimeString(pDate As Date) As String
|
||||
Return $"{pDate:yyyy-MM-dd_hh-mm-ffff}"
|
||||
End Function
|
||||
|
||||
Friend Class InvalidChars
|
||||
Public Shared Filenames As String = Regex.Escape(New String(IO.Path.GetInvalidFileNameChars()))
|
||||
Public Shared Paths As String = Regex.Escape(New String(IO.Path.GetInvalidPathChars()))
|
||||
|
||||
64
Base/StringFunctions.vb
Normal file
64
Base/StringFunctions.vb
Normal file
@@ -0,0 +1,64 @@
|
||||
Imports System.Globalization
|
||||
Imports DigitalData.Modules.Logging
|
||||
|
||||
Public Class StringFunctions
|
||||
Public Shared Function SplitText_Length(ByVal input As String, ByVal maxLength As Integer) As List(Of String)
|
||||
Dim result As New List(Of String)
|
||||
|
||||
For i As Integer = 0 To input.Length - 1 Step maxLength
|
||||
' Textabschnitt extrahieren
|
||||
Dim chunk As String = input.Substring(i, Math.Min(maxLength, input.Length - i))
|
||||
result.Add(chunk)
|
||||
Next
|
||||
|
||||
Return result
|
||||
End Function
|
||||
Public Shared Function SplitTextByNewLine(text As String) As List(Of String)
|
||||
If String.IsNullOrEmpty(text) Then
|
||||
Return New List(Of String)()
|
||||
End If
|
||||
|
||||
' Zerlege den Text anhand von Zeilenumbrüchen
|
||||
Dim lines As List(Of String) = text.Split({vbCrLf, vbLf, vbCr}, StringSplitOptions.None).ToList()
|
||||
Return lines
|
||||
End Function
|
||||
|
||||
Public Shared Function DatetimeStringToGermanStringConverter(pDatetimeString As String, pLogger As Logger) As String
|
||||
|
||||
If pDatetimeString.IsNullOrEmpty() = True Then
|
||||
' Wenn nichts kommt, kommt nichts zurueck
|
||||
Return String.Empty
|
||||
End If
|
||||
|
||||
Dim formatList As List(Of String) = New List(Of String) From {
|
||||
"yyyyMMdd",
|
||||
"MM/dd/yyyy", "M/d/yyyy", "MM/d/yyyy", "M/dd/yyyy",
|
||||
"yyyy-MM-dd", "yyyy-M-d", "yyyy-MM-d", "yyyy-M-dd",
|
||||
"dd.MM.yyyy", "d.M.yyyy", "d.MM.yyyy", "dd.M.yyyy"
|
||||
}
|
||||
|
||||
Dim dateStringResult As Date = Date.MinValue
|
||||
Dim oConvertResult As Boolean = False
|
||||
|
||||
For Each formatStringItem In formatList
|
||||
Try
|
||||
dateStringResult = DateTime.ParseExact(pDatetimeString, formatStringItem, CultureInfo.InvariantCulture)
|
||||
oConvertResult = True
|
||||
Exit For
|
||||
Catch ex As FormatException
|
||||
oConvertResult = False
|
||||
pLogger?.Debug("DatetimeStringToGermanStringConverter() - Could not parse date string {0} ({1})", pDatetimeString, formatStringItem)
|
||||
End Try
|
||||
Next
|
||||
|
||||
If oConvertResult = True Then
|
||||
' In deutsches Format umwandeln (dd.MM.yyyy)
|
||||
Dim germanDateFormat As String = dateStringResult.ToString("dd.MM.yyyy")
|
||||
Return germanDateFormat
|
||||
Else
|
||||
' Wenn nichts konvertiert werden konnte, geben wir den ursprünglichen Wert zurück
|
||||
Return pDatetimeString
|
||||
End If
|
||||
|
||||
End Function
|
||||
End Class
|
||||
36
Base/WindowsEx.vb
Normal file
36
Base/WindowsEx.vb
Normal file
@@ -0,0 +1,36 @@
|
||||
Imports System.ComponentModel
|
||||
Imports System.Runtime.InteropServices
|
||||
Imports DigitalData.Modules.Logging
|
||||
Imports DigitalData.Modules.Base.NativeMethods
|
||||
|
||||
Public Class WindowsEx
|
||||
Private ReadOnly _LogConfig As LogConfig
|
||||
Private ReadOnly _Logger As Logger
|
||||
|
||||
Public Sub New(LogConfig As LogConfig)
|
||||
_LogConfig = LogConfig
|
||||
_Logger = LogConfig.GetLogger()
|
||||
End Sub
|
||||
|
||||
Public Function OpenFileProperties(FilePath As String) As Boolean
|
||||
Try
|
||||
Dim oShellExecuteInfo As New ShellExecuteInfo()
|
||||
oShellExecuteInfo.cbSize = Marshal.SizeOf(oShellExecuteInfo)
|
||||
oShellExecuteInfo.lpVerb = "properties"
|
||||
oShellExecuteInfo.lpFile = FilePath
|
||||
oShellExecuteInfo.nShow = SW_SHOW
|
||||
oShellExecuteInfo.fMask = SEE_MASK_INVOKEIDLIST
|
||||
|
||||
If Not ShellExecuteEx(oShellExecuteInfo) Then
|
||||
Dim oWin32Error = Marshal.GetLastWin32Error()
|
||||
Dim oException As New Win32Exception(oWin32Error)
|
||||
Throw oException
|
||||
End If
|
||||
|
||||
Return True
|
||||
Catch ex As Exception
|
||||
_Logger.Error(ex)
|
||||
Return False
|
||||
End Try
|
||||
End Function
|
||||
End Class
|
||||
@@ -1,4 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="NLog" version="5.0.5" targetFramework="net461" />
|
||||
<package id="NuGet.CommandLine" version="6.13.2" targetFramework="net462" developmentDependency="true" />
|
||||
</packages>
|
||||
22
Config/App.config
Normal file
22
Config/App.config
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<configSections>
|
||||
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
|
||||
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
|
||||
</configSections>
|
||||
<entityFramework>
|
||||
<providers>
|
||||
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
|
||||
<provider invariantName="FirebirdSql.Data.FirebirdClient" type="EntityFramework.Firebird.FbProviderServices, EntityFramework.Firebird" />
|
||||
</providers>
|
||||
<defaultConnectionFactory type="EntityFramework.Firebird.FbConnectionFactory, EntityFramework.Firebird" />
|
||||
</entityFramework>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="FirebirdSql.Data.FirebirdClient" publicKeyToken="3750abcc3150b00c" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-7.5.0.0" newVersion="7.5.0.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
</configuration>
|
||||
@@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\packages\EntityFramework.6.4.4\build\EntityFramework.props" Condition="Exists('..\packages\EntityFramework.6.4.4\build\EntityFramework.props')" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
@@ -12,6 +13,8 @@
|
||||
<MyType>Windows</MyType>
|
||||
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
|
||||
<TargetFrameworkProfile />
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@@ -44,13 +47,43 @@
|
||||
<OptionInfer>On</OptionInfer>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="DigitalData.Modules.Base">
|
||||
<HintPath>..\Base\bin\Debug\DigitalData.Modules.Base.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="DigitalData.Modules.Config, Version=1.3.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>bin\Debug\DigitalData.Modules.Config.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="DigitalData.Modules.Database">
|
||||
<HintPath>..\Database\bin\Debug\DigitalData.Modules.Database.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="DigitalData.Modules.Logging, Version=2.6.5.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\Logging\bin\Debug\DigitalData.Modules.Logging.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="EntityFramework.Firebird, Version=6.4.0.0, Culture=neutral, PublicKeyToken=42d22d092898e5f8, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\EntityFramework.Firebird.6.4.0\lib\net452\EntityFramework.Firebird.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="FirebirdSql.Data.FirebirdClient, Version=7.5.0.0, Culture=neutral, PublicKeyToken=3750abcc3150b00c, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\FirebirdSql.Data.FirebirdClient.7.5.0\lib\net452\FirebirdSql.Data.FirebirdClient.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="NLog, Version=5.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NLog.5.0.5\lib\net46\NLog.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.ComponentModel.DataAnnotations" />
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Data.Odbc, Version=6.0.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Data.Odbc.6.0.1\lib\net461\System.Data.Odbc.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.Compression" />
|
||||
<Reference Include="System.Runtime.Serialization" />
|
||||
<Reference Include="System.ServiceModel" />
|
||||
@@ -75,6 +108,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ConfigAttributes.vb" />
|
||||
<Compile Include="ConfigDbFunct.vb" />
|
||||
<Compile Include="ConfigManager.vb" />
|
||||
<Compile Include="ConfigSample.vb" />
|
||||
<Compile Include="ConfigUtils.vb" />
|
||||
@@ -104,6 +138,7 @@
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
<None Include="My Project\Application.myapp">
|
||||
<Generator>MyApplicationCodeGenerator</Generator>
|
||||
<LastGenOutput>Application.Designer.vb</LastGenOutput>
|
||||
@@ -115,19 +150,16 @@
|
||||
</None>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Encryption\Encryption.vbproj">
|
||||
<Project>{8a8f20fc-c46e-41ac-bee7-218366cfff99}</Project>
|
||||
<Name>Encryption</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Filesystem\Filesystem.vbproj">
|
||||
<Project>{991d0231-4623-496d-8bd0-9ca906029cbc}</Project>
|
||||
<Name>Filesystem</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Logging\Logging.vbproj">
|
||||
<Project>{903b2d7d-3b80-4be9-8713-7447b704e1b0}</Project>
|
||||
<Name>Logging</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>powershell.exe -command "& { &'$(SolutionDir)copy-binary.ps1' '$(TargetPath)' '$(TargetFileName)' '$(ConfigurationName)' '$(ProjectName)' }"</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>Dieses Projekt verweist auf mindestens ein NuGet-Paket, das auf diesem Computer fehlt. Verwenden Sie die Wiederherstellung von NuGet-Paketen, um die fehlenden Dateien herunterzuladen. Weitere Informationen finden Sie unter "http://go.microsoft.com/fwlink/?LinkID=322105". Die fehlende Datei ist "{0}".</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\EntityFramework.6.4.4\build\EntityFramework.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\EntityFramework.6.4.4\build\EntityFramework.props'))" />
|
||||
<Error Condition="!Exists('..\packages\EntityFramework.6.4.4\build\EntityFramework.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\EntityFramework.6.4.4\build\EntityFramework.targets'))" />
|
||||
</Target>
|
||||
<Import Project="..\packages\EntityFramework.6.4.4\build\EntityFramework.targets" Condition="Exists('..\packages\EntityFramework.6.4.4\build\EntityFramework.targets')" />
|
||||
</Project>
|
||||
52
Config/ConfigDbFunct.vb
Normal file
52
Config/ConfigDbFunct.vb
Normal file
@@ -0,0 +1,52 @@
|
||||
Imports DigitalData.Modules.Logging
|
||||
Imports DigitalData.Modules.Database
|
||||
|
||||
|
||||
Public Class ConfigDbFunct
|
||||
|
||||
''' <summary>
|
||||
''' Ermittelt die aktuelle Lizenz für das gewünschte Produkt
|
||||
''' aus der DB-Tabelle TBDD_3RD_PARTY_MODULES
|
||||
''' </summary>
|
||||
'''
|
||||
''' <param name="pLogConfig">An instance of LogConfig</param>
|
||||
''' <param name="pConnectionString">Initial connectionstring for connecting to DD_ECM database.</param>
|
||||
''' <returns>LicenseKey, if found, otherwise String.Empty</returns>
|
||||
Public Shared Function GetProductLicense(pProductName As String, pVersion As String, pLogConfig As LogConfig, pConnectionString As String) As String
|
||||
|
||||
Dim oLogger As Logger = pLogConfig.GetLogger()
|
||||
|
||||
If (String.IsNullOrEmpty(pProductName)) Then
|
||||
oLogger.Error("Parameter pProductName is null or empty")
|
||||
Return String.Empty
|
||||
End If
|
||||
|
||||
If (String.IsNullOrEmpty(pVersion)) Then
|
||||
oLogger.Error("Parameter pVersion is null or empty")
|
||||
Return String.Empty
|
||||
End If
|
||||
|
||||
If (String.IsNullOrEmpty(pConnectionString)) Then
|
||||
oLogger.Error("Parameter pConnectionString is null or empty")
|
||||
Return String.Empty
|
||||
End If
|
||||
|
||||
Try
|
||||
Dim oDecryptedConnectionString As String = MSSQLServer.DecryptConnectionString(pConnectionString)
|
||||
Dim oDatabase As MSSQLServer = New MSSQLServer(pLogConfig, oDecryptedConnectionString)
|
||||
|
||||
Dim oSql As String = "SELECT LICENSE FROM TBDD_3RD_PARTY_MODULES WHERE NAME = '" + pProductName + "' AND ACTIVE = 1 AND VERSION = '" + pVersion + "'"
|
||||
Dim oLicenseString As String = oDatabase.GetScalarValue(oSql)
|
||||
|
||||
Return oLicenseString
|
||||
|
||||
Catch ex As Exception
|
||||
oLogger.Error("Exception occured in ConfigDbFunct.GetProductLicense()")
|
||||
oLogger.Error(ex)
|
||||
End Try
|
||||
|
||||
Return String.Empty
|
||||
|
||||
End Function
|
||||
|
||||
End Class
|
||||
@@ -2,17 +2,17 @@
|
||||
Imports System.Reflection
|
||||
Imports System.Xml.Serialization
|
||||
Imports DigitalData.Modules.Logging
|
||||
Imports DigitalData.Modules.Encryption
|
||||
Imports DigitalData.Modules.Config.ConfigAttributes
|
||||
Imports DigitalData.Modules.Base
|
||||
|
||||
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"
|
||||
Public Const USER_CONFIG_NAME As String = "UserConfig.xml"
|
||||
Public Const COMPUTER_CONFIG_NAME As String = "ComputerConfig.xml"
|
||||
Public Const APP_CONFIG_NAME As String = "AppConfig.xml"
|
||||
|
||||
Private ReadOnly _LogConfig As LogConfig
|
||||
Private ReadOnly _Logger As Logger
|
||||
Private ReadOnly _File As Filesystem.File
|
||||
Private ReadOnly _File As FilesystemEx
|
||||
|
||||
Private ReadOnly _UserDirectory As String
|
||||
Private ReadOnly _UserConfigPath As String
|
||||
@@ -104,7 +104,7 @@ Public Class ConfigManager(Of T)
|
||||
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 Filesystem.File(_LogConfig)
|
||||
_File = New FilesystemEx(_LogConfig)
|
||||
|
||||
_Blueprint = Activator.CreateInstance(Of T)
|
||||
_BlueprintType = _Blueprint.GetType
|
||||
@@ -122,7 +122,7 @@ Public Class ConfigManager(Of T)
|
||||
_ComputerConfigPath = Path.Combine(_ComputerDirectory, COMPUTER_CONFIG_NAME)
|
||||
End If
|
||||
|
||||
If ApplicationStartupPath <> String.Empty Then
|
||||
If ApplicationStartupPath <> String.Empty Then
|
||||
_AppConfigPath = Path.Combine(ApplicationStartupPath, APP_CONFIG_NAME)
|
||||
|
||||
End If
|
||||
|
||||
@@ -1,17 +1,80 @@
|
||||
Imports DigitalData.Modules.Logging
|
||||
Imports System.IO
|
||||
Imports DigitalData.Modules.Base
|
||||
Imports DigitalData.Modules.Logging
|
||||
|
||||
Public Class ConfigUtils
|
||||
Private _Logger As Logger
|
||||
Private _File As Filesystem.File
|
||||
Private ReadOnly _Logger As Logger
|
||||
Private ReadOnly _File As FilesystemEx
|
||||
|
||||
Private Const MIGRATE_DIRECTORY As String = "Migrate"
|
||||
|
||||
|
||||
Public Sub New(LogConfig As LogConfig)
|
||||
_Logger = LogConfig.GetLogger()
|
||||
_File = New Filesystem.File(LogConfig)
|
||||
_File = New FilesystemEx(LogConfig)
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' Migrate a config file when the ProductName has changed
|
||||
''' </summary>
|
||||
''' <param name="pUserBasePath">The user config base path, should be Application.UserAppDataPath</param>
|
||||
''' <param name="pProductName">The current or new product name</param>
|
||||
''' <param name="pOldProductName">The old product name</param>
|
||||
''' <returns></returns>
|
||||
Public Function MigrateUserAppDataConfig(pUserBasePath As String, pProductName As String, pOldProductName As String)
|
||||
Return MigrateAppDataConfig(pUserBasePath, ConfigManager(Of ConfigSample).USER_CONFIG_NAME, pProductName, pOldProductName)
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Migrate a config file when the ProductName has changed
|
||||
''' </summary>
|
||||
''' <param name="pCommonBasePath">The config base path, should be Application.CommonAppDataPath</param>
|
||||
''' <param name="pProductName">The current or new product name</param>
|
||||
''' <param name="pOldProductName">The old product name</param>
|
||||
''' <returns></returns>
|
||||
Public Function MigrateCommonAppDataConfig(pCommonBasePath As String, pProductName As String, pOldProductName As String)
|
||||
Return MigrateAppDataConfig(pCommonBasePath, ConfigManager(Of ConfigSample).COMPUTER_CONFIG_NAME, pProductName, pOldProductName)
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Migrate a config file when the ProductName has changed
|
||||
''' </summary>
|
||||
''' <param name="pBasePath">The config base path, can be Application.UserAppDataPath or Application.CommonAppDataPath</param>
|
||||
''' <param name="pProductName">The current or new product name</param>
|
||||
''' <param name="pOldProductName">The old product name</param>
|
||||
''' <returns></returns>
|
||||
Private Function MigrateAppDataConfig(pBasePath As String, pConfigName As String, pProductName As String, pOldProductName As String)
|
||||
Dim oNewDirPath = pBasePath
|
||||
Dim oOldDirPath = oNewDirPath.Replace(pProductName, pOldProductName)
|
||||
Dim oNewFilePath = Path.Combine(oNewDirPath, pConfigName)
|
||||
Dim oOldFilePath = Path.Combine(oOldDirPath, pConfigName)
|
||||
|
||||
' If there is already a new config, exit.
|
||||
If File.Exists(oNewFilePath) Then
|
||||
Return True
|
||||
End If
|
||||
|
||||
' If there is no old config, exit.
|
||||
If Not File.Exists(oOldFilePath) Then
|
||||
Return True
|
||||
End If
|
||||
|
||||
Try
|
||||
If Not Directory.Exists(oNewDirPath) Then
|
||||
Directory.CreateDirectory(oNewDirPath)
|
||||
End If
|
||||
|
||||
_Logger.Info("Migrating Config from [{0}] to [{1}]", pOldProductName, pProductName)
|
||||
File.Move(oOldFilePath, oNewFilePath)
|
||||
Return True
|
||||
|
||||
Catch ex As Exception
|
||||
_Logger.Warn("Error while Migrating Config")
|
||||
_Logger.Error(ex)
|
||||
Return False
|
||||
|
||||
End Try
|
||||
End Function
|
||||
|
||||
Public Function TestMigrationNeeded(TargetDirectory As String) As Boolean
|
||||
If IO.Directory.Exists(TargetDirectory) Then
|
||||
Return False
|
||||
@@ -21,97 +84,97 @@ Public Class ConfigUtils
|
||||
End Function
|
||||
|
||||
Public Sub MigrateConfig(SourceDirectory As String, TargetDirectory As String, Optional FilePattern As String = "*.*")
|
||||
If IO.Directory.Exists(TargetDirectory) Then
|
||||
_Logger.Warn("Config Migration aborted because new config directory [{0}] already exists!", TargetDirectory)
|
||||
Exit Sub
|
||||
End If
|
||||
'If IO.Directory.Exists(TargetDirectory) Then
|
||||
' _Logger.Warn("Config Migration aborted because new config directory [{0}] already exists!", TargetDirectory)
|
||||
' Exit Sub
|
||||
'End If
|
||||
|
||||
_Logger.Debug("Creating TargetDirectory [{0}]", TargetDirectory)
|
||||
' Create target directory
|
||||
Try
|
||||
IO.Directory.CreateDirectory(TargetDirectory)
|
||||
Catch ex As Exception
|
||||
_Logger.Warn("Config Migration aborted because new config directory [{0}] could not be created!", TargetDirectory)
|
||||
_Logger.Error(ex)
|
||||
Exit Sub
|
||||
End Try
|
||||
'_Logger.Debug("Creating TargetDirectory [{0}]", TargetDirectory)
|
||||
'' Create target directory
|
||||
'Try
|
||||
' IO.Directory.CreateDirectory(TargetDirectory)
|
||||
'Catch ex As Exception
|
||||
' _Logger.Warn("Config Migration aborted because new config directory [{0}] could not be created!", TargetDirectory)
|
||||
' _Logger.Error(ex)
|
||||
' Exit Sub
|
||||
'End Try
|
||||
|
||||
' Create Migration directory
|
||||
Dim oMigrationDirectory = IO.Path.Combine(SourceDirectory, MIGRATE_DIRECTORY)
|
||||
_Logger.Debug("Creating MigrationDirectory [{0}]", oMigrationDirectory)
|
||||
Try
|
||||
IO.Directory.CreateDirectory(oMigrationDirectory)
|
||||
Catch ex As Exception
|
||||
_Logger.Warn("Config Migration aborted because migration directory [{0}] could not be created!", oMigrationDirectory)
|
||||
_Logger.Error(ex)
|
||||
Exit Sub
|
||||
End Try
|
||||
'' Create Migration directory
|
||||
'Dim oMigrationDirectory = IO.Path.Combine(SourceDirectory, MIGRATE_DIRECTORY)
|
||||
'_Logger.Debug("Creating MigrationDirectory [{0}]", oMigrationDirectory)
|
||||
'Try
|
||||
' IO.Directory.CreateDirectory(oMigrationDirectory)
|
||||
'Catch ex As Exception
|
||||
' _Logger.Warn("Config Migration aborted because migration directory [{0}] could not be created!", oMigrationDirectory)
|
||||
' _Logger.Error(ex)
|
||||
' Exit Sub
|
||||
'End Try
|
||||
|
||||
' Copy individual files from top level directory
|
||||
For Each oPath In IO.Directory.EnumerateFiles(SourceDirectory, FilePattern)
|
||||
Dim oFileInfo = New IO.FileInfo(oPath)
|
||||
'' Copy individual files from top level directory
|
||||
'For Each oPath In IO.Directory.EnumerateFiles(SourceDirectory, FilePattern)
|
||||
' Dim oFileInfo = New IO.FileInfo(oPath)
|
||||
|
||||
_Logger.Debug("Processing file [{0}]", oFileInfo.Name)
|
||||
' _Logger.Debug("Processing file [{0}]", oFileInfo.Name)
|
||||
|
||||
_Logger.Debug("Copying [{0}] to TargetDirectory..", oFileInfo.Name)
|
||||
' Copy to target directory
|
||||
Try
|
||||
IO.File.Copy(oPath, IO.Path.Combine(TargetDirectory, oFileInfo.Name))
|
||||
Catch ex As Exception
|
||||
_Logger.Warn("Could not move old config file {0} to new config location {1}", oFileInfo.Name, TargetDirectory)
|
||||
_Logger.Error(ex)
|
||||
End Try
|
||||
' _Logger.Debug("Copying [{0}] to TargetDirectory..", oFileInfo.Name)
|
||||
' ' Copy to target directory
|
||||
' Try
|
||||
' IO.File.Copy(oPath, IO.Path.Combine(TargetDirectory, oFileInfo.Name))
|
||||
' Catch ex As Exception
|
||||
' _Logger.Warn("Could not move old config file {0} to new config location {1}", oFileInfo.Name, TargetDirectory)
|
||||
' _Logger.Error(ex)
|
||||
' End Try
|
||||
|
||||
_Logger.Debug("Moving [{0}] to MigrationDirectory..", oFileInfo.Name)
|
||||
' Move to migration directory
|
||||
Try
|
||||
IO.File.Move(oPath, IO.Path.Combine(oMigrationDirectory, oFileInfo.Name))
|
||||
Catch ex As Exception
|
||||
_Logger.Warn("Could not move old config file {0} to migration directory {1}", oFileInfo.Name, oMigrationDirectory)
|
||||
_Logger.Error(ex)
|
||||
End Try
|
||||
Next
|
||||
' _Logger.Debug("Moving [{0}] to MigrationDirectory..", oFileInfo.Name)
|
||||
' ' Move to migration directory
|
||||
' Try
|
||||
' IO.File.Move(oPath, IO.Path.Combine(oMigrationDirectory, oFileInfo.Name))
|
||||
' Catch ex As Exception
|
||||
' _Logger.Warn("Could not move old config file {0} to migration directory {1}", oFileInfo.Name, oMigrationDirectory)
|
||||
' _Logger.Error(ex)
|
||||
' End Try
|
||||
'Next
|
||||
|
||||
For Each oDirectoryPath In IO.Directory.EnumerateDirectories(SourceDirectory, "*", IO.SearchOption.TopDirectoryOnly)
|
||||
Dim oDirInfo As New IO.DirectoryInfo(oDirectoryPath)
|
||||
'For Each oDirectoryPath In IO.Directory.EnumerateDirectories(SourceDirectory, "*", IO.SearchOption.TopDirectoryOnly)
|
||||
' Dim oDirInfo As New IO.DirectoryInfo(oDirectoryPath)
|
||||
|
||||
_Logger.Debug("Processing directory [{0}]", oDirInfo.Name)
|
||||
' _Logger.Debug("Processing directory [{0}]", oDirInfo.Name)
|
||||
|
||||
' Don't copy TargetDirectory if subpath of SourceDirectory or if MigrationDirectory
|
||||
If oDirInfo.FullName = TargetDirectory Or oDirInfo.FullName = oMigrationDirectory Then
|
||||
_Logger.Debug("Directory [{0}] should not be copied. Skipping.", oDirInfo.Name)
|
||||
Continue For
|
||||
End If
|
||||
' ' Don't copy TargetDirectory if subpath of SourceDirectory or if MigrationDirectory
|
||||
' If oDirInfo.FullName = TargetDirectory Or oDirInfo.FullName = oMigrationDirectory Then
|
||||
' _Logger.Debug("Directory [{0}] should not be copied. Skipping.", oDirInfo.Name)
|
||||
' Continue For
|
||||
' End If
|
||||
|
||||
' Copy directory to TargetDirectory
|
||||
Dim oNewDirectoryPath = IO.Path.Combine(TargetDirectory, oDirInfo.Name)
|
||||
_Logger.Debug("Copying [{0}] to TargetDirectory..", oDirInfo.Name)
|
||||
Try
|
||||
_File.CopyDirectory(oDirInfo.FullName, oNewDirectoryPath, True)
|
||||
Catch ex As Exception
|
||||
_Logger.Warn("Could not move directory [{0}] to new path [{1}]", oDirInfo.FullName, oNewDirectoryPath)
|
||||
_Logger.Error(ex)
|
||||
End Try
|
||||
' ' Copy directory to TargetDirectory
|
||||
' Dim oNewDirectoryPath = IO.Path.Combine(TargetDirectory, oDirInfo.Name)
|
||||
' _Logger.Debug("Copying [{0}] to TargetDirectory..", oDirInfo.Name)
|
||||
' Try
|
||||
' _File.CopyDirectory(oDirInfo.FullName, oNewDirectoryPath, True)
|
||||
' Catch ex As Exception
|
||||
' _Logger.Warn("Could not move directory [{0}] to new path [{1}]", oDirInfo.FullName, oNewDirectoryPath)
|
||||
' _Logger.Error(ex)
|
||||
' End Try
|
||||
|
||||
_Logger.Debug("Copying [{0}] to MigrationDirectory..", oDirInfo.Name)
|
||||
' Copy directory to MigrationDirectory
|
||||
Dim oMigrationDirectoryPath = IO.Path.Combine(oMigrationDirectory, oDirInfo.Name)
|
||||
Try
|
||||
_File.CopyDirectory(oDirInfo.FullName, oMigrationDirectoryPath, True)
|
||||
Catch ex As Exception
|
||||
_Logger.Error(ex)
|
||||
_Logger.Warn("Could not move directory [{0}] to migration directory [{1}]", oDirInfo.FullName, oMigrationDirectoryPath)
|
||||
End Try
|
||||
' _Logger.Debug("Copying [{0}] to MigrationDirectory..", oDirInfo.Name)
|
||||
' ' Copy directory to MigrationDirectory
|
||||
' Dim oMigrationDirectoryPath = IO.Path.Combine(oMigrationDirectory, oDirInfo.Name)
|
||||
' Try
|
||||
' _File.CopyDirectory(oDirInfo.FullName, oMigrationDirectoryPath, True)
|
||||
' Catch ex As Exception
|
||||
' _Logger.Error(ex)
|
||||
' _Logger.Warn("Could not move directory [{0}] to migration directory [{1}]", oDirInfo.FullName, oMigrationDirectoryPath)
|
||||
' End Try
|
||||
|
||||
_Logger.Debug("Deleting [{0}]..", oDirInfo.Name)
|
||||
' Delete directory
|
||||
Try
|
||||
IO.Directory.Delete(oDirInfo.FullName, True)
|
||||
Catch ex As Exception
|
||||
_Logger.Error(ex)
|
||||
_Logger.Warn("Could not delete directory [{0}]", oDirInfo.FullName)
|
||||
End Try
|
||||
Next
|
||||
' _Logger.Debug("Deleting [{0}]..", oDirInfo.Name)
|
||||
' ' Delete directory
|
||||
' Try
|
||||
' IO.Directory.Delete(oDirInfo.FullName, True)
|
||||
' Catch ex As Exception
|
||||
' _Logger.Error(ex)
|
||||
' _Logger.Warn("Could not delete directory [{0}]", oDirInfo.FullName)
|
||||
' End Try
|
||||
'Next
|
||||
End Sub
|
||||
|
||||
End Class
|
||||
|
||||
@@ -9,10 +9,10 @@ Imports System.Runtime.InteropServices
|
||||
' Werte der Assemblyattribute überprüfen
|
||||
|
||||
<Assembly: AssemblyTitle("Modules.Config")>
|
||||
<Assembly: AssemblyDescription("")>
|
||||
<Assembly: AssemblyCompany("")>
|
||||
<Assembly: AssemblyDescription("Stellt Module für die Konfiguration von Produkten bereit")>
|
||||
<Assembly: AssemblyCompany("Digital Data GmbH, Heuchelheim")>
|
||||
<Assembly: AssemblyProduct("Modules.Config")>
|
||||
<Assembly: AssemblyCopyright("Copyright © 2022")>
|
||||
<Assembly: AssemblyCopyright("Copyright © 2025")>
|
||||
<Assembly: AssemblyTrademark("")>
|
||||
|
||||
<Assembly: ComVisible(False)>
|
||||
@@ -31,5 +31,5 @@ Imports System.Runtime.InteropServices
|
||||
' übernehmen, indem Sie "*" eingeben:
|
||||
' <Assembly: AssemblyVersion("1.0.*")>
|
||||
|
||||
<Assembly: AssemblyVersion("1.2.1.0")>
|
||||
<Assembly: AssemblyFileVersion("1.2.1.0")>
|
||||
<Assembly: AssemblyVersion("1.3.0.0")>
|
||||
<Assembly: AssemblyFileVersion("1.3.0.0")>
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="EntityFramework" version="6.4.4" targetFramework="net462" />
|
||||
<package id="EntityFramework.Firebird" version="6.4.0" targetFramework="net462" />
|
||||
<package id="FirebirdSql.Data.FirebirdClient" version="7.5.0" targetFramework="net462" />
|
||||
<package id="NLog" version="5.0.5" targetFramework="net461" />
|
||||
<package id="System.Data.Odbc" version="6.0.1" targetFramework="net462" />
|
||||
</packages>
|
||||
@@ -8,6 +8,15 @@ Public Class MSSQLServer
|
||||
|
||||
Public Property DBInitialized As Boolean = False Implements IDatabase.DBInitialized
|
||||
Public Property CurrentConnectionString As String = "" Implements IDatabase.CurrentConnectionString
|
||||
Public ReadOnly Property MaskedConnectionString As String
|
||||
Get
|
||||
If CurrentConnectionString = "" Then
|
||||
Return ""
|
||||
Else
|
||||
Return MaskConnectionString(CurrentConnectionString)
|
||||
End If
|
||||
End Get
|
||||
End Property
|
||||
|
||||
Private ReadOnly QueryTimeout As Integer
|
||||
Private ReadOnly Logger As Logger
|
||||
@@ -100,29 +109,31 @@ Public Class MSSQLServer
|
||||
End Try
|
||||
End Function
|
||||
|
||||
Private Function MaybeGetTransaction(Connection As SqlConnection, Mode As TransactionMode, Transaction As SqlTransaction) As SqlTransaction
|
||||
If Connection Is Nothing Then
|
||||
Throw New ArgumentNullException("Connection")
|
||||
Private Function MaybeGetTransaction(pConnection As SqlConnection, pTransactionMode As TransactionMode, pTransaction As SqlTransaction) As SqlTransaction
|
||||
If pConnection Is Nothing Then
|
||||
Throw New ArgumentNullException("Connection", "Could not get transaction because connection is null!")
|
||||
End If
|
||||
|
||||
If Mode = TransactionMode.NoTransaction Then
|
||||
Logger.Debug("Transaction Mode: [{0}]", pTransactionMode.ToString)
|
||||
|
||||
If pTransactionMode = TransactionMode.NoTransaction Then
|
||||
Return Nothing
|
||||
ElseIf Mode = TransactionMode.ExternalTransaction Then
|
||||
Return Transaction
|
||||
ElseIf pTransactionMode = TransactionMode.ExternalTransaction Then
|
||||
Return pTransaction
|
||||
Else
|
||||
Return Connection.BeginTransaction()
|
||||
Return pConnection.BeginTransaction()
|
||||
End If
|
||||
End Function
|
||||
|
||||
Private Function MaybeCommitTransaction(Transaction As SqlTransaction, TransactionMode As TransactionMode) As Boolean
|
||||
Select Case TransactionMode
|
||||
Private Function MaybeCommitTransaction(pTransaction As SqlTransaction, pTransactionMode As TransactionMode) As Boolean
|
||||
Select Case pTransactionMode
|
||||
Case TransactionMode.NoTransaction
|
||||
Return True
|
||||
Case TransactionMode.ExternalTransaction
|
||||
Return True
|
||||
Case TransactionMode.WithTransaction
|
||||
Try
|
||||
Transaction.Commit()
|
||||
pTransaction.Commit()
|
||||
Return True
|
||||
Catch ex As Exception
|
||||
Logger.Warn("Error while committing transaction!")
|
||||
@@ -137,7 +148,24 @@ Public Class MSSQLServer
|
||||
Public Function GetConnectionStringForId(pConnectionId As Integer) As String
|
||||
Return Get_ConnectionStringforID(pConnectionId)
|
||||
End Function
|
||||
|
||||
Public Function GetGDPictureString() As String
|
||||
Using oConnection As SqlConnection = GetSQLConnection()
|
||||
Dim oSQL = Queries.DD_ECM.ThirdPartyModules.GdPictureLicense
|
||||
Dim oGDPicture = GetScalarValueWithConnectionObject(oSQL, oConnection)
|
||||
If oGDPicture = String.Empty Then
|
||||
oSQL = Queries.DD_ECM.ThirdPartyModules.GdPictureLicense_REGULAR
|
||||
oGDPicture = GetScalarValueWithConnectionObject(oSQL, oConnection)
|
||||
End If
|
||||
Return oGDPicture
|
||||
End Using
|
||||
End Function
|
||||
Public Function GetDDCatalog() As DataTable
|
||||
Using oConnection As SqlConnection = GetSQLConnection()
|
||||
Dim oSQL = Queries.DD_ECM.DD_SELECTS.TBDD_CATALOG
|
||||
Dim oDT_CATALOG As DataTable = GetDatatable(oSQL)
|
||||
Return oDT_CATALOG
|
||||
End Using
|
||||
End Function
|
||||
Public Function Get_ConnectionStringforID(pConnectionId As Integer) As String
|
||||
Dim oConnectionString As String = String.Empty
|
||||
|
||||
@@ -216,15 +244,15 @@ Public Class MSSQLServer
|
||||
''' <summary>
|
||||
''' This Function intentionally has no try..catch block to have any errors caught outside
|
||||
''' </summary>
|
||||
''' <param name="Connection"></param>
|
||||
''' <param name="pConnection"></param>
|
||||
''' <returns></returns>
|
||||
Private Function OpenSQLConnection(Connection As SqlConnection) As SqlConnection
|
||||
Private Function OpenSQLConnection(pConnection As SqlConnection) As SqlConnection
|
||||
Try
|
||||
If Connection.State = ConnectionState.Closed Then
|
||||
Connection.Open()
|
||||
If pConnection.State = ConnectionState.Closed Then
|
||||
pConnection.Open()
|
||||
End If
|
||||
|
||||
Return Connection
|
||||
Return pConnection
|
||||
Catch ex As Exception
|
||||
Logger.Error("Error while opening Connection!")
|
||||
Logger.Error(ex)
|
||||
@@ -260,7 +288,7 @@ Public Class MSSQLServer
|
||||
Try
|
||||
If pConnectionString Is Nothing OrElse pConnectionString.Length = 0 Then
|
||||
Logger.Warn("Connection String is empty!")
|
||||
Throw New ArgumentNullException("pConnectionString")
|
||||
Throw New ArgumentNullException("pConnectionString", "Could not mask connection string because connectiong string is empty!")
|
||||
End If
|
||||
|
||||
Dim oBuilder As New SqlConnectionStringBuilder() With {.ConnectionString = pConnectionString}
|
||||
@@ -297,15 +325,11 @@ Public Class MSSQLServer
|
||||
End Function
|
||||
|
||||
Public Function GetDatatable(pSqlCommand As String, pTransaction As SqlTransaction, Optional pTimeout As Integer = Constants.DEFAULT_TIMEOUT) As DataTable
|
||||
Using oSqlConnection = GetSQLConnection()
|
||||
Return GetDatatableWithConnectionObject(pSqlCommand, oSqlConnection, TransactionMode.ExternalTransaction, pTransaction, pTimeout)
|
||||
End Using
|
||||
Return GetDatatableWithConnectionObject(pSqlCommand, pTransaction.Connection, TransactionMode.ExternalTransaction, pTransaction, pTimeout)
|
||||
End Function
|
||||
|
||||
Public Function GetDatatable(pSqlCommandObject As SqlCommand, pTransaction As SqlTransaction, Optional pTimeout As Integer = Constants.DEFAULT_TIMEOUT) As DataTable
|
||||
Using oSqlConnection = GetSQLConnection()
|
||||
Return GetDatatableWithConnectionObject(pSqlCommandObject, oSqlConnection, TransactionMode.ExternalTransaction, pTransaction, pTimeout)
|
||||
End Using
|
||||
Return GetDatatableWithConnectionObject(pSqlCommandObject, pTransaction.Connection, TransactionMode.ExternalTransaction, pTransaction, pTimeout)
|
||||
End Function
|
||||
|
||||
Public Async Function GetDatatableAsync(pSqlCommand As String, Optional pTimeout As Integer = Constants.DEFAULT_TIMEOUT) As Task(Of DataTable)
|
||||
@@ -328,6 +352,20 @@ Public Class MSSQLServer
|
||||
End Using
|
||||
End Function
|
||||
|
||||
Public Async Function GetDatatableWithConnectionObjectAsync(pSqlCommand As String, pSqlConnection As SqlConnection,
|
||||
Optional pTransactionMode As TransactionMode = TransactionMode.WithTransaction,
|
||||
Optional pTransaction As SqlTransaction = Nothing,
|
||||
Optional pTimeout As Integer = Constants.DEFAULT_TIMEOUT) As Task(Of DataTable)
|
||||
Return Await Task.Run(Function() GetDatatableWithConnectionObject(pSqlCommand, pSqlConnection, pTransactionMode, pTransaction, pTimeout))
|
||||
End Function
|
||||
|
||||
Public Async Function GetDatatableWithConnectionObjectAsync(pSqlCommandObject As SqlCommand, pSqlConnection As SqlConnection,
|
||||
Optional pTransactionMode As TransactionMode = TransactionMode.WithTransaction,
|
||||
Optional pTransaction As SqlTransaction = Nothing,
|
||||
Optional pTimeout As Integer = Constants.DEFAULT_TIMEOUT) As Task(Of DataTable)
|
||||
Return Await Task.Run(Function() GetDatatableWithConnectionObject(pSqlCommandObject, pSqlConnection, pTransactionMode, pTransaction, pTimeout))
|
||||
End Function
|
||||
|
||||
Public Function GetDatatableWithConnectionObject(pSqlCommand As String, pSqlConnection As SqlConnection,
|
||||
Optional pTransactionMode As TransactionMode = TransactionMode.WithTransaction,
|
||||
Optional pTransaction As SqlTransaction = Nothing,
|
||||
@@ -390,15 +428,11 @@ Public Class MSSQLServer
|
||||
|
||||
|
||||
Public Function ExecuteNonQuery(pSQLCommand As String, pTransaction As SqlTransaction, Optional pTimeout As Integer = Constants.DEFAULT_TIMEOUT) As Boolean
|
||||
Using oConnection = GetSQLConnection()
|
||||
Return ExecuteNonQueryWithConnectionObject(pSQLCommand, pTransaction.Connection, TransactionMode.ExternalTransaction, pTransaction, pTimeout)
|
||||
End Using
|
||||
Return ExecuteNonQueryWithConnectionObject(pSQLCommand, pTransaction.Connection, TransactionMode.ExternalTransaction, pTransaction, pTimeout)
|
||||
End Function
|
||||
|
||||
Public Function ExecuteNonQuery(pSQLCommandObject As SqlCommand, pTransaction As SqlTransaction, Optional pTimeout As Integer = Constants.DEFAULT_TIMEOUT) As Boolean
|
||||
Using oConnection = GetSQLConnection()
|
||||
Return ExecuteNonQueryWithConnectionObject(pSQLCommandObject, pTransaction.Connection, TransactionMode.ExternalTransaction, pTransaction, pTimeout)
|
||||
End Using
|
||||
Return ExecuteNonQueryWithConnectionObject(pSQLCommandObject, pTransaction.Connection, TransactionMode.ExternalTransaction, pTransaction, pTimeout)
|
||||
End Function
|
||||
|
||||
Public Async Function ExecuteNonQueryAsync(pSQLCommand As String, Optional pTimeout As Integer = Constants.DEFAULT_TIMEOUT) As Task(Of Boolean)
|
||||
@@ -445,7 +479,8 @@ Public Class MSSQLServer
|
||||
|
||||
Return True
|
||||
Catch ex As Exception
|
||||
Logger.Error("ExecuteNonQueryWithConnectionObject: Error in ExecuteNonQueryWithConnectionObject while executing command: [{0}]", pSqlCommandObject.CommandText)
|
||||
Dim omsg = $"Unexpected Error in ExecuteNonQueryWithConnectionObject while executing command: [{pSqlCommandObject.CommandText}]"
|
||||
Logger.Warn(omsg)
|
||||
Logger.Error(ex)
|
||||
|
||||
Return False
|
||||
@@ -479,15 +514,11 @@ Public Class MSSQLServer
|
||||
End Function
|
||||
|
||||
Public Function GetScalarValue(pSQLCommand As String, pTransaction As SqlTransaction, Optional pTimeout As Integer = Constants.DEFAULT_TIMEOUT) As Object
|
||||
Using oConnection = GetSQLConnection()
|
||||
Return GetScalarValueWithConnectionObject(pSQLCommand, oConnection, TransactionMode.ExternalTransaction, pTransaction, pTimeout)
|
||||
End Using
|
||||
Return GetScalarValueWithConnectionObject(pSQLCommand, pTransaction.Connection, TransactionMode.ExternalTransaction, pTransaction, pTimeout)
|
||||
End Function
|
||||
|
||||
Public Function GetScalarValue(pSQLCommandObject As SqlCommand, pTransaction As SqlTransaction, Optional pTimeout As Integer = Constants.DEFAULT_TIMEOUT) As Object
|
||||
Using oConnection = GetSQLConnection()
|
||||
Return GetScalarValueWithConnectionObject(pSQLCommandObject, oConnection, TransactionMode.ExternalTransaction, pTransaction, pTimeout)
|
||||
End Using
|
||||
Return GetScalarValueWithConnectionObject(pSQLCommandObject, pTransaction.Connection, TransactionMode.ExternalTransaction, pTransaction, pTimeout)
|
||||
End Function
|
||||
|
||||
Public Async Function GetScalarValueAsync(pSQLCommand As String, Optional pTimeout As Integer = Constants.DEFAULT_TIMEOUT) As Task(Of Object)
|
||||
@@ -621,6 +652,11 @@ Public Class MSSQLServer
|
||||
Select(Function(p) $"({p.ParameterName}={p.Value})").
|
||||
ToList()
|
||||
|
||||
Return String.Join(",", oList)
|
||||
Dim oParamString = String.Join(",", oList)
|
||||
If oParamString.Length > 1000 Then
|
||||
oParamString = oParamString.Substring(1, 1000)
|
||||
End If
|
||||
Return oParamString
|
||||
|
||||
End Function
|
||||
End Class
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<configSections>
|
||||
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
|
||||
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false"/>
|
||||
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
|
||||
</configSections>
|
||||
<entityFramework>
|
||||
<defaultConnectionFactory type="EntityFramework.Firebird.FbConnectionFactory, EntityFramework.Firebird"/>
|
||||
<defaultConnectionFactory type="EntityFramework.Firebird.FbConnectionFactory, EntityFramework.Firebird" />
|
||||
<providers>
|
||||
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer"/>
|
||||
<provider invariantName="FirebirdSql.Data.FirebirdClient" type="EntityFramework.Firebird.FbProviderServices, EntityFramework.Firebird"/>
|
||||
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
|
||||
<provider invariantName="FirebirdSql.Data.FirebirdClient" type="EntityFramework.Firebird.FbProviderServices, EntityFramework.Firebird" />
|
||||
</providers>
|
||||
</entityFramework>
|
||||
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="FirebirdSql.Data.FirebirdClient" publicKeyToken="3750abcc3150b00c" culture="neutral"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-7.5.0.0" newVersion="7.5.0.0"/>
|
||||
<assemblyIdentity name="FirebirdSql.Data.FirebirdClient" publicKeyToken="3750abcc3150b00c" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-7.5.0.0" newVersion="7.5.0.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/></startup></configuration>
|
||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" /></startup></configuration>
|
||||
|
||||
@@ -47,6 +47,13 @@
|
||||
<OptionInfer>On</OptionInfer>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="DigitalData.Modules.Encryption">
|
||||
<HintPath>..\Encryption\bin\Debug\DigitalData.Modules.Encryption.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="DigitalData.Modules.Logging, Version=2.6.5.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\Logging\bin\Debug\DigitalData.Modules.Logging.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll</HintPath>
|
||||
</Reference>
|
||||
@@ -145,16 +152,6 @@
|
||||
</None>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Encryption\Encryption.vbproj">
|
||||
<Project>{8a8f20fc-c46e-41ac-bee7-218366cfff99}</Project>
|
||||
<Name>Encryption</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Logging\Logging.vbproj">
|
||||
<Project>{903b2d7d-3b80-4be9-8713-7447b704e1b0}</Project>
|
||||
<Name>Logging</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
@@ -164,4 +161,7 @@
|
||||
<Error Condition="!Exists('..\packages\EntityFramework.6.4.4\build\EntityFramework.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\EntityFramework.6.4.4\build\EntityFramework.targets'))" />
|
||||
</Target>
|
||||
<Import Project="..\packages\EntityFramework.6.4.4\build\EntityFramework.targets" Condition="Exists('..\packages\EntityFramework.6.4.4\build\EntityFramework.targets')" />
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>powershell.exe -command "& { &'$(SolutionDir)copy-binary.ps1' '$(TargetPath)' '$(TargetFileName)' '$(ConfigurationName)' '$(ProjectName)' }"</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -9,11 +9,11 @@ Imports System.Runtime.InteropServices
|
||||
' Werte der Assemblyattribute überprüfen
|
||||
|
||||
<Assembly: AssemblyTitle("Modules.Database")>
|
||||
<Assembly: AssemblyDescription("")>
|
||||
<Assembly: AssemblyDescription("Stellt Funktionen für den Datenbankzugriff zur Verfügung")>
|
||||
<Assembly: AssemblyCompany("Digital Data")>
|
||||
<Assembly: AssemblyProduct("Modules.Database")>
|
||||
<Assembly: AssemblyCopyright("Copyright © 2023")>
|
||||
<Assembly: AssemblyTrademark("2.3.3.1")>
|
||||
<Assembly: AssemblyCopyright("Copyright © 2025")>
|
||||
<Assembly: AssemblyTrademark("2.3.6.0")>
|
||||
|
||||
<Assembly: ComVisible(False)>
|
||||
|
||||
@@ -31,5 +31,5 @@ Imports System.Runtime.InteropServices
|
||||
' übernehmen, indem Sie "*" eingeben:
|
||||
' <Assembly: AssemblyVersion("1.0.*")>
|
||||
|
||||
<Assembly: AssemblyVersion("2.3.3.1")>
|
||||
<Assembly: AssemblyFileVersion("2.3.3.1")>
|
||||
<Assembly: AssemblyVersion("2.3.6.0")>
|
||||
<Assembly: AssemblyFileVersion("2.3.6.0")>
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
Public Class Queries
|
||||
Public Class DD_ECM
|
||||
Public Class ThirdPartyModules
|
||||
Public Const GdPictureLicense As String = "SELECT LICENSE FROM TBDD_3RD_PARTY_MODULES WHERE NAME = 'GDPICTURE'"
|
||||
Public Const GdPictureLicense As String = "SELECT COALESCE(MAX(LICENSE),'') FROM TBDD_3RD_PARTY_MODULES WHERE ACTIVE = 1 AND NAME = 'GDPICTURE' AND [VERSION] = '11.2024'"
|
||||
Public Const GdPictureLicense_REGULAR As String = "SELECT COALESCE(MAX(LICENSE),'') FROM TBDD_3RD_PARTY_MODULES WHERE NAME = 'GDPICTURE' AND ACTIVE = 1"
|
||||
End Class
|
||||
Public Class DD_SELECTS
|
||||
Public Const TBDD_CATALOG As String = "SELECT * FROM TBDD_CATALOG"
|
||||
End Class
|
||||
|
||||
Public Class Connections
|
||||
Public Const AllConnections As String = "SELECT * FROM TBDD_CONNECTION"
|
||||
Public Const AllConnections As String = "SELECT * FROM TBDD_CONNECTION AND AKTIV = 1"
|
||||
End Class
|
||||
End Class
|
||||
End Class
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
Imports System.IO
|
||||
Imports System.ServiceModel
|
||||
Imports DigitalData.Modules.Base
|
||||
Imports DigitalData.Modules.EDMI.API.Constants
|
||||
Imports DigitalData.Modules.EDMI.API.EDMIServiceReference
|
||||
Imports DigitalData.Modules.EDMI.API.Rights
|
||||
Imports DigitalData.Modules.Language.Utils
|
||||
Imports DigitalData.Modules.Logging
|
||||
|
||||
Public Class Client
|
||||
@@ -550,10 +550,10 @@ Public Class Client
|
||||
.Id = oRow.Item("AttributeId"),
|
||||
.Title = oRow.Item("AttributeTitle"),
|
||||
.Type = oRow.Item("AttributeType"),
|
||||
.ValueBigInt = NotNull(oRow.Item("ValueBigInt"), Nothing),
|
||||
.ValueDate = NotNull(oRow.Item("ValueDate"), Nothing),
|
||||
.ValueDecimal = NotNull(oRow.Item("ValueDecimal"), Nothing),
|
||||
.ValueText = NotNull(oRow.Item("ValueText"), Nothing)
|
||||
.ValueBigInt = oRow.ItemEx(Of Object)("ValueBigInt", Nothing),
|
||||
.ValueDate = oRow.ItemEx(Of Object)("ValueDate", Nothing),
|
||||
.ValueDecimal = oRow.ItemEx(Of Object)("ValueDecimal", Nothing),
|
||||
.ValueText = oRow.ItemEx(Of Object)("ValueText", Nothing)
|
||||
}
|
||||
|
||||
oAttributes.Add(oAttribute)
|
||||
@@ -932,11 +932,11 @@ Public Class Client
|
||||
|
||||
|
||||
Private Function GetUserLanguage(pOverrideLanguage As String) As String
|
||||
Return NotNull(pOverrideLanguage, Threading.Thread.CurrentThread.CurrentUICulture.Name)
|
||||
Return ObjectEx.NotNull(pOverrideLanguage, Threading.Thread.CurrentThread.CurrentUICulture.Name)
|
||||
End Function
|
||||
|
||||
Private Function GetUserName(pOverrideName) As String
|
||||
Return NotNull(pOverrideName, Environment.UserName)
|
||||
Return ObjectEx.NotNull(pOverrideName, Environment.UserName)
|
||||
End Function
|
||||
#End Region
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ Imports DigitalData.Modules.EDMI.API
|
||||
Imports DigitalData.Modules.EDMI.API.Constants
|
||||
Imports DigitalData.Modules.EDMI.API.EDMIServiceReference
|
||||
Imports DigitalData.Modules.Logging
|
||||
Imports DigitalData.Modules.Language.Utils
|
||||
|
||||
Public Class DatabaseWithFallback
|
||||
Private ReadOnly _Logger As Logger
|
||||
|
||||
@@ -308,18 +308,13 @@
|
||||
<Project>{eaf0ea75-5fa7-485d-89c7-b2d843b03a96}</Project>
|
||||
<Name>Database</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Filesystem\Filesystem.vbproj">
|
||||
<Project>{991d0231-4623-496d-8bd0-9ca906029cbc}</Project>
|
||||
<Name>Filesystem</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Language\Language.vbproj">
|
||||
<Project>{d3c8cfed-d6f6-43a8-9bdf-454145d0352f}</Project>
|
||||
<Name>Language</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Logging\Logging.vbproj">
|
||||
<Project>{903b2d7d-3b80-4be9-8713-7447b704e1b0}</Project>
|
||||
<Name>Logging</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>powershell.exe -command "& { &'$(SolutionDir)copy-binary.ps1' '$(TargetPath)' '$(TargetFileName)' '$(ConfigurationName)' '$(ProjectName)' }"</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -1,16 +1,17 @@
|
||||
Imports DigitalData.Modules.EDMI.API.EDMIServiceReference
|
||||
Imports DigitalData.Modules.Base
|
||||
Imports DigitalData.Modules.EDMI.API.EDMIServiceReference
|
||||
Imports DigitalData.Modules.Logging
|
||||
|
||||
|
||||
Public Class Helpers
|
||||
Private ReadOnly LogConfig As LogConfig
|
||||
Private ReadOnly Logger As Logger
|
||||
Private ReadOnly FileEx As Filesystem.File
|
||||
Private ReadOnly FileEx As FilesystemEx
|
||||
|
||||
Public Sub New(pLogConfig As LogConfig)
|
||||
LogConfig = pLogConfig
|
||||
Logger = pLogConfig.GetLogger()
|
||||
FileEx = New Filesystem.File(pLogConfig)
|
||||
FileEx = New FilesystemEx(pLogConfig)
|
||||
End Sub
|
||||
|
||||
Public Function GetFileProperties(pFilePath As String, pDateImportedAt As Date) As FileProperties
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
Imports DigitalData.Modules.EDMI.API.EDMIServiceReference
|
||||
Imports DigitalData.Modules.Base
|
||||
Imports DigitalData.Modules.EDMI.API.EDMIServiceReference
|
||||
Imports DigitalData.Modules.Logging
|
||||
|
||||
Namespace Modules
|
||||
@@ -6,14 +7,14 @@ Namespace Modules
|
||||
Friend ReadOnly LogConfig As LogConfig
|
||||
Friend ReadOnly Logger As Logger
|
||||
Friend ReadOnly Channel As IEDMIServiceChannel
|
||||
Friend ReadOnly FileEx As Filesystem.File
|
||||
Friend ReadOnly FileEx As FilesystemEx
|
||||
Friend ReadOnly Helpers As Helpers
|
||||
|
||||
Public Sub New(pLogConfig As LogConfig, pChannel As IEDMIServiceChannel)
|
||||
LogConfig = pLogConfig
|
||||
Logger = pLogConfig.GetLogger()
|
||||
Channel = pChannel
|
||||
FileEx = New Filesystem.File(pLogConfig)
|
||||
FileEx = New FilesystemEx(pLogConfig)
|
||||
Helpers = New Helpers(pLogConfig)
|
||||
End Sub
|
||||
End Class
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
Imports DigitalData.Modules.EDMI.API.EDMIServiceReference
|
||||
Imports DigitalData.Modules.Logging
|
||||
Imports DigitalData.Modules.Filesystem
|
||||
|
||||
Namespace Modules.IDB
|
||||
Public Class NewFile
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<system.diagnostics>
|
||||
<sources>
|
||||
<!-- Dieser Abschnitt definiert die Protokollierungskonfiguration für My.Application.Log -->
|
||||
<source name="DefaultSource" switchName="DefaultSwitch">
|
||||
<listeners>
|
||||
<add name="FileLog"/>
|
||||
<add name="FileLog" />
|
||||
<!-- Auskommentierung des nachfolgenden Abschnitts aufheben, um in das Anwendungsereignisprotokoll zu schreiben -->
|
||||
<!--<add name="EventLog"/>-->
|
||||
</listeners>
|
||||
</source>
|
||||
</sources>
|
||||
<switches>
|
||||
<add name="DefaultSwitch" value="Information"/>
|
||||
<add name="DefaultSwitch" value="Information" />
|
||||
</switches>
|
||||
<sharedListeners>
|
||||
<add name="FileLog" type="Microsoft.VisualBasic.Logging.FileLogTraceListener, Microsoft.VisualBasic, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" initializeData="FileLogWriter"/>
|
||||
<add name="FileLog" type="Microsoft.VisualBasic.Logging.FileLogTraceListener, Microsoft.VisualBasic, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" initializeData="FileLogWriter" />
|
||||
<!-- Auskommentierung des nachfolgenden Abschnitts aufheben und APPLICATION_NAME durch den Namen der Anwendung ersetzen, um in das Anwendungsereignisprotokoll zu schreiben -->
|
||||
<!--<add name="EventLog" type="System.Diagnostics.EventLogTraceListener" initializeData="APPLICATION_NAME"/> -->
|
||||
</sharedListeners>
|
||||
@@ -25,7 +25,7 @@
|
||||
<netTcpBinding>
|
||||
<binding name="NetTcpBinding_IEDMIService" transferMode="Streamed">
|
||||
<security>
|
||||
<transport sslProtocols="None"/>
|
||||
<transport sslProtocols="None" />
|
||||
</security>
|
||||
</binding>
|
||||
</netTcpBinding>
|
||||
@@ -33,7 +33,7 @@
|
||||
<client>
|
||||
<endpoint address="net.tcp://localhost:9000/DigitalData/Services/Main" binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IEDMIService" contract="EDMIServiceReference.IEDMIService" name="NetTcpBinding_IEDMIService">
|
||||
<identity>
|
||||
<userPrincipalName value="Administrator@dd-san01.dd-gan.local.digitaldata.works"/>
|
||||
<userPrincipalName value="Administrator@dd-san01.dd-gan.local.digitaldata.works" />
|
||||
</identity>
|
||||
</endpoint>
|
||||
</client>
|
||||
@@ -41,9 +41,9 @@
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="FirebirdSql.Data.FirebirdClient" publicKeyToken="3750abcc3150b00c" culture="neutral"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-7.5.0.0" newVersion="7.5.0.0"/>
|
||||
<assemblyIdentity name="FirebirdSql.Data.FirebirdClient" publicKeyToken="3750abcc3150b00c" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-7.5.0.0" newVersion="7.5.0.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/></startup></configuration>
|
||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" /></startup></configuration>
|
||||
|
||||
@@ -45,6 +45,10 @@
|
||||
<OptionInfer>On</OptionInfer>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="DigitalData.Modules.Logging, Version=2.6.5.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\Logging\bin\Debug\DigitalData.Modules.Logging.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="NLog, Version=5.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NLog.5.0.5\lib\net46\NLog.dll</HintPath>
|
||||
@@ -114,11 +118,5 @@
|
||||
</None>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Logging\Logging.vbproj">
|
||||
<Project>{903b2d7d-3b80-4be9-8713-7447b704e1b0}</Project>
|
||||
<Name>Logging</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
|
||||
</Project>
|
||||
@@ -8,12 +8,12 @@ Imports System.Runtime.InteropServices
|
||||
|
||||
' Werte der Assemblyattribute überprüfen
|
||||
|
||||
<Assembly: AssemblyTitle("Encryption")>
|
||||
<Assembly: AssemblyDescription("")>
|
||||
<Assembly: AssemblyCompany("")>
|
||||
<Assembly: AssemblyProduct("Encryption")>
|
||||
<Assembly: AssemblyTitle("DDModules.DDEncryption")>
|
||||
<Assembly: AssemblyDescription("Stellt Funktionen zur Entschlüsselung bereit")>
|
||||
<Assembly: AssemblyCompany("Digital Data Gmbh, Heuchelheim")>
|
||||
<Assembly: AssemblyProduct("DDModules.Encryption")>
|
||||
<Assembly: AssemblyCopyright("Copyright © 2021")>
|
||||
<Assembly: AssemblyTrademark("1.2.0.0")>
|
||||
<Assembly: AssemblyTrademark("")>
|
||||
|
||||
<Assembly: ComVisible(False)>
|
||||
|
||||
@@ -31,5 +31,5 @@ Imports System.Runtime.InteropServices
|
||||
' indem Sie "*" wie unten gezeigt eingeben:
|
||||
' <Assembly: AssemblyVersion("1.0.*")>
|
||||
|
||||
<Assembly: AssemblyVersion("1.2.0.0")>
|
||||
<Assembly: AssemblyFileVersion("1.2.0.0")>
|
||||
<Assembly: AssemblyVersion("1.3.1.0")>
|
||||
<Assembly: AssemblyFileVersion("1.3.1.0")>
|
||||
|
||||
@@ -39,9 +39,6 @@ Public Class File
|
||||
' Source: https://docs.microsoft.com/de-de/windows/win32/fileio/naming-a-file?redirectedfrom=MSDN#maximum-path-length-limitation
|
||||
Private Const MAX_FILE_PATH_LENGTH = 250
|
||||
|
||||
' This prevents an infinite loop when no file can be created in a location
|
||||
Private Const MAX_FILE_VERSION = 100
|
||||
|
||||
Private Const FILE_NAME_ACCESS_TEST = "accessTest.txt"
|
||||
|
||||
Public Sub New(LogConfig As LogConfig)
|
||||
@@ -103,14 +100,6 @@ Public Class File
|
||||
Return FormatHash(oChecksum)
|
||||
End Function
|
||||
|
||||
Public Function GetHash(FilePath As String) As String
|
||||
Return GetChecksum(FilePath)
|
||||
End Function
|
||||
|
||||
Public Function GetHashFromString(pStringToCheck As String) As String
|
||||
Return GetChecksumFromString(pStringToCheck)
|
||||
End Function
|
||||
|
||||
Private Function FormatHash(pChecksum)
|
||||
Return BitConverter.
|
||||
ToString(pChecksum).
|
||||
@@ -120,21 +109,11 @@ Public Class File
|
||||
''' <summary>
|
||||
''' Adds file version string to given filename `Destination` if that file already exists.
|
||||
''' </summary>
|
||||
''' <param name="pFilePath">Filepath to check</param>
|
||||
''' <returns>Versioned string</returns>
|
||||
Public Function GetVersionedFilename(pFilePath As String) As String
|
||||
Return GetVersionedFilenameWithFilecheck(pFilePath, Function(pPath As String) IO.File.Exists(pFilePath))
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Adds file version string to given filename `Destination` if that file already exists.
|
||||
''' </summary>
|
||||
''' <param name="pFilePath">Filepath to check</param>
|
||||
''' <param name="pFileExistsAction">Custom action to check for file existence</param>
|
||||
''' <returns>Versioned string</returns>
|
||||
Public Function GetVersionedFilenameWithFilecheck(pFilePath As String, pFileExistsAction As Func(Of String, Boolean)) As String
|
||||
''' <param name="Destination"></param>
|
||||
''' <returns></returns>
|
||||
Public Function GetVersionedFilename(Destination As String) As String
|
||||
Try
|
||||
Dim oFileName As String = pFilePath
|
||||
Dim oFileName As String = Destination
|
||||
Dim oFinalFileName = oFileName
|
||||
|
||||
Dim oDestinationDir = Path.GetDirectoryName(oFileName)
|
||||
@@ -142,6 +121,33 @@ Public Class File
|
||||
|
||||
Dim oVersionSeparator As Char = "~"c
|
||||
|
||||
' 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
|
||||
|
||||
Dim oFileNameWithoutExtension = Path.GetFileNameWithoutExtension(oFileName)
|
||||
Dim oSplitResult = GetVersionedString(oFileNameWithoutExtension, oVersionSeparator)
|
||||
@@ -151,37 +157,31 @@ Public Class File
|
||||
|
||||
' Shorten the filename (only filename, without extension or version)
|
||||
' by cutting the length in half. This should work no matter how long the path and/or filename are.
|
||||
' The initial check operates on the full path to catch all scenarios.
|
||||
If pFilePath.Length > MAX_FILE_PATH_LENGTH Then
|
||||
If oFileName.Length > MAX_FILE_PATH_LENGTH Then
|
||||
_Logger.Info("Filename is too long. Filename will be cut to prevent further errors.")
|
||||
_Logger.Info("Original Filename is: {0}", oFileNameWithoutExtension)
|
||||
Dim oNewLength As Integer = CInt(Math.Floor(oFileNameWithoutExtension.Length / 2.0))
|
||||
Dim oNewLength As Integer = Math.Round(oFileNameWithoutExtension.Length / 2)
|
||||
Dim oNewFileNameWithoutExtension = oFileNameWithoutExtension.Substring(0, oNewLength)
|
||||
_Logger.Info("New Filename will be: {0}", oNewFileNameWithoutExtension)
|
||||
|
||||
oFileNameWithoutExtension = oNewFileNameWithoutExtension
|
||||
End If
|
||||
|
||||
' while file exists, increment version.
|
||||
' version cannot go above MAX_FILE_VERSION, to prevent infinite loop
|
||||
' while file exists, increment version
|
||||
Do
|
||||
If oFileVersion >= MAX_FILE_VERSION Then
|
||||
Throw New OverflowException($"Tried '{MAX_FILE_VERSION}' times to version filename before giving up. Sorry.")
|
||||
End If
|
||||
|
||||
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 pFileExistsAction(oFinalFileName) = True
|
||||
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!", pFilePath)
|
||||
_Logger.Warn("Filename {0} could not be versioned. Original filename will be returned!", Destination)
|
||||
_Logger.Error(ex)
|
||||
Return pFilePath
|
||||
Return Destination
|
||||
End Try
|
||||
End Function
|
||||
|
||||
@@ -221,8 +221,6 @@ Public Class File
|
||||
oStringVersion = 1
|
||||
End If
|
||||
|
||||
_Logger.Debug("Versioned: String [{0}], Version [{1}]", pString, oStringVersion)
|
||||
|
||||
Return New Tuple(Of String, Integer)(pString, oStringVersion)
|
||||
End Function
|
||||
|
||||
@@ -420,34 +418,6 @@ Public Class File
|
||||
Return oIsDirectory
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Checks the size of the supplied file.
|
||||
''' </summary>
|
||||
''' <param name="pFilePath"></param>
|
||||
''' <param name="pMaxFileSizeInMegaBytes"></param>
|
||||
''' <returns></returns>
|
||||
Public Function TestFileSizeIsLessThanMaxFileSize(pFilePath As String, pMaxFileSizeInMegabytes As Integer) As Boolean
|
||||
Dim oFileInfo As New FileInfo(pFilePath)
|
||||
|
||||
_Logger.Info("Checking Filesize of {0}", oFileInfo.Name)
|
||||
_Logger.Debug("Filesize threshold is {0} MB.", pMaxFileSizeInMegabytes)
|
||||
|
||||
If pMaxFileSizeInMegabytes <= 0 Then
|
||||
_Logger.Debug("Filesize is not configured. Skipping check.")
|
||||
Return True
|
||||
End If
|
||||
|
||||
Dim oMaxSize = pMaxFileSizeInMegabytes * 1024 * 1024
|
||||
|
||||
If oMaxSize > 0 And oFileInfo.Length > oMaxSize Then
|
||||
_Logger.Debug("Filesize is bigger than threshold.")
|
||||
Return False
|
||||
Else
|
||||
_Logger.Debug("Filesize is smaller than threshold. All fine.")
|
||||
Return True
|
||||
End If
|
||||
End Function
|
||||
|
||||
Public Function GetDateDirectory(pBaseDirectory As String, pDate As Date) As String
|
||||
Dim oDateDirectory = GetDateString(pDate)
|
||||
Dim oFinalDirectory As String = IO.Path.Combine(pBaseDirectory, oDateDirectory)
|
||||
|
||||
@@ -44,6 +44,10 @@
|
||||
<OptionInfer>On</OptionInfer>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="DigitalData.Modules.Logging, Version=2.6.5.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\Logging\bin\Debug\DigitalData.Modules.Logging.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="NLog, Version=5.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NLog.5.0.5\lib\net46\NLog.dll</HintPath>
|
||||
@@ -125,10 +129,6 @@
|
||||
<Project>{8a8f20fc-c46e-41ac-bee7-218366cfff99}</Project>
|
||||
<Name>Encryption</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Logging\Logging.vbproj">
|
||||
<Project>{903b2d7d-3b80-4be9-8713-7447b704e1b0}</Project>
|
||||
<Name>Logging</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
|
||||
</Project>
|
||||
@@ -9,11 +9,11 @@ Imports System.Runtime.InteropServices
|
||||
' Werte der Assemblyattribute überprüfen
|
||||
|
||||
<Assembly: AssemblyTitle("Modules.Filesystem")>
|
||||
<Assembly: AssemblyDescription("")>
|
||||
<Assembly: AssemblyDescription("Stellt Funktionen für das Filesystem und Container zur Verfügung")>
|
||||
<Assembly: AssemblyCompany("Digital Data")>
|
||||
<Assembly: AssemblyProduct("Modules.Filesystem")>
|
||||
<Assembly: AssemblyCopyright("Copyright © 2023")>
|
||||
<Assembly: AssemblyTrademark("1.5.1.1")>
|
||||
<Assembly: AssemblyCopyright("Copyright © 2022")>
|
||||
<Assembly: AssemblyTrademark("1.3.1.0")>
|
||||
|
||||
<Assembly: ComVisible(False)>
|
||||
|
||||
@@ -31,5 +31,5 @@ Imports System.Runtime.InteropServices
|
||||
' übernehmen, indem Sie "*" eingeben:
|
||||
' <Assembly: AssemblyVersion("1.0.*")>
|
||||
|
||||
<Assembly: AssemblyVersion("1.5.1.1")>
|
||||
<Assembly: AssemblyFileVersion("1.5.1.1")>
|
||||
<Assembly: AssemblyVersion("1.3.3.0")>
|
||||
<Assembly: AssemblyFileVersion("1.3.3.0")>
|
||||
|
||||
2
Filesystem/My Project/Settings.Designer.vb
generated
2
Filesystem/My Project/Settings.Designer.vb
generated
@@ -15,7 +15,7 @@ Option Explicit On
|
||||
Namespace My
|
||||
|
||||
<Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
|
||||
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.4.0.0"), _
|
||||
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.9.0.0"), _
|
||||
Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
||||
Partial Friend NotInheritable Class MySettings
|
||||
Inherits Global.System.Configuration.ApplicationSettingsBase
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="NLog" version="5.0.5" targetFramework="net461" />
|
||||
<package id="NLog" version="5.0.5" targetFramework="net48" />
|
||||
<package id="NuGet.CommandLine" version="6.13.2" targetFramework="net48" developmentDependency="true" />
|
||||
<package id="protobuf-net" version="2.4.0" targetFramework="net461" />
|
||||
</packages>
|
||||
@@ -37,23 +37,22 @@ Public Class ActiveDirectoryInterface
|
||||
_logger.Info("Using RootPath {0}", _rootPath)
|
||||
End Sub
|
||||
|
||||
Public Function SyncUsersForGroup(GroupName As String, Firebird As Firebird, MSSQL As MSSQLServer) As List(Of ADUser)
|
||||
Public Function SyncUsersForGroup(GroupName As String, MSSQL As MSSQLServer) As List(Of ADUser)
|
||||
Try
|
||||
Return SyncUsersForGroup(GroupName, New List(Of AttributeMapping), Firebird, MSSQL)
|
||||
Return SyncUsersForGroup(GroupName, New List(Of AttributeMapping), MSSQL)
|
||||
Catch ex As Exception
|
||||
_logger.Error(ex)
|
||||
Return Nothing
|
||||
End Try
|
||||
End Function
|
||||
|
||||
Public Function SyncUsersForGroup(GroupName As String, AttributeMappings As List(Of AttributeMapping), Firebird As Firebird, MSSQL As MSSQLServer, Optional Filter As String = DEFAULT_USER_FILTER) As List(Of ADUser)
|
||||
Public Function SyncUsersForGroup(GroupName As String, AttributeMappings As List(Of AttributeMapping), MSSQL As MSSQLServer, Optional Filter As String = DEFAULT_USER_FILTER) As List(Of ADUser)
|
||||
Dim oUsers As New List(Of ADUser)
|
||||
Dim oSyncedUsers As New List(Of ADUser)
|
||||
Dim oGroupId As Int64 = Nothing
|
||||
|
||||
Dim oFirebirdSync As New SyncUsers.SyncUsersFirebird(_logConfig, Firebird)
|
||||
Dim oSQLSync As New SyncUsers.SyncUsersMSSQL(_logConfig, MSSQL)
|
||||
Dim oSyncedUsersFirebird, oSyncedUsersMSSQL As List(Of ADUser)
|
||||
Dim oSyncedUsersMSSQL As List(Of ADUser)
|
||||
|
||||
Try
|
||||
_logger.Debug("Fetching users from ActiveDirectory")
|
||||
@@ -64,16 +63,6 @@ Public Class ActiveDirectoryInterface
|
||||
Return Nothing
|
||||
End Try
|
||||
|
||||
' Do the actual sync into firebird
|
||||
If Firebird IsNot Nothing Then
|
||||
oSyncedUsersFirebird = oFirebirdSync.SyncUsers(GroupName, oUsers, AttributeMappings)
|
||||
If oSyncedUsersFirebird.Count > 0 Then
|
||||
_logger.Debug("Synced {0} users to Firebird", oSyncedUsersFirebird.Count)
|
||||
End If
|
||||
Else
|
||||
_logger.Debug("SyncUsersForGroup: _firebird is nothing. ")
|
||||
End If
|
||||
|
||||
' Do the actual sync into MSSQL
|
||||
If MSSQL IsNot Nothing Then
|
||||
oSyncedUsersMSSQL = oSQLSync.SyncUsers(GroupName, oUsers, AttributeMappings)
|
||||
@@ -81,7 +70,7 @@ Public Class ActiveDirectoryInterface
|
||||
_logger.Debug("Synced {0} users to MSSQLServer", oSyncedUsersMSSQL.Count)
|
||||
End If
|
||||
Else
|
||||
_logger.Debug("SyncUsersForGroup: _mssql is nothing. ")
|
||||
_logger.Debug("SyncUsersForGroup: _mssql is nothing.")
|
||||
End If
|
||||
|
||||
Return oUsers
|
||||
@@ -231,10 +220,23 @@ Public Class ActiveDirectoryInterface
|
||||
Return oUsers
|
||||
End Try
|
||||
End Function
|
||||
Private Function GetPartFromFirstOU(dnString As String) As String
|
||||
Dim keyword As String = "OU="
|
||||
Dim index As Integer = dnString.IndexOf(keyword)
|
||||
|
||||
Public Function FindUserWithFilter(User As UserPrincipalEx, Filter As String) As Boolean
|
||||
If index <> -1 Then
|
||||
Return dnString.Substring(index)
|
||||
Else
|
||||
Return "No_Result_from_GetPartFromFirstOU"
|
||||
End If
|
||||
End Function
|
||||
Public Function FindUserWithFilter(pUser As UserPrincipalEx, pFilter As String) As Boolean
|
||||
Try
|
||||
Dim oRootPath = String.Join(","c, User.DistinguishedName.Split(","c).Skip(1))
|
||||
'Dim oRootPath = String.Join(","c, pUser.DistinguishedName.Split(","c).Skip(1))
|
||||
Dim oRootPath = GetPartFromFirstOU(pUser.DistinguishedName)
|
||||
_logger.Debug("FindUserWithFilter: pUser.DistinguishedName: [{0}]", pUser.DistinguishedName)
|
||||
_logger.Debug("FindUserWithFilter: oRootPath from User.DistinguishedName: [{0}]", oRootPath)
|
||||
|
||||
Dim oPlaceholder = "@SAMACCOUNTNAME"
|
||||
Dim oProtocol = "LDAP://"
|
||||
Dim oEntry As New DirectoryEntry(oProtocol & oRootPath) With {
|
||||
@@ -242,22 +244,25 @@ Public Class ActiveDirectoryInterface
|
||||
.Password = Nothing,
|
||||
.AuthenticationType = AuthenticationTypes.Secure
|
||||
}
|
||||
|
||||
If Filter = String.Empty Then
|
||||
_logger.Debug("FindUserWithFilter: Filter was empty, returning True for User [{0}]", User.SamAccountName)
|
||||
_logger.Debug("FindUserWithFilter: got oDirectoryEntry (Path): [{0}]", oProtocol & oRootPath)
|
||||
If pFilter = String.Empty Then
|
||||
_logger.Debug("FindUserWithFilter: Filter was empty, returning True for User [{0}]", pUser.SamAccountName)
|
||||
Return True
|
||||
End If
|
||||
|
||||
If Filter.Contains(oPlaceholder) Then
|
||||
Filter = Filter.Replace(oPlaceholder, User.SamAccountName)
|
||||
If pFilter.Contains(oPlaceholder) Then
|
||||
pFilter = pFilter.Replace(oPlaceholder, pUser.SamAccountName)
|
||||
_logger.Debug("FindUserWithFilter: Filter.Contains(oPlaceholder) [{0}]", pFilter)
|
||||
Else
|
||||
_logger.Warn("FindUserWithFilter: Placeholder [{0}] was not found in filter. Results may not be correct.")
|
||||
End If
|
||||
|
||||
Dim oSearcher As New DirectorySearcher(oEntry, Filter)
|
||||
Dim oSearcher As New DirectorySearcher(oEntry, pFilter)
|
||||
_logger.Debug("FindUserWithFilter: oSearcher created! Now executing DirectoryServices.SearchResult with .FindOne ...")
|
||||
Dim oResult As SearchResult = oSearcher.FindOne()
|
||||
|
||||
If oResult IsNot Nothing AndAlso oResult.Path.Replace(oProtocol, String.Empty) = User.DistinguishedName Then
|
||||
If oResult IsNot Nothing AndAlso oResult.Path.Replace(oProtocol, String.Empty) = pUser.DistinguishedName Then
|
||||
_logger.Debug("FindUserWithFilter: We have an oResult - oResult.Path: [{0}]", oResult.Path)
|
||||
Return True
|
||||
Else
|
||||
Return False
|
||||
|
||||
@@ -1,145 +0,0 @@
|
||||
Imports DigitalData.Modules.Database
|
||||
Imports DigitalData.Modules.Interfaces
|
||||
Imports DigitalData.Modules.Logging
|
||||
|
||||
Namespace SyncUsers
|
||||
Public Class SyncUsersFirebird
|
||||
Implements ISyncUsers
|
||||
|
||||
Private ReadOnly _logConfig As LogConfig
|
||||
Private ReadOnly _logger As Logger
|
||||
Private ReadOnly _firebird As Database.Firebird
|
||||
|
||||
Public Sub New(LogConfig As LogConfig, Firebird As Database.Firebird)
|
||||
_logConfig = LogConfig
|
||||
_logger = LogConfig.GetLogger()
|
||||
_firebird = Firebird
|
||||
End Sub
|
||||
|
||||
Public Function SyncUsers(GroupName As String, Users As List(Of ADUser), PropertyMapping As List(Of AttributeMapping)) As List(Of ADUser) Implements ISyncUsers.SyncUsers
|
||||
Dim oGroupId As Integer
|
||||
Dim oSyncedUsers As New List(Of ADUser)
|
||||
|
||||
Try
|
||||
_logger.Debug("Getting group Id for group [{0}]", GroupName)
|
||||
oGroupId = GetGroupId(GroupName)
|
||||
|
||||
If oGroupId = 0 Then
|
||||
_logger.Debug("Group [{0}] does not exist in database or is not enabled for sync.", GroupName)
|
||||
Return oSyncedUsers
|
||||
End If
|
||||
|
||||
_logger.Debug("Using group Id [{0}]", oGroupId)
|
||||
Catch ex As Exception
|
||||
_logger.Error(ex)
|
||||
Return oSyncedUsers
|
||||
End Try
|
||||
|
||||
For Each oUser In Users
|
||||
Dim oUserId As Int64
|
||||
Dim oUserExists As Boolean = False
|
||||
|
||||
' Check if user already exists
|
||||
Try
|
||||
_logger.Debug("Checking if user [{0}] exists", oUser)
|
||||
oUserId = GetUserId(oUser.samAccountName)
|
||||
oUserExists = Not IsNothing(oUserId)
|
||||
_logger.Debug("User [{0}] exists in database: ", oUser, oUserExists)
|
||||
Catch ex As Exception
|
||||
_logger.Error(ex)
|
||||
_logger.Warn("Could not get UserId for user. Skipping")
|
||||
Continue For
|
||||
End Try
|
||||
|
||||
' I user does not exist, create a new user
|
||||
Try
|
||||
If Not oUserExists Then
|
||||
_logger.Debug("Creating new user for [{0}]", oUser)
|
||||
oUserId = CreateUser(oUser)
|
||||
_logger.Debug("User created with Id [{0}]", oUserId)
|
||||
End If
|
||||
Catch ex As Exception
|
||||
_logger.Error(ex)
|
||||
_logger.Warn("Could not create user. Skipping")
|
||||
Continue For
|
||||
End Try
|
||||
|
||||
' Add the user to group
|
||||
Try
|
||||
AddUserToGroup(oUserId, oGroupId)
|
||||
Catch ex As Exception
|
||||
_logger.Error(ex)
|
||||
_logger.Warn("Could not add user to group. Skipping")
|
||||
Continue For
|
||||
End Try
|
||||
|
||||
oSyncedUsers.Add(oUser)
|
||||
Next
|
||||
|
||||
Return oSyncedUsers
|
||||
End Function
|
||||
|
||||
Private Function AddUserToGroup(UserId As Integer, GroupId As Integer) As Boolean Implements ISyncUsers.AddUserToGroup
|
||||
Try
|
||||
Dim oSQL = $"SELECT FNICM_RADM_NEW_USER2GROUP({UserId}, {GroupId}, 'AD-Sync') from RDB$DATABASE"
|
||||
Dim oRecordId = _firebird.GetScalarValue(oSQL)
|
||||
|
||||
If IsDBNull(oRecordId) Then
|
||||
_logger.Warn("UserId {0} - GroupId {1} relation already exists.", UserId, GroupId)
|
||||
Return False
|
||||
End If
|
||||
|
||||
Return True
|
||||
Catch ex As Exception
|
||||
_logger.Error(ex)
|
||||
Throw ex
|
||||
End Try
|
||||
End Function
|
||||
Private Function GetGroupId(GroupName As String) As Integer Implements ISyncUsers.GetGroupId
|
||||
Try
|
||||
Dim oSQL As String = $"SELECT FNICM_GET_RECORD4SYSKEY('{GroupName}','002-NAME') from RDB$DATABASE"
|
||||
Dim oGroupId = _firebird.GetScalarValue(oSQL)
|
||||
|
||||
If IsDBNull(oGroupId) OrElse oGroupId = 0 Then
|
||||
_logger.Debug("Group {0} not found in database", GroupName)
|
||||
Return Nothing
|
||||
End If
|
||||
|
||||
Return oGroupId
|
||||
Catch ex As Exception
|
||||
_logger.Error(ex)
|
||||
Throw ex
|
||||
End Try
|
||||
End Function
|
||||
Private Function GetUserId(UserName As String) As Integer Implements ISyncUsers.GetUserId
|
||||
Try
|
||||
Dim oSQL As String = $"SELECT FNICM_GET_RECORD4SYSKEY('{UserName}','001-USRNAME') from RDB$DATABASE"
|
||||
Dim oResult = _firebird.GetScalarValue(oSQL)
|
||||
|
||||
If IsDBNull(oResult) Then
|
||||
Return Nothing
|
||||
End If
|
||||
|
||||
Return oResult
|
||||
Catch ex As Exception
|
||||
_logger.Error(ex)
|
||||
Throw ex
|
||||
End Try
|
||||
End Function
|
||||
Private Function CreateUser(User As ADUser) As Integer Implements ISyncUsers.CreateUser
|
||||
Try
|
||||
Dim oSQL = $"SELECT FNICM_RADM_NEW_USER('{User?.GivenName}', '{User?.Surname}', '{User?.samAccountName}', 'AD-Sync') from RDB$DATABASE"
|
||||
Dim oUserId As Integer = _firebird.GetScalarValue(oSQL)
|
||||
|
||||
Return oUserId
|
||||
Catch ex As Exception
|
||||
_logger.Error(ex)
|
||||
Throw ex
|
||||
End Try
|
||||
End Function
|
||||
|
||||
Public Sub AddCustomAttributesToUser(User As ADUser, UserId As Integer) Implements ISyncUsers.AddCustomAttributesToUser
|
||||
Throw New NotImplementedException()
|
||||
End Sub
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -1,6 +1,6 @@
|
||||
Imports DigitalData.Modules.Database
|
||||
Imports DigitalData.Modules.Logging
|
||||
Imports DigitalData.Modules.Language
|
||||
Imports DigitalData.Modules.Base
|
||||
|
||||
Namespace SyncUsers
|
||||
Public Class SyncUsersMSSQL
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -22,6 +22,15 @@ Public Class GraphQLInterface
|
||||
Public Property Proxy As WebProxy
|
||||
Public Property Credentials As NetworkCredential
|
||||
|
||||
Public Event LogRequested As EventHandler(Of String)
|
||||
|
||||
Public ReadOnly Property Certificate As X509Certificate2
|
||||
Get
|
||||
Return _certificate
|
||||
End Get
|
||||
End Property
|
||||
|
||||
|
||||
Public Sub New(LogConfig As LogConfig, BaseUrl As String, Email As String, Password As String, CertificateFingerprint As String)
|
||||
Try
|
||||
_logConfig = LogConfig
|
||||
@@ -46,6 +55,10 @@ Public Class GraphQLInterface
|
||||
Exit For
|
||||
End If
|
||||
Next
|
||||
|
||||
If oCertificate IsNot Nothing Then
|
||||
Exit For
|
||||
End If
|
||||
Next
|
||||
|
||||
|
||||
@@ -103,10 +116,18 @@ Public Class GraphQLInterface
|
||||
|
||||
Public Function Login() As HttpWebResponse
|
||||
Try
|
||||
RaiseEvent LogRequested(Me, $"Login started with user: [{_userEmail}]")
|
||||
|
||||
Dim oLoginData As New LoginData() With {.email = _userEmail, .token = _userPassword}
|
||||
Dim oBytes As Byte() = ToBytes(JsonConvert.SerializeObject(oLoginData))
|
||||
Dim oRequest As HttpWebRequest = GetRequest("/login", oBytes)
|
||||
|
||||
RaiseEvent LogRequested(Me, $"Sending HTTP request to GraphQL")
|
||||
RaiseEvent LogRequested(Me, $"Request Host: [{oRequest.Host}]")
|
||||
RaiseEvent LogRequested(Me, $"Request Address: [{oRequest.Address}]")
|
||||
RaiseEvent LogRequested(Me, $"Request Method: [{oRequest.Method}]")
|
||||
RaiseEvent LogRequested(Me, $"Request ContentType: [{oRequest.ContentType}]")
|
||||
|
||||
Using oStream = oRequest.GetRequestStream()
|
||||
oStream.Write(oBytes, 0, oBytes.Length)
|
||||
End Using
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
<MyType>Windows</MyType>
|
||||
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
|
||||
<TargetFrameworkProfile />
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@@ -44,30 +46,170 @@
|
||||
<OptionInfer>On</OptionInfer>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="GdPicture.NET.14">
|
||||
<HintPath>D:\ProgramFiles\GdPicture.NET 14\Redist\GdPicture.NET (.NET Framework 4.5)\GdPicture.NET.14.dll</HintPath>
|
||||
<Reference Include="BouncyCastle.Cryptography, Version=2.0.0.0, Culture=neutral, PublicKeyToken=072edcf4a5328938, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\BouncyCastle.Cryptography.2.5.0\lib\net461\BouncyCastle.Cryptography.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="DigitalData.Modules.Base">
|
||||
<HintPath>..\Base\bin\Debug\DigitalData.Modules.Base.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="DigitalData.Modules.Database">
|
||||
<HintPath>..\Database\bin\Debug\DigitalData.Modules.Database.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="DigitalData.Modules.Logging">
|
||||
<HintPath>..\Logging\bin\Debug\DigitalData.Modules.Logging.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="DocumentFormat.OpenXml, Version=3.2.0.0, Culture=neutral, PublicKeyToken=8fb06cb64d019a17, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\DocumentFormat.OpenXml.3.2.0\lib\net46\DocumentFormat.OpenXml.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="DocumentFormat.OpenXml.Framework, Version=3.2.0.0, Culture=neutral, PublicKeyToken=8fb06cb64d019a17, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\DocumentFormat.OpenXml.Framework.3.2.0\lib\net46\DocumentFormat.OpenXml.Framework.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GdPicture.NET.14, Version=14.3.3.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GdPicture.NET.14.barcode.1d.writer, Version=14.3.3.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.barcode.1d.writer.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GdPicture.NET.14.barcode.2d.writer, Version=14.3.3.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.barcode.2d.writer.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GdPicture.NET.14.CAD, Version=14.3.3.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.CAD.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GdPicture.NET.14.CAD.DWG, Version=14.3.3.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.CAD.DWG.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GdPicture.NET.14.Common, Version=14.3.3.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.Common.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GdPicture.NET.14.Document, Version=14.3.3.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.Document.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GdPicture.NET.14.Email, Version=14.3.3.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.Email.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GdPicture.NET.14.HTML, Version=14.3.3.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.HTML.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GdPicture.NET.14.Imaging, Version=14.3.3.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.Imaging.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GdPicture.NET.14.Imaging.Formats, Version=14.3.3.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.Imaging.Formats.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GdPicture.NET.14.Imaging.Formats.Conversion, Version=14.3.3.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.Imaging.Formats.Conversion.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GdPicture.NET.14.Imaging.Rendering, Version=14.3.3.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.Imaging.Rendering.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GdPicture.NET.14.MSOfficeBinary, Version=14.3.3.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.MSOfficeBinary.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GdPicture.NET.14.OpenDocument, Version=14.3.3.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.OpenDocument.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GdPicture.NET.14.OpenXML, Version=14.3.3.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.OpenXML.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GdPicture.NET.14.OpenXML.Templating, Version=14.3.3.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.OpenXML.Templating.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GdPicture.NET.14.PDF, Version=14.3.3.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.PDF.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GdPicture.NET.14.RTF, Version=14.3.3.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.RTF.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GdPicture.NET.14.SVG, Version=14.3.3.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.SVG.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GdPicture.NET.14.wia.gateway, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6973b5c22dcf45f7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.wia.gateway.dll</HintPath>
|
||||
<EmbedInteropTypes>True</EmbedInteropTypes>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Bcl.AsyncInterfaces.8.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json.Bson, Version=1.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Newtonsoft.Json.Bson.1.0.2\lib\net45\Newtonsoft.Json.Bson.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="NLog, Version=5.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NLog.5.0.5\lib\net46\NLog.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="OpenMcdf, Version=2.4.1.0, Culture=neutral, PublicKeyToken=fdbb1629d7c00800, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\OpenMcdf.2.4.1\lib\net40\OpenMcdf.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="protobuf-net, Version=3.0.0.0, Culture=neutral, PublicKeyToken=257b51d87d2e4d67, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\protobuf-net.3.2.46\lib\net462\protobuf-net.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="protobuf-net.Core, Version=3.0.0.0, Culture=neutral, PublicKeyToken=257b51d87d2e4d67, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\protobuf-net.Core.3.2.46\lib\net462\protobuf-net.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RtfPipe, Version=2.0.7677.4303, Culture=neutral, PublicKeyToken=5f6ab4ce530296d2, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\RtfPipe.2.0.7677.4303\lib\net45\RtfPipe.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Buffers, Version=4.0.4.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Buffers.4.6.0\lib\net462\System.Buffers.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.CodeDom, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.CodeDom.8.0.0\lib\net462\System.CodeDom.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Collections.Immutable, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Collections.Immutable.8.0.0\lib\net462\System.Collections.Immutable.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.DirectoryServices" />
|
||||
<Reference Include="System.DirectoryServices.AccountManagement" />
|
||||
<Reference Include="System.IO.Compression" />
|
||||
<Reference Include="System.IO.Packaging, Version=8.0.0.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.IO.Packaging.8.0.1\lib\net462\System.IO.Packaging.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Management" />
|
||||
<Reference Include="System.Memory, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Memory.4.6.0\lib\net462\System.Memory.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Http.Formatting, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.AspNet.WebApi.Client.6.0.0\lib\net45\System.Net.Http.Formatting.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Numerics" />
|
||||
<Reference Include="System.Numerics.Vectors, Version=4.1.5.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Numerics.Vectors.4.6.0\lib\net462\System.Numerics.Vectors.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=6.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.6.1.0\lib\net462\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Serialization" />
|
||||
<Reference Include="System.Security" />
|
||||
<Reference Include="System.Security.Cryptography.Pkcs, Version=8.0.0.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Security.Cryptography.Pkcs.8.0.1\lib\net462\System.Security.Cryptography.Pkcs.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ServiceModel" />
|
||||
<Reference Include="System.Text.Encodings.Web, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Text.Encodings.Web.8.0.0\lib\net462\System.Text.Encodings.Web.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Text.Json, Version=8.0.0.6, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Text.Json.8.0.6\lib\net462\System.Text.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Transactions" />
|
||||
<Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.ValueTuple.4.5.0\lib\net461\System.ValueTuple.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="WindowsBase" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Import Include="Microsoft.VisualBasic" />
|
||||
@@ -86,7 +228,6 @@
|
||||
<Compile Include="ActiveDirectoryInterface\ActiveDirectoryUser.vb" />
|
||||
<Compile Include="ActiveDirectoryInterface\AttributeMap.vb" />
|
||||
<Compile Include="ActiveDirectoryInterface\ISyncUsers.vb" />
|
||||
<Compile Include="ActiveDirectoryInterface\SyncUsers.Firebird.vb" />
|
||||
<Compile Include="ActiveDirectoryInterface\SyncUsers.MSSQL.vb" />
|
||||
<Compile Include="ActiveDirectoryInterface\UserEqualityComparer.vb" />
|
||||
<Compile Include="ActiveDirectoryInterface\UserPrincipalEx.vb" />
|
||||
@@ -94,6 +235,8 @@
|
||||
<Compile Include="GrapQLInterface\LoginData.vb" />
|
||||
<Compile Include="GrapQLInterface\LogoutData.vb" />
|
||||
<Compile Include="GrapQLInterface\QueryData.vb" />
|
||||
<Compile Include="ZUGFeRDInterface\Enums\ErrorCodes.vb" />
|
||||
<Compile Include="ZUGFeRDInterface\Enums\Item_Types.vb" />
|
||||
<Compile Include="ZUGFeRDInterface\Exceptions.vb" />
|
||||
<Compile Include="My Project\AssemblyInfo.vb" />
|
||||
<Compile Include="My Project\Application.Designer.vb">
|
||||
@@ -111,6 +254,10 @@
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
<Compile Include="ZUGFeRDInterface\PDFConverter.vb" />
|
||||
<Compile Include="ZUGFeRDInterface\Peppol_UBL2.1\CreditNoteType.vb" />
|
||||
<Compile Include="ZUGFeRDInterface\Peppol_UBL2.1\InvoiceType.vb" />
|
||||
<Compile Include="ZUGFeRDInterface\RejectionStringRow.vb" />
|
||||
<Compile Include="ZUGFeRDInterface\Validator.vb" />
|
||||
<Compile Include="ZUGFeRDInterface\Version1.0\CrossIndustryDocumentType.vb" />
|
||||
<Compile Include="ZUGFeRDInterface.vb" />
|
||||
@@ -120,6 +267,9 @@
|
||||
<Compile Include="ZUGFeRDInterface\Version2.0\CrossIndustryInvoiceType.vb" />
|
||||
<Compile Include="ZUGFeRDInterface\Version2.1.1\CrossIndustryInvoiceType.vb" />
|
||||
<Compile Include="ZUGFeRDInterface\Version2.2_FacturX\CrossIndustryInvoiceType.vb" />
|
||||
<Compile Include="ZUGFeRDInterface\Version2.3_3_FacturX\CrossIndustryInvoiceType.vb" />
|
||||
<Compile Include="ZUGFeRDInterface\Version2.3_FacturX\CrossIndustryInvoiceType.vb" />
|
||||
<Compile Include="ZUGFeRDInterface\Version2.4_FacturX\CrossIndustryInvoiceType.vb" />
|
||||
<Compile Include="ZUGFeRDInterface\XmlItemProperty.vb" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -144,29 +294,21 @@
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AdditionalFiles Include="GdPicture.NET.14.filters.dll">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</AdditionalFiles>
|
||||
<AdditionalFiles Include="GdPicture.NET.14.image.gdimgplug.dll">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</AdditionalFiles>
|
||||
<AdditionalFiles Include="GdPicture.NET.14.Imaging.Rendering.Skia.dll">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</AdditionalFiles>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Database\Database.vbproj">
|
||||
<Project>{eaf0ea75-5fa7-485d-89c7-b2d843b03a96}</Project>
|
||||
<Name>Database</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Language\Language.vbproj">
|
||||
<Project>{d3c8cfed-d6f6-43a8-9bdf-454145d0352f}</Project>
|
||||
<Name>Language</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Logging\Logging.vbproj">
|
||||
<Project>{903b2d7d-3b80-4be9-8713-7447b704e1b0}</Project>
|
||||
<Name>Logging</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>powershell.exe -command "& { &'$(SolutionDir)copy-binary.ps1' '$(TargetPath)' '$(TargetFileName)' '$(ConfigurationName)' '$(ProjectName)' }"</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\packages\GdPicture.runtimes.windows.14.3.3\build\net462\GdPicture.runtimes.windows.targets" Condition="Exists('..\packages\GdPicture.runtimes.windows.14.3.3\build\net462\GdPicture.runtimes.windows.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>Dieses Projekt verweist auf mindestens ein NuGet-Paket, das auf diesem Computer fehlt. Verwenden Sie die Wiederherstellung von NuGet-Paketen, um die fehlenden Dateien herunterzuladen. Weitere Informationen finden Sie unter "http://go.microsoft.com/fwlink/?LinkID=322105". Die fehlende Datei ist "{0}".</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\GdPicture.runtimes.windows.14.3.3\build\net462\GdPicture.runtimes.windows.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\GdPicture.runtimes.windows.14.3.3\build\net462\GdPicture.runtimes.windows.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -12,8 +12,8 @@ Imports System.Runtime.InteropServices
|
||||
<Assembly: AssemblyDescription("")>
|
||||
<Assembly: AssemblyCompany("Digital Data")>
|
||||
<Assembly: AssemblyProduct("Modules.Interfaces")>
|
||||
<Assembly: AssemblyCopyright("Copyright © 2023")>
|
||||
<Assembly: AssemblyTrademark("1.12.0.0")>
|
||||
<Assembly: AssemblyCopyright("Copyright © 2025")>
|
||||
<Assembly: AssemblyTrademark("2.3.7.0")>
|
||||
|
||||
<Assembly: ComVisible(False)>
|
||||
|
||||
@@ -31,5 +31,5 @@ Imports System.Runtime.InteropServices
|
||||
' übernehmen, indem Sie "*" eingeben:
|
||||
' <Assembly: AssemblyVersion("1.0.*")>
|
||||
|
||||
<Assembly: AssemblyVersion("1.12.0.0")>
|
||||
<Assembly: AssemblyFileVersion("1.12.0.0")>
|
||||
<Assembly: AssemblyVersion("2.4.0.0")>
|
||||
<Assembly: AssemblyFileVersion("2.4.0.0")>
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
Imports System.Collections.Generic
|
||||
Imports System.IO
|
||||
Imports System.Reflection.Emit
|
||||
Imports System.IO
|
||||
Imports System.Xml
|
||||
Imports System.Xml.Serialization
|
||||
Imports System.Xml.XPath
|
||||
Imports System.Xml.Xsl
|
||||
Imports DigitalData.Modules.Interfaces.Exceptions
|
||||
Imports DigitalData.Modules.Interfaces.PDFEmbeds
|
||||
Imports DigitalData.Modules.Interfaces.ZUGFeRD
|
||||
Imports DigitalData.Modules.Interfaces.ZUGFeRDInterface
|
||||
Imports DigitalData.Modules.Logging
|
||||
Imports GdPicture14
|
||||
|
||||
@@ -23,6 +19,22 @@ Public Class ZUGFeRDInterface
|
||||
Public Const ZUGFERD_SPEC_DEFAULT = "DEFAULT"
|
||||
Public Const ZUGFERD_SPEC_10 = "ZUGFERD_10"
|
||||
Public Const ZUGFERD_SPEC_2x = "ZUGFERD_2x"
|
||||
Public Const ZUGFERD_SPEC_2_3x = "ZUGFERD_2_3x"
|
||||
|
||||
Public Const UBL_SPEC_21 = "UBL_21"
|
||||
|
||||
Public Const XMLSCHEMA_ZUGFERD_10 = "Version1_0"
|
||||
Public Const XMLSCHEMA_ZUGFERD_20 = "Version2_0"
|
||||
Public Const XMLSCHEMA_ZUGFERD_211 = "Version2_1_1"
|
||||
Public Const XMLSCHEMA_ZUGFERD_22 = "Version2_2_FacturX"
|
||||
Public Const XMLSCHEMA_ZUGFERD_23 = "Version2_3_FacturX"
|
||||
Public Const XMLSCHEMA_ZUGFERD_233 = "Version2_3_3_FacturX"
|
||||
Public Const XMLSCHEMA_ZUGFERD_24 = "Version2_4_FacturX"
|
||||
Public Const XMLSCHEMA_UBL_21_INVOICE = "UBL2_1_INVOICE"
|
||||
Public Const XMLSCHEMA_UBL_21_CREDITNOTE = "UBL2_1_CREDITNOTE"
|
||||
|
||||
Public Const RECEIPT_TYPE_XML = "XML"
|
||||
Public Const RECEIPT_TYPE_PDF = "PDF"
|
||||
|
||||
Private ReadOnly ValidFilenames As New List(Of String) From {
|
||||
PDFEmbeds.ZUGFERD_XML_FILENAME.ToUpper,
|
||||
@@ -40,6 +52,7 @@ Public Class ZUGFeRDInterface
|
||||
UnsupportedFormat
|
||||
FileTooBig
|
||||
UnknownError
|
||||
NotInUse
|
||||
End Enum
|
||||
|
||||
Public ReadOnly Property FileGroup As FileGroups
|
||||
@@ -50,6 +63,8 @@ Public Class ZUGFeRDInterface
|
||||
Public Property AllowXRechnung_Filename As Boolean = True
|
||||
Public Property AllowZugferd_1_0_Schema As Boolean = True
|
||||
Public Property AllowZugferd_2_x_Schema As Boolean = True
|
||||
Public Property AllowZugferd_2_3_x_Schema As Boolean = True
|
||||
Public Property AllowPeppol_3_x_Schema As Boolean = False
|
||||
End Class
|
||||
|
||||
Public Class ZugferdResult
|
||||
@@ -57,6 +72,11 @@ Public Class ZUGFeRDInterface
|
||||
Public Property XElementObject As XElement
|
||||
Public Property SchemaObject As Object
|
||||
Public Property Specification As String
|
||||
Public Property UsedXMLSchema As String
|
||||
''' <summary>
|
||||
''' Dateityp des Belegs: PDF oder XML
|
||||
''' </summary>
|
||||
Public Property ReceiptFileType As String
|
||||
Public Property ValidationErrors As New List(Of ZugferdValidationError)
|
||||
End Class
|
||||
|
||||
@@ -64,6 +84,7 @@ Public Class ZUGFeRDInterface
|
||||
Public ElementName As String
|
||||
Public ElementValue As String
|
||||
Public ErrorMessage As String
|
||||
Public ErrorMessageDE As String
|
||||
End Class
|
||||
|
||||
''' <summary>
|
||||
@@ -113,27 +134,86 @@ Public Class ZUGFeRDInterface
|
||||
AllowedFilenames = oAllowedFilenames
|
||||
End Sub
|
||||
|
||||
Public Function FilterPropertyMap(pPropertyMap As Dictionary(Of String, XmlItemProperty), pSpecification As String) As Dictionary(Of String, XmlItemProperty)
|
||||
_logger.Debug("Filtering Property map for Specification [{0}]", pSpecification)
|
||||
Public Function FilterPropertyMap(pPropertyMapList As List(Of XmlItemProperty), pSpecification As String) As Dictionary(Of String, XmlItemProperty)
|
||||
_logger.Debug("Filtering Property map list for Specification [{0}]", pSpecification)
|
||||
|
||||
If pSpecification = ZUGFERD_SPEC_10 Then
|
||||
_logger.Debug("Special Case [{0}], including [{1}]", ZUGFERD_SPEC_10, ZUGFERD_SPEC_DEFAULT)
|
||||
Return pPropertyMap.
|
||||
Where(Function(kv) kv.Value.Specification = pSpecification Or kv.Value.Specification = ZUGFERD_SPEC_DEFAULT).
|
||||
ToDictionary(Function(kv) kv.Key, Function(kv) kv.Value)
|
||||
Try
|
||||
|
||||
_logger.Debug("Special Case [{0}], including [{1}]", ZUGFERD_SPEC_10, ZUGFERD_SPEC_DEFAULT)
|
||||
|
||||
Dim countElements As Integer = pPropertyMapList.Where(Function(x) x.Specification = pSpecification Or x.Specification = ZUGFERD_SPEC_DEFAULT).Count
|
||||
_logger.Debug("Property map list contains [{0}] elements for specification [{1}]", countElements, pSpecification)
|
||||
|
||||
Return pPropertyMapList.
|
||||
Where(Function(kv) kv.Specification = pSpecification Or kv.Specification = ZUGFERD_SPEC_DEFAULT).
|
||||
ToDictionary(Function(kv) kv.XMLPath, Function(kv) kv)
|
||||
|
||||
Catch ex As Exception
|
||||
_logger.Error(ex)
|
||||
End Try
|
||||
Else
|
||||
_logger.Debug("Using Specification [{0}]", pSpecification)
|
||||
Return pPropertyMap.
|
||||
Where(Function(kv) kv.Value.Specification = pSpecification).
|
||||
ToDictionary(Function(kv) kv.Key, Function(kv) kv.Value)
|
||||
|
||||
Try
|
||||
|
||||
Dim countElements As Integer = pPropertyMapList.Where(Function(x) x.Specification = pSpecification).Count
|
||||
_logger.Debug("Property map list contains [{0}] elements for specification [{1}]", countElements, pSpecification)
|
||||
|
||||
Return pPropertyMapList.
|
||||
Where(Function(kv) kv.Specification = pSpecification).
|
||||
ToDictionary(Function(kv) kv.XMLPath, Function(kv) kv)
|
||||
|
||||
Catch ex As Exception
|
||||
_logger.Error(ex)
|
||||
End Try
|
||||
End If
|
||||
|
||||
Return Nothing
|
||||
End Function
|
||||
|
||||
Public Function GetSerializedXMLContentFromFile(oFileInfo As FileInfo) As ZugferdResult
|
||||
Dim oResult = New ZugferdResult()
|
||||
Dim oMessage As String = String.Empty
|
||||
|
||||
Try
|
||||
Dim oFileSize As Integer = oFileInfo.Length
|
||||
Dim oFileData As Byte() = File.ReadAllBytes(oFileInfo.FullName)
|
||||
|
||||
Dim oXmlFile As EmbeddedFile = New EmbeddedFile() With {
|
||||
.FileName = oFileInfo.Name,
|
||||
.FileContents = oFileData
|
||||
}
|
||||
|
||||
Using oStream As New MemoryStream(oXmlFile.FileContents)
|
||||
oResult = New ZugferdResult With {
|
||||
.DataFileName = oXmlFile.FileName,
|
||||
.XElementObject = XElement.Load(oStream)
|
||||
}
|
||||
End Using
|
||||
|
||||
Catch ex As ZUGFeRDExecption
|
||||
' Don't log ZUGFeRD Exceptions here, they should be handled by the calling code.
|
||||
' It also produces misleading error messages when checking if an attachment is a zugferd file.
|
||||
Throw ex
|
||||
|
||||
Catch ex As Exception
|
||||
_logger.Error(ex)
|
||||
Throw New ZUGFeRDExecption(ErrorCodes.UnsupportedFerdException, "Datei ist eine ungültige XML Datei.")
|
||||
End Try
|
||||
|
||||
If oResult.ValidationErrors.Any() Then
|
||||
Throw New ValidationException() With {
|
||||
.ValidationErrors = oResult.ValidationErrors
|
||||
}
|
||||
End If
|
||||
|
||||
Return SerializeZUGFeRDDocument(oResult)
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Validates a ZUGFeRD File and extracts the XML Document from it
|
||||
''' </summary>
|
||||
''' <param name="Path"></param>
|
||||
''' <exception cref="ZUGFeRDExecption"></exception>
|
||||
Public Function ExtractZUGFeRDFileWithGDPicture(Path As String) As ZugferdResult
|
||||
Dim oResult = ValidateZUGFeRDFileWithGDPicture(Path)
|
||||
oResult = ValidateZUGFeRDDocument(oResult)
|
||||
@@ -151,7 +231,6 @@ Public Class ZUGFeRDInterface
|
||||
''' Validates a ZUGFeRD File and extracts the XML Document from it
|
||||
''' </summary>
|
||||
''' <param name="Stream"></param>
|
||||
''' <exception cref="ZUGFeRDExecption"></exception>
|
||||
Public Function ExtractZUGFeRDFileWithGDPicture(Stream As Stream) As ZugferdResult
|
||||
Dim oResult = ValidateZUGFeRDFileWithGDPicture(Stream)
|
||||
oResult = ValidateZUGFeRDDocument(oResult)
|
||||
@@ -174,7 +253,6 @@ Public Class ZUGFeRDInterface
|
||||
''' Validates a ZUGFeRD File and extracts the XML Document from it
|
||||
''' </summary>
|
||||
''' <param name="pStream"></param>
|
||||
''' <exception cref="ZUGFeRDExecption"></exception>
|
||||
''' <returns>The embedded xml data as an XPath document</returns>
|
||||
Public Function ValidateZUGFeRDFileWithGDPicture(pStream As Stream) As ZugferdResult
|
||||
Dim oEmbedExtractor = New PDFEmbeds(_logConfig)
|
||||
@@ -193,7 +271,7 @@ Public Class ZUGFeRDInterface
|
||||
Throw ex
|
||||
|
||||
Catch ex As Exception
|
||||
_logger.Warn("Error while validating ZUGFeRD file with GDPicture")
|
||||
_logger.Warn("Error while validating eInvoice file with GDPicture")
|
||||
_logger.Error(ex)
|
||||
Throw ex
|
||||
End Try
|
||||
@@ -203,7 +281,6 @@ Public Class ZUGFeRDInterface
|
||||
''' Validates a ZUGFeRD File and extracts the XML Document from it
|
||||
''' </summary>
|
||||
''' <param name="pPath"></param>
|
||||
''' <exception cref="ZUGFeRDExecption"></exception>
|
||||
''' <returns>The embedded xml data as an XPath document</returns>
|
||||
Public Function ValidateZUGFeRDFileWithGDPicture(pPath As String) As ZugferdResult
|
||||
Dim oEmbedExtractor = New PDFEmbeds(_logConfig)
|
||||
@@ -222,19 +299,15 @@ Public Class ZUGFeRDInterface
|
||||
Throw ex
|
||||
|
||||
Catch ex As Exception
|
||||
_logger.Warn("Error while validating ZUGFeRD file with GDPicture")
|
||||
_logger.Warn("Error while validating eInvoice file with GDPicture")
|
||||
_logger.Error(ex)
|
||||
Throw ex
|
||||
End Try
|
||||
End Function
|
||||
|
||||
Private Function HandleEmbeddedFiles(pResults As List(Of PDFEmbeds.EmbeddedFile)) As ZugferdResult
|
||||
If pResults Is Nothing Then
|
||||
Throw New ZUGFeRDExecption(ErrorType.NoZugferd, "Datei ist keine ZUGFeRD Datei, weil die Attachments nicht gelesen werden konnten.")
|
||||
End If
|
||||
|
||||
If pResults.Count = 0 Then
|
||||
Throw New ZUGFeRDExecption(ErrorType.NoZugferd, "Datei ist keine ZUGFeRD Datei, weil sie keine Attachments enthält.")
|
||||
If pResults Is Nothing OrElse pResults.Count = 0 Then
|
||||
Throw New ZUGFeRDExecption(ErrorCodes.InvalidFerdNoXMLAttachmentFound, "Die Datei ist keine gültige ZUGFeRD-Datei, es wurde kein passender XML-Anhang gefunden.")
|
||||
End If
|
||||
|
||||
' Find the first file which filename matches the valid filenames for embedded invoice files
|
||||
@@ -243,7 +316,7 @@ Public Class ZUGFeRDInterface
|
||||
FirstOrDefault()
|
||||
|
||||
If oValidResult Is Nothing Then
|
||||
Throw New ZUGFeRDExecption(ErrorType.NoZugferd, "Datei ist keine ZUGFeRD Datei, weil keine entsprechende XML-Datei gefunden wurde.")
|
||||
Throw New ZUGFeRDExecption(ErrorCodes.InvalidFerdNoXMLAttachmentFound, "Die Datei ist keine ZUGFeRD Datei, weil keine passende XML-Datei gefunden wurde.")
|
||||
End If
|
||||
|
||||
' Search the embedded files for the ones which are allowed as per the configuration.
|
||||
@@ -253,7 +326,7 @@ Public Class ZUGFeRDInterface
|
||||
FirstOrDefault()
|
||||
|
||||
If oAllowedResult Is Nothing Then
|
||||
Throw New ZUGFeRDExecption(ErrorType.UnsupportedFormat, "Datei ist eine ZUGFeRD Datei, aber das Format wird nicht unterstützt.", oAllowedResult.FileName)
|
||||
Throw New ZUGFeRDExecption(ErrorCodes.InvalidFerdNoXMLAttachmentFound, "Datei enthält einen XML-Anhang mit einem ungültigen Dateinamen.", oAllowedResult.FileName)
|
||||
End If
|
||||
|
||||
Try
|
||||
@@ -271,13 +344,14 @@ Public Class ZUGFeRDInterface
|
||||
|
||||
Catch ex As Exception
|
||||
_logger.Error(ex)
|
||||
Throw New ZUGFeRDExecption(ErrorType.NoValidZugferd, "Datei ist eine ungültige ZUGFeRD Datei.")
|
||||
Throw New ZUGFeRDExecption(ErrorCodes.InvalidFerdException, "XML-Datei konnte nicht gelesen werden.")
|
||||
End Try
|
||||
End Function
|
||||
|
||||
Private Class AllowedType
|
||||
Public SchemaType As Type
|
||||
Public Specification As String
|
||||
Public XMLSchema As String
|
||||
End Class
|
||||
|
||||
Public Function ValidateZUGFeRDDocument(pResult As ZugferdResult) As ZugferdResult
|
||||
@@ -290,29 +364,71 @@ Public Class ZUGFeRDInterface
|
||||
|
||||
Dim oObject As Object = Nothing
|
||||
Dim oSpecification As String = Nothing
|
||||
Dim oUsedXMLSchema As String = Nothing
|
||||
|
||||
Dim oAllowedTypes As New List(Of AllowedType)
|
||||
|
||||
If _Options.AllowZugferd_1_0_Schema Then
|
||||
oAllowedTypes.Add(New AllowedType With {
|
||||
.SchemaType = GetType(Version1_0.CrossIndustryDocumentType),
|
||||
.Specification = ZUGFERD_SPEC_10
|
||||
.Specification = ZUGFERD_SPEC_10,
|
||||
.XMLSchema = XMLSCHEMA_ZUGFERD_10
|
||||
})
|
||||
End If
|
||||
|
||||
'' Reihenfolge 2.0 muss unverändert bleiben. Älteste Version immer zuerst!
|
||||
If _Options.AllowZugferd_2_x_Schema Then
|
||||
oAllowedTypes.AddRange(New List(Of AllowedType) From {
|
||||
New AllowedType With {
|
||||
.SchemaType = GetType(Version2_0.CrossIndustryInvoiceType),
|
||||
.Specification = ZUGFERD_SPEC_2x
|
||||
.Specification = ZUGFERD_SPEC_2x,
|
||||
.XMLSchema = XMLSCHEMA_ZUGFERD_20
|
||||
},
|
||||
New AllowedType With {
|
||||
.SchemaType = GetType(Version2_1_1.CrossIndustryInvoiceType),
|
||||
.Specification = ZUGFERD_SPEC_2x
|
||||
.Specification = ZUGFERD_SPEC_2x,
|
||||
.XMLSchema = XMLSCHEMA_ZUGFERD_211
|
||||
},
|
||||
New AllowedType With {
|
||||
.SchemaType = GetType(Version2_2_FacturX.CrossIndustryInvoiceType),
|
||||
.Specification = ZUGFERD_SPEC_2x
|
||||
.Specification = ZUGFERD_SPEC_2x,
|
||||
.XMLSchema = XMLSCHEMA_ZUGFERD_22
|
||||
}
|
||||
})
|
||||
End If
|
||||
|
||||
'' Reihenfolge ab 2.3 geändert. Neuste Version immer zuerst bzw. oben
|
||||
If _Options.AllowZugferd_2_3_x_Schema Then
|
||||
oAllowedTypes.AddRange(New List(Of AllowedType) From {
|
||||
New AllowedType With {
|
||||
.SchemaType = GetType(Version2_4_FacturX.CrossIndustryInvoiceType),
|
||||
.Specification = ZUGFERD_SPEC_2_3x,
|
||||
.XMLSchema = XMLSCHEMA_ZUGFERD_24
|
||||
},
|
||||
New AllowedType With {
|
||||
.SchemaType = GetType(Version2_3_3_FacturX.CrossIndustryInvoiceType),
|
||||
.Specification = ZUGFERD_SPEC_2_3x,
|
||||
.XMLSchema = XMLSCHEMA_ZUGFERD_233
|
||||
},
|
||||
New AllowedType With {
|
||||
.SchemaType = GetType(Version2_3_FacturX.CrossIndustryInvoiceType),
|
||||
.Specification = ZUGFERD_SPEC_2_3x,
|
||||
.XMLSchema = XMLSCHEMA_ZUGFERD_23
|
||||
}
|
||||
})
|
||||
End If
|
||||
|
||||
If _Options.AllowPeppol_3_x_Schema Then
|
||||
oAllowedTypes.AddRange(New List(Of AllowedType) From {
|
||||
New AllowedType With {
|
||||
.SchemaType = GetType(UBL_21_Invoice.InvoiceType),
|
||||
.Specification = UBL_SPEC_21,
|
||||
.XMLSchema = XMLSCHEMA_UBL_21_INVOICE
|
||||
},
|
||||
New AllowedType With {
|
||||
.SchemaType = GetType(UBL_21_CreditNote.CreditNoteType),
|
||||
.Specification = UBL_SPEC_21,
|
||||
.XMLSchema = XMLSCHEMA_UBL_21_CREDITNOTE
|
||||
}
|
||||
})
|
||||
End If
|
||||
@@ -326,6 +442,7 @@ Public Class ZUGFeRDInterface
|
||||
oReader = pResult.XElementObject.CreateReader()
|
||||
oObject = oSerializer.Deserialize(oReader)
|
||||
oSpecification = oType.Specification
|
||||
oUsedXMLSchema = oType.XMLSchema
|
||||
|
||||
_logger.Debug("Serializing with type [{0}] succeeded", oTypeName)
|
||||
Exit For
|
||||
@@ -339,11 +456,11 @@ Public Class ZUGFeRDInterface
|
||||
Next
|
||||
|
||||
If oObject Is Nothing Then
|
||||
'Throw New ApplicationException("No Types matched the given document. Document could not be serialized.")
|
||||
Throw New ZUGFeRDExecption(ErrorType.UnsupportedFormat, "Unsupported Format")
|
||||
Throw New ZUGFeRDExecption(ErrorCodes.UnsupportedFerdException, "Unsupported Format")
|
||||
End If
|
||||
|
||||
pResult.Specification = oSpecification
|
||||
pResult.UsedXMLSchema = oUsedXMLSchema
|
||||
pResult.SchemaObject = oObject
|
||||
|
||||
Return pResult
|
||||
@@ -354,10 +471,8 @@ Public Class ZUGFeRDInterface
|
||||
|
||||
Catch ex As Exception
|
||||
_logger.Error(ex)
|
||||
Dim oMessage = "Datei ist eine ungültige ZUGFeRD Datei oder das Format wird nicht unterstüzt, oder das Format ist deaktiviert."
|
||||
Throw New ZUGFeRDExecption(ErrorType.NoValidZugferd, oMessage)
|
||||
Dim oMessage = "Datei ist eine ungültige Datei oder das Format wird nicht unterstüzt, oder das Format ist deaktiviert."
|
||||
Throw New ZUGFeRDExecption(ErrorCodes.UnsupportedFerdException, oMessage)
|
||||
End Try
|
||||
End Function
|
||||
|
||||
|
||||
End Class
|
||||
|
||||
14
Interfaces/ZUGFeRDInterface/Enums/ErrorCodes.vb
Normal file
14
Interfaces/ZUGFeRDInterface/Enums/ErrorCodes.vb
Normal file
@@ -0,0 +1,14 @@
|
||||
Public Enum ErrorCodes
|
||||
NotInUse = 0
|
||||
ValidationException = 20001
|
||||
MD5HashException = 20002
|
||||
UnsupportedFerdException = 20003
|
||||
InvalidFerdException = 20004
|
||||
TooMuchFerdsException = 20005
|
||||
InvalidFerdNoXMLAttachmentFound = 20006
|
||||
MissingValueException = 20007
|
||||
FileSizeLimitReachedException = 20008
|
||||
OutOfMemoryException = 20009
|
||||
UnhandledException = 20010
|
||||
FileMoveException = 200011
|
||||
End Enum
|
||||
8
Interfaces/ZUGFeRDInterface/Enums/Item_Types.vb
Normal file
8
Interfaces/ZUGFeRDInterface/Enums/Item_Types.vb
Normal file
@@ -0,0 +1,8 @@
|
||||
Public Enum Item_Types
|
||||
StringType '0
|
||||
DateType '1
|
||||
MoneyType '2
|
||||
FileType '3
|
||||
ListType '4 - vgl. Währung
|
||||
|
||||
End Enum
|
||||
@@ -4,7 +4,11 @@ Public Class Exceptions
|
||||
Public Class ZUGFeRDExecption
|
||||
Inherits ApplicationException
|
||||
|
||||
Public ReadOnly Property ErrorType() As ZUGFeRDInterface.ErrorType
|
||||
Public ReadOnly Property ErrorCode() As ErrorCodes
|
||||
|
||||
Public ReadOnly Property Param1 As String = String.Empty
|
||||
|
||||
Public ReadOnly Property Param2 As String = String.Empty
|
||||
|
||||
''' <summary>
|
||||
''' Contains the name of the extracted xml file if already extracted.
|
||||
@@ -12,18 +16,37 @@ Public Class Exceptions
|
||||
''' <returns>A filename like zugferd-invoice.xml</returns>
|
||||
Public ReadOnly Property XmlFile As String = String.Empty
|
||||
|
||||
Public Sub New(ErrorType As ZUGFeRDInterface.ErrorType, Message As String)
|
||||
Public Sub New(pErrorCode As ErrorCodes, Message As String)
|
||||
MyBase.New(Message)
|
||||
|
||||
_ErrorType = ErrorType
|
||||
_ErrorCode = pErrorCode
|
||||
End Sub
|
||||
|
||||
Public Sub New(ErrorType As ZUGFeRDInterface.ErrorType, Message As String, pXmlFileName As String)
|
||||
Public Sub New(pErrorCode As ErrorCodes, Message As String, pXmlFileName As String)
|
||||
MyBase.New(Message)
|
||||
|
||||
_ErrorType = ErrorType
|
||||
_ErrorCode = pErrorCode
|
||||
_XmlFile = pXmlFileName
|
||||
End Sub
|
||||
|
||||
Public Sub New(pErrorCode As ErrorCodes, Param1 As String, Param2 As String, Message As String)
|
||||
MyBase.New(Message)
|
||||
|
||||
_ErrorCode = pErrorCode
|
||||
_Param1 = Param1
|
||||
_Param2 = Param2
|
||||
|
||||
End Sub
|
||||
|
||||
Public Sub New(pErrorCode As ErrorCodes, Param1 As String, Param2 As String, Message As String, pXmlFileName As String)
|
||||
MyBase.New(Message)
|
||||
|
||||
_ErrorCode = pErrorCode
|
||||
_Param1 = Param1
|
||||
_Param2 = Param2
|
||||
_XmlFile = pXmlFileName
|
||||
|
||||
End Sub
|
||||
End Class
|
||||
|
||||
Public Class ValidationException
|
||||
@@ -31,8 +54,13 @@ Public Class Exceptions
|
||||
|
||||
Public ValidationErrors As List(Of ZugferdValidationError)
|
||||
|
||||
Public ReadOnly Property ErrorCode() As ErrorCodes
|
||||
|
||||
Public Sub New()
|
||||
MyBase.New("ZUGFeRD document found but validation failed!")
|
||||
|
||||
_ErrorCode = ErrorCodes.ValidationException
|
||||
End Sub
|
||||
|
||||
End Class
|
||||
End Class
|
||||
|
||||
@@ -3,7 +3,7 @@ Imports System.Text.RegularExpressions
|
||||
Imports DigitalData.Modules.Logging
|
||||
|
||||
Public Class FileGroups
|
||||
Private _logger As Logger
|
||||
Private ReadOnly _logger As Logger
|
||||
|
||||
Public Sub New(LogConfig As LogConfig)
|
||||
_logger = LogConfig.GetLogger()
|
||||
@@ -25,7 +25,7 @@ Public Class FileGroups
|
||||
Dim oMessageId = GetMessageIdFromFileName(oFile.Name)
|
||||
|
||||
If oMessageId Is Nothing Then
|
||||
_logger.Warn("File {0} did not have the required filename-format!", oMessageId)
|
||||
_logger.Warn("File {0} did not have the required filename-format!", oFile.Name)
|
||||
Continue For
|
||||
End If
|
||||
|
||||
@@ -69,7 +69,9 @@ Public Class FileGroups
|
||||
Private Function GetMessageIdFromFileName(Filename As String) As String
|
||||
' Regex to find MessageId
|
||||
' See also: https://stackoverflow.com/questions/3968500/regex-to-validate-a-message-id-as-per-rfc2822
|
||||
Dim oRegex = "(((([a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*)|(""(([\x01-\x08\x0B\x0C\x0E-\x1F\x7F]|[\x21\x23-\x5B\x5D-\x7E])|(\\[\x01-\x09\x0B\x0C\x0E-\x7F]))*""))@(([a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*)|(\[(([\x01-\x08\x0B\x0C\x0E-\x1F\x7F]|[\x21-\x5A\x5E-\x7E])|(\\[\x01-\x09\x0B\x0C\x0E-\x7F]))*\]))))~.+"
|
||||
'Dim oRegex = "(((([a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*)|(""(([\x01-\x08\x0B\x0C\x0E-\x1F\x7F]|[\x21\x23-\x5B\x5D-\x7E])|(\\[\x01-\x09\x0B\x0C\x0E-\x7F]))*""))@(([a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*)|(\[(([\x01-\x08\x0B\x0C\x0E-\x1F\x7F]|[\x21-\x5A\x5E-\x7E])|(\\[\x01-\x09\x0B\x0C\x0E-\x7F]))*\]))))~.+"
|
||||
|
||||
Dim oRegex = "([A-Z0-9]+)~ATTM\d+\..*"
|
||||
Dim oMatch = Regex.Match(Filename, oRegex, RegexOptions.IgnoreCase)
|
||||
|
||||
If oMatch.Success Then
|
||||
|
||||
68
Interfaces/ZUGFeRDInterface/PDFConverter.vb
Normal file
68
Interfaces/ZUGFeRDInterface/PDFConverter.vb
Normal file
@@ -0,0 +1,68 @@
|
||||
Imports System.IO
|
||||
Imports DigitalData.Modules.Interfaces.Exceptions
|
||||
Imports DigitalData.Modules.Logging
|
||||
Imports GdPicture14
|
||||
|
||||
Public Class PDFConverter
|
||||
Private ReadOnly _LogConfig As LogConfig
|
||||
Private ReadOnly _Logger As Logger
|
||||
|
||||
Public Sub New(pLogConfig As LogConfig)
|
||||
_LogConfig = pLogConfig
|
||||
_Logger = pLogConfig.GetLogger()
|
||||
End Sub
|
||||
|
||||
Public Function ConvertPDFADocumentToPDFDocument(pFilePath As String, pNewFilePath As String) As Boolean
|
||||
Try
|
||||
Using oGdPicturePDF As New GdPicturePDF()
|
||||
Using oGdPicturePDFDestination As New GdPicturePDF()
|
||||
|
||||
' Load the source file into memory
|
||||
If oGdPicturePDF.LoadFromFile(pFilePath, True) <> GdPictureStatus.OK Then
|
||||
Throw New ApplicationException("File could not be loaded!")
|
||||
End If
|
||||
|
||||
' Create a new pdf file
|
||||
If oGdPicturePDFDestination.NewPDF() <> GdPictureStatus.OK Then
|
||||
Throw New ApplicationException("New Pdf could not be created!")
|
||||
End If
|
||||
|
||||
' Copy all pages from the source into the new pdf
|
||||
If oGdPicturePDFDestination.ClonePages(oGdPicturePDF, "*") <> GdPictureStatus.OK Then
|
||||
Throw New ApplicationException("Document could not be copied into new pdf!")
|
||||
End If
|
||||
|
||||
' Close the source document
|
||||
If oGdPicturePDF.CloseDocument() <> GdPictureStatus.OK Then
|
||||
Throw New ApplicationException("Source document could not be closed!")
|
||||
End If
|
||||
|
||||
' Set the file path
|
||||
Dim oFinalFilePath = pFilePath
|
||||
If Not String.IsNullOrWhiteSpace(pNewFilePath) Then
|
||||
oFinalFilePath = pNewFilePath
|
||||
End If
|
||||
|
||||
' Save the file to disk
|
||||
If oGdPicturePDFDestination.SaveToFile(oFinalFilePath) <> GdPictureStatus.OK Then
|
||||
Throw New ApplicationException("New document could not be saved to disk!")
|
||||
End If
|
||||
|
||||
If oGdPicturePDFDestination.CloseDocument() <> GdPictureStatus.OK Then
|
||||
Throw New ApplicationException("Destination document could not be closed!")
|
||||
End If
|
||||
|
||||
End Using
|
||||
End Using
|
||||
|
||||
Return True
|
||||
Catch ex As Exception
|
||||
_Logger.Error(ex)
|
||||
Return False
|
||||
End Try
|
||||
|
||||
|
||||
End Function
|
||||
|
||||
|
||||
End Class
|
||||
@@ -1,5 +1,4 @@
|
||||
Imports System.Collections.Generic
|
||||
Imports System.IO
|
||||
Imports System.IO
|
||||
Imports DigitalData.Modules.Logging
|
||||
Imports GdPicture14
|
||||
|
||||
@@ -70,7 +69,8 @@ Public Class PDFEmbeds
|
||||
Public Function Extract(Stream As Stream, AllowedExtensions As List(Of String)) As List(Of EmbeddedFile)
|
||||
Dim oResults As New List(Of EmbeddedFile)
|
||||
Dim oExtensions = AllowedExtensions.Select(Function(ext) ext.ToUpper).ToList()
|
||||
|
||||
Dim oLicenseManager As New LicenseManager
|
||||
oLicenseManager.RegisterKEY("LICENSE_KEY")
|
||||
Logger.Debug("Extracting embedded files from stream")
|
||||
|
||||
Try
|
||||
@@ -91,6 +91,65 @@ Public Class PDFEmbeds
|
||||
End Try
|
||||
End Function
|
||||
|
||||
Public Function RemoveEmbeddedFiles(pFilePath As String) As Boolean
|
||||
Dim oFile As New List(Of EmbeddedFile)
|
||||
Dim oFileInfo As FileInfo
|
||||
|
||||
Logger.Debug("Removing embedded files from [{0}]", pFilePath)
|
||||
|
||||
Try
|
||||
oFileInfo = New FileInfo(pFilePath)
|
||||
|
||||
Logger.Debug("Filename: {0}", oFileInfo.Name)
|
||||
Logger.Debug("Filesize: {0} bytes", oFileInfo.Length)
|
||||
Logger.Debug("Exists: {0}", oFileInfo.Exists)
|
||||
Catch ex As Exception
|
||||
Logger.Warn("File information for [{0}] could not be read!", pFilePath)
|
||||
Logger.Error(ex)
|
||||
End Try
|
||||
|
||||
Try
|
||||
Using oGDPicturePDF As New GdPicturePDF()
|
||||
If oGDPicturePDF.LoadFromFile(pFilePath, False) <> GdPictureStatus.OK Then
|
||||
Dim oMessage = String.Format("The file [{0}] can't be loaded. Status: [{1}]", pFilePath, oGDPicturePDF.GetStat().ToString())
|
||||
Throw New ApplicationException(oMessage)
|
||||
End If
|
||||
|
||||
If DoRemove(oGDPicturePDF) = False Then
|
||||
Dim oMessage = String.Format("Attachments for file [{0}] can't be removed. Status: [{1}]", pFilePath, oGDPicturePDF.GetStat().ToString())
|
||||
Throw New ApplicationException(oMessage)
|
||||
End If
|
||||
End Using
|
||||
|
||||
Return True
|
||||
Catch ex As Exception
|
||||
Logger.Warn("Unexpected Error while Extracting attachments from File [{0}]", pFilePath)
|
||||
Logger.Error(ex)
|
||||
Return False
|
||||
End Try
|
||||
End Function
|
||||
|
||||
Private Function DoRemove(GDPicturePDF As GdPicturePDF) As Boolean
|
||||
Dim oStatus As GdPictureStatus
|
||||
|
||||
Dim oEmbeddedFileCount As Integer = GDPicturePDF.GetEmbeddedFileCount()
|
||||
|
||||
If oStatus <> GdPictureStatus.OK Then
|
||||
Logger.Warn("Embedded files could not be removed. Status: [{0}]", oStatus.ToString)
|
||||
Return False
|
||||
End If
|
||||
|
||||
If oEmbeddedFileCount = 0 Then
|
||||
Return True
|
||||
End If
|
||||
|
||||
While GDPicturePDF.GetEmbeddedFileCount() > 0
|
||||
GDPicturePDF.DeleteEmbeddedFile(0)
|
||||
End While
|
||||
|
||||
Return True
|
||||
End Function
|
||||
|
||||
Private Function DoExtract(GDPicturePDF As GdPicturePDF, pExtensions As List(Of String)) As List(Of EmbeddedFile)
|
||||
Dim oResults As New List(Of EmbeddedFile)
|
||||
Dim oEmbeddedFileCount As Integer = GDPicturePDF.GetEmbeddedFileCount()
|
||||
@@ -105,7 +164,17 @@ Public Class PDFEmbeds
|
||||
If GDPicturePDF.GetStat() = GdPictureStatus.OK Then
|
||||
Logger.Debug("Extracting embedded file [{0}]", oFileName)
|
||||
|
||||
Dim oExtension = New FileInfo(oFileName).Extension.ToUpper.Substring(1)
|
||||
Dim oFileInfo = New FileInfo(oFileName)
|
||||
Dim oExtension As String = oFileInfo.Extension
|
||||
|
||||
If String.IsNullOrWhiteSpace(oExtension) Then
|
||||
Logger.Error("The embedded file [{0}] does not have any extension. Skipping.", oFileName)
|
||||
Continue For
|
||||
Else
|
||||
' Jetzt wissen wir, das es eine Extension gibt!
|
||||
oExtension = oFileInfo.Extension.ToUpper.Substring(1)
|
||||
End If
|
||||
|
||||
If pExtensions.Contains(oExtension) Then
|
||||
Dim oFileSize As Integer = GDPicturePDF.GetEmbeddedFileSize(oIndex)
|
||||
|
||||
@@ -114,7 +183,7 @@ Public Class PDFEmbeds
|
||||
|
||||
Dim oFileData As Byte() = New Byte(oFileSize) {}
|
||||
Dim oStatus As GdPictureStatus = GDPicturePDF.ExtractEmbeddedFile(oIndex, oFileData)
|
||||
|
||||
'MsgBox($"FileSize of filename: {oFileName} is bytes: {oFileData.Length}/Filesize: {oFileSize}")
|
||||
If oStatus = GdPictureStatus.OK Then
|
||||
Logger.Debug("Embedded file [{0}] extracted sucessfully!", oFileName)
|
||||
|
||||
|
||||
42562
Interfaces/ZUGFeRDInterface/Peppol_UBL2.1/CreditNoteType.vb
Normal file
42562
Interfaces/ZUGFeRDInterface/Peppol_UBL2.1/CreditNoteType.vb
Normal file
File diff suppressed because it is too large
Load Diff
42601
Interfaces/ZUGFeRDInterface/Peppol_UBL2.1/InvoiceType.vb
Normal file
42601
Interfaces/ZUGFeRDInterface/Peppol_UBL2.1/InvoiceType.vb
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,5 @@
|
||||
Imports System.Reflection
|
||||
Imports System.Globalization
|
||||
Imports System.Reflection
|
||||
Imports System.Text.RegularExpressions
|
||||
Imports DigitalData.Modules.Logging
|
||||
|
||||
@@ -15,7 +16,7 @@ Public Class PropertyValues
|
||||
End Sub
|
||||
|
||||
Public Class CheckPropertyValuesResult
|
||||
Public MissingProperties As New List(Of String)
|
||||
Public MissingProperties As New List(Of MissingProperty)
|
||||
Public ValidProperties As New List(Of ValidProperty)
|
||||
End Class
|
||||
|
||||
@@ -27,11 +28,25 @@ Public Class PropertyValues
|
||||
Public IsRequired As Boolean
|
||||
Public GroupCounter As Integer = -1
|
||||
|
||||
Public EN16931_ID As String
|
||||
Public Description As String
|
||||
Public Value As String
|
||||
Public XMLPath As String
|
||||
|
||||
Public ItemType As Integer = 0
|
||||
End Class
|
||||
|
||||
Public Function CheckPropertyValues(Document As Object, PropertyMap As Dictionary(Of String, XmlItemProperty), MessageId As String) As CheckPropertyValuesResult
|
||||
Public Class MissingProperty
|
||||
Public EN16931_ID As String
|
||||
Public Description As String
|
||||
Public XMLPath As String
|
||||
|
||||
Public Overrides Function ToString() As String
|
||||
Return XMLPath
|
||||
End Function
|
||||
End Class
|
||||
|
||||
Public Function CheckPropertyValues(pDocument As Object, PropertyMap As Dictionary(Of String, XmlItemProperty), MessageId As String) As CheckPropertyValuesResult
|
||||
Dim oGlobalGroupCounter = 0
|
||||
Dim oMissingProperties As New List(Of String)
|
||||
Dim oResult As New CheckPropertyValuesResult()
|
||||
@@ -42,7 +57,7 @@ Public Class PropertyValues
|
||||
ToDictionary(Function(Item) Item.Key,
|
||||
Function(Item) Item.Value)
|
||||
|
||||
_logger.Debug("Found {0} default properties.", oDefaultProperties.Count)
|
||||
_logger.Debug("Found {0} ungrouped properties.", oDefaultProperties.Count)
|
||||
|
||||
' PropertyMap items with `IsGrouped = True` are grouped by group scope
|
||||
Dim oGroupedProperties = PropertyMap.
|
||||
@@ -56,7 +71,7 @@ Public Class PropertyValues
|
||||
Dim oGroupScope As String = oGroup.Key
|
||||
|
||||
Dim oPropertyList As New Dictionary(Of XmlItemProperty, List(Of Object))
|
||||
Dim oRowCount = 0
|
||||
Dim oRowCount = 0 ' TODO - Es wird anhand der Anzahl XML-Knoten ermittelt wieviele Rows gelesen werden???????
|
||||
|
||||
_logger.Debug($"Fetching Property values for group [{oGroupScope}].")
|
||||
|
||||
@@ -65,23 +80,23 @@ Public Class PropertyValues
|
||||
Dim oPropertyValues As List(Of Object)
|
||||
_logger.Debug($"Fetching value for itemSpecification [{oProperty.Value.TableColumn}].")
|
||||
Try
|
||||
oPropertyValues = GetPropValue(Document, oProperty.Key)
|
||||
oPropertyValues = GetPropValue(pDocument, oProperty.Key)
|
||||
Catch ex As Exception
|
||||
_logger.Warn($"{MessageId} - Unknown error occurred while fetching property/TColumn [{0}] in group [{1}]:", oProperty.Value.TableColumn, oGroupScope)
|
||||
_logger.Error(ex)
|
||||
oPropertyValues = New List(Of Object)
|
||||
End Try
|
||||
|
||||
' check the first batch of values to determine the row count
|
||||
If oRowCount = 0 Then '08.04.2025 MS Added as Workaround for Positions Or oGroupScope = "POSITIONS" !
|
||||
oRowCount = oPropertyValues.Count
|
||||
End If
|
||||
|
||||
' Flatten result value
|
||||
oPropertyValues = GetFinalPropValue(oPropertyValues)
|
||||
|
||||
' Add to list
|
||||
oPropertyList.Add(oProperty.Value, oPropertyValues)
|
||||
|
||||
' check the first batch of values to determine the row count
|
||||
If oRowCount = 0 Then
|
||||
oRowCount = oPropertyValues.Count
|
||||
End If
|
||||
Next
|
||||
|
||||
' Structure of oPropertyList
|
||||
@@ -98,25 +113,57 @@ Public Class PropertyValues
|
||||
Dim oTableColumn As String = oColumn.Key.TableColumn
|
||||
Dim oIsRequired As Boolean = oColumn.Key.IsRequired
|
||||
Dim oPropertyDescription As String = oColumn.Key.Description
|
||||
Dim oPropertyPath As String = oColumn.Key.XMLPath
|
||||
Dim oItemType As Integer = oColumn.Key.ItemType
|
||||
Dim oEN16931Value As String = oColumn.Key.EN16931_ID
|
||||
|
||||
Dim oRowCounter = oRowIndex + oGlobalGroupCounter + 1
|
||||
|
||||
' Returns nothing if oColumn.Value contains an empty list
|
||||
Dim oPropertyValue = oColumn.Value.ElementAtOrDefault(oRowIndex)
|
||||
|
||||
_logger.Debug("Processing itemSpecification *TableColumn* [{0}].", oTableColumn)
|
||||
|
||||
_logger.Debug("Processing itemColumn *TableColumn* [{0}].", oTableColumn)
|
||||
If oTableColumn = "INVOICE_SELLER_EMAIL" Then
|
||||
Console.WriteLine("INVOICE_SELLER_EMAIL")
|
||||
ElseIf oTableColumn = "INVOICE_POSITION_ARTICLE" Then
|
||||
Console.WriteLine("INVOICE_POSITION_ARTICLE")
|
||||
End If
|
||||
If IsNothing(oPropertyValue) OrElse String.IsNullOrEmpty(oPropertyValue) Then
|
||||
If oColumn.Key.IsRequired Then
|
||||
_logger.Warn($"{MessageId} # oPropertyValue for specification [{oTableColumn}] is empty or not found but is required. Continuing with Empty String.")
|
||||
oResult.MissingProperties.Add(oPropertyDescription)
|
||||
_logger.Warn($"{MessageId} - oPropertyValue for column [{oTableColumn}] is empty or not found but is required. Continuing with Empty String.")
|
||||
Dim oMissingProperty = New MissingProperty() With {
|
||||
.EN16931_ID = oEN16931Value,
|
||||
.Description = oPropertyDescription,
|
||||
.XMLPath = oPropertyPath
|
||||
}
|
||||
oResult.MissingProperties.Add(oMissingProperty)
|
||||
Else
|
||||
_logger.Debug($"{MessageId} # oPropertyValue for specification [{oTableColumn}] is empty or not found. Continuing with Empty String.")
|
||||
_logger.Debug($"{MessageId} - oPropertyValue for column [{oTableColumn}] is empty or not found. Continuing with Empty String.")
|
||||
End If
|
||||
|
||||
oPropertyValue = String.Empty
|
||||
End If
|
||||
|
||||
_logger.Debug("ItemSpecification [{0}] has value '{1}'", oTableColumn, oPropertyValue)
|
||||
If (oPropertyValue IsNot Nothing) Then
|
||||
Dim logValue As String = oPropertyValue.ToString()
|
||||
If logValue.Length > 50 Then
|
||||
_logger.Debug("Item [{0}] has value '{1}...'", oTableColumn, logValue.Substring(1, 50))
|
||||
Else
|
||||
_logger.Debug("Item [{0}] has value '{1}'", oTableColumn, oPropertyValue)
|
||||
End If
|
||||
|
||||
End If
|
||||
|
||||
If oTableColumn = "INVOICE_CURRENCY" Or oItemType = 4 Then
|
||||
Dim oValuestring = oPropertyValue.ToString()
|
||||
|
||||
' Bei Listenelementen entfernen wir den String Item, um den Wert zu erhalten
|
||||
If oValuestring.Contains("Item") Then
|
||||
oValuestring = oValuestring.Replace("Item", "")
|
||||
End If
|
||||
|
||||
oPropertyValue = oValuestring
|
||||
End If
|
||||
|
||||
oResult.ValidProperties.Add(New ValidProperty() With {
|
||||
.MessageId = MessageId,
|
||||
@@ -125,7 +172,10 @@ Public Class PropertyValues
|
||||
.GroupCounter = oRowCounter,
|
||||
.TableName = oTableName,
|
||||
.TableColumn = oTableColumn,
|
||||
.IsRequired = oIsRequired
|
||||
.IsRequired = oIsRequired,
|
||||
.XMLPath = oPropertyPath,
|
||||
.ItemType = oItemType,
|
||||
.EN16931_ID = oEN16931Value
|
||||
})
|
||||
Next
|
||||
Next
|
||||
@@ -138,14 +188,19 @@ Public Class PropertyValues
|
||||
Dim oPropertyValueList As List(Of Object)
|
||||
Dim oTableColumn As String = oItem.Value.TableColumn
|
||||
Dim oPropertyDescription As String = oItem.Value.Description
|
||||
Dim oPropertyPath As String = oItem.Value.XMLPath
|
||||
Dim oPropertyValue As Object = Nothing
|
||||
Dim oTableName = oItem.Value.TableName
|
||||
Dim oIsRequired = oItem.Value.IsRequired
|
||||
Dim oDescription = oItem.Value.Description
|
||||
Dim oItemType = oItem.Value.ItemType
|
||||
Dim oEN16931_ID = oItem.Value.EN16931_ID
|
||||
|
||||
Try
|
||||
oPropertyValueList = GetPropValue(Document, oItem.Key)
|
||||
oPropertyValueList = GetPropValue(pDocument, oItem.Key)
|
||||
Catch ex As Exception
|
||||
_logger.Warn("{2} # Unknown error occurred while fetching specification [{0}] in group [{1}]:", oPropertyDescription, oItem.Value.GroupScope, MessageId)
|
||||
_logger.Warn("{2} - Unknown error occurred while fetching specification [{0}] in group [{1}]:", oTableColumn, oItem.Value.GroupScope, MessageId)
|
||||
_logger.Warn("ERROR-MESSAGE [{0}]", ex.Message)
|
||||
_logger.Error(ex)
|
||||
oPropertyValueList = New List(Of Object)
|
||||
End Try
|
||||
@@ -163,36 +218,56 @@ Public Class PropertyValues
|
||||
|
||||
' This should hopefully show config errors
|
||||
If TypeOf oPropertyValue Is List(Of Object) Then
|
||||
_logger.Warn("Item with specification [{0}] may be configured incorrectly", oPropertyDescription)
|
||||
_logger.Warn("Item with specification [{0}] may be configured incorrectly", oTableColumn)
|
||||
oPropertyValue = Nothing
|
||||
End If
|
||||
End Select
|
||||
End If
|
||||
Catch ex As Exception
|
||||
_logger.Warn("Unknown error occurred while processing specification [{0}]:", oPropertyDescription)
|
||||
_logger.Warn("Unknown error occurred while processing specification [{0}]:", oTableColumn)
|
||||
_logger.Error(ex)
|
||||
oPropertyValue = Nothing
|
||||
End Try
|
||||
|
||||
If IsNothing(oPropertyValue) OrElse String.IsNullOrEmpty(oPropertyValue) Then
|
||||
If oItem.Value.IsRequired Then
|
||||
_logger.Warn("{0} # Specification [{1}] is empty, but marked as required! Skipping.", MessageId, oPropertyDescription)
|
||||
oResult.MissingProperties.Add(oPropertyDescription)
|
||||
_logger.Warn("Specification [{0}] is empty, but marked as required! Skipping.", oTableColumn)
|
||||
Dim oMissingProperty = New MissingProperty With
|
||||
{
|
||||
.Description = oPropertyDescription,
|
||||
.XMLPath = oPropertyPath
|
||||
}
|
||||
oResult.MissingProperties.Add(oMissingProperty)
|
||||
Continue For
|
||||
Else
|
||||
_logger.Debug("{0} # oPropertyValue for specification [{1}] is empty or not found. Skipping.", MessageId, oPropertyDescription)
|
||||
_logger.Debug("oPropertyValue for specification [{0}] is empty or not found. Skipping.", oTableColumn)
|
||||
|
||||
Continue For
|
||||
End If
|
||||
End If
|
||||
|
||||
' Statt dem Zahlenwert des Enums, wollen wir die Währungsbezeichnung
|
||||
If oTableColumn = "INVOICE_CURRENCY" Or oItemType = 4 Then
|
||||
Dim oValuestring = oPropertyValue.ToString()
|
||||
|
||||
' Bei Listenelementen entfernen wir den String Item, um den Wert zu erhalten
|
||||
If oValuestring.Contains("Item") Then
|
||||
oValuestring = oValuestring.Replace("Item", "")
|
||||
End If
|
||||
|
||||
oPropertyValue = oValuestring
|
||||
End If
|
||||
|
||||
oResult.ValidProperties.Add(New ValidProperty() With {
|
||||
.MessageId = MessageId,
|
||||
.Description = oDescription,
|
||||
.Value = oPropertyValue,
|
||||
.TableName = oTableName,
|
||||
.TableColumn = oTableColumn,
|
||||
.IsRequired = oIsRequired
|
||||
.IsRequired = oIsRequired,
|
||||
.XMLPath = oPropertyPath,
|
||||
.ItemType = oItemType,
|
||||
.EN16931_ID = oEN16931_ID
|
||||
})
|
||||
Next
|
||||
|
||||
@@ -239,17 +314,11 @@ Public Class PropertyValues
|
||||
|
||||
Obj = oInfo.GetValue(Obj, Nothing)
|
||||
|
||||
' TODO: This code should check for array properties by itself
|
||||
' and should not rely on the user to
|
||||
'If oInfo.PropertyType.IsArray Then
|
||||
' Obj = Obj(0)
|
||||
'End If
|
||||
|
||||
If oHasIndex Then
|
||||
Obj = Obj(0)
|
||||
End If
|
||||
|
||||
If IsArray(Obj) And Not oHasIndex Then
|
||||
If IsArray(Obj) And Not oHasIndex And oPart <> "Value" Then
|
||||
Dim oCurrentPart As String = oPart
|
||||
Dim oSplitString As String() = New String() {oCurrentPart & "."}
|
||||
Dim oPathFragments = PropertyName.Split(oSplitString, StringSplitOptions.None)
|
||||
@@ -269,9 +338,56 @@ Public Class PropertyValues
|
||||
Next
|
||||
|
||||
Return oResults
|
||||
Else
|
||||
If oPart = "Value" AndAlso Obj IsNot Nothing Then
|
||||
' Der Name des gefundenen Datentyps
|
||||
Dim oObjType = oInfo.PropertyType.FullName
|
||||
|
||||
If oObjType.Equals("System.DateTime", StringComparison.OrdinalIgnoreCase) Then
|
||||
|
||||
Dim d As Date
|
||||
Dim s As String
|
||||
Dim oResult As String
|
||||
|
||||
s = Convert.ToString(Obj)
|
||||
|
||||
If IsDate(s) = True Then
|
||||
' Hier wird das DEFAULT-Format auf yyyyMMdd gesetzt
|
||||
Dim dtfi As DateTimeFormatInfo = CultureInfo.CreateSpecificCulture(CultureInfo.InvariantCulture.Name).DateTimeFormat
|
||||
dtfi.DateSeparator = ""
|
||||
dtfi.ShortDatePattern = "yyyyMMdd"
|
||||
|
||||
d = CDate(s)
|
||||
oResult = d.ToString("d", dtfi)
|
||||
|
||||
'Return New List(Of Object) From {oResult}
|
||||
Dim oRetValue As List(Of Object) = New List(Of Object) From {
|
||||
oResult
|
||||
}
|
||||
|
||||
Return oRetValue
|
||||
|
||||
End If
|
||||
ElseIf oObjType.Equals("System.Decimal", StringComparison.OrdinalIgnoreCase) Then
|
||||
|
||||
Dim oResult As String
|
||||
|
||||
If IsNumeric(Obj) = True Then
|
||||
Dim decValue As Decimal = CDec(Obj)
|
||||
' Es wird immer ein . als Dezimaltrenner verwendet, falls nötig
|
||||
oResult = decValue.ToString(CultureInfo.InvariantCulture)
|
||||
|
||||
'Return New List(Of Object) From {oResult}
|
||||
Dim oRetValue As List(Of Object) = New List(Of Object) From {
|
||||
oResult
|
||||
}
|
||||
|
||||
Return oRetValue
|
||||
|
||||
End If
|
||||
End If
|
||||
End If
|
||||
End If
|
||||
|
||||
|
||||
Next
|
||||
|
||||
Return New List(Of Object) From {Obj}
|
||||
@@ -299,13 +415,31 @@ Public Class PropertyValues
|
||||
Select Case oCount
|
||||
Case 0
|
||||
Return Nothing
|
||||
Case 1
|
||||
Dim firstElement As Object
|
||||
firstElement = oList.FirstOrDefault()
|
||||
If firstElement IsNot Nothing AndAlso IsArray(firstElement) Then
|
||||
|
||||
' Attachments sind Byte-Arrays und müssen umgewandelt werden
|
||||
Return Convert.ToBase64String(firstElement)
|
||||
|
||||
Else
|
||||
Return DoGetFinalPropValue(oList.First())
|
||||
End If
|
||||
Case Else
|
||||
Return DoGetFinalPropValue(oList.First())
|
||||
|
||||
End Select
|
||||
|
||||
Return DoGetFinalPropValue(Value)
|
||||
Else
|
||||
Return Value.ToString
|
||||
' Nothing kann auch der Default-Wert der Variablen bedeuten. Also auch 0.00
|
||||
If IsNothing(Value) Then
|
||||
Return String.Empty
|
||||
Else
|
||||
Return Value.ToString
|
||||
End If
|
||||
|
||||
End If
|
||||
End Function
|
||||
|
||||
|
||||
8
Interfaces/ZUGFeRDInterface/RejectionStringRow.vb
Normal file
8
Interfaces/ZUGFeRDInterface/RejectionStringRow.vb
Normal file
@@ -0,0 +1,8 @@
|
||||
Public Class RejectionStringRow
|
||||
Public ModuleName As String
|
||||
Public Title As String
|
||||
Public Caption As String
|
||||
Public Language As String
|
||||
Public String1 As String
|
||||
|
||||
End Class
|
||||
@@ -14,6 +14,7 @@ Public Class Validator
|
||||
ValidateDecimalNodes(pResult)
|
||||
ValidateCurrencyNodes(pResult)
|
||||
|
||||
'TODO Validate Datumsfelder
|
||||
Return pResult
|
||||
End Function
|
||||
|
||||
@@ -28,7 +29,8 @@ Public Class Validator
|
||||
pResult.ValidationErrors.Add(New ZugferdValidationError() With {
|
||||
.ElementName = oNode.Name.LocalName,
|
||||
.ElementValue = oNode.Value,
|
||||
.ErrorMessage = "Value could not be parsed as Decimal"
|
||||
.ErrorMessage = "Value could not be parsed as Decimal.",
|
||||
.ErrorMessageDE = "Der Wert ist keine Dezimalzahl."
|
||||
})
|
||||
End If
|
||||
Next
|
||||
@@ -50,7 +52,8 @@ Public Class Validator
|
||||
pResult.ValidationErrors.Add(New ZugferdValidationError() With {
|
||||
.ElementName = oNode.Name.LocalName,
|
||||
.ElementValue = oNode.Value,
|
||||
.ErrorMessage = "Invalid CurrencyCode. Only 3-Character codes are allowed."
|
||||
.ErrorMessage = "Invalid CurrencyCode. Only 3-Character codes are allowed.",
|
||||
.ErrorMessageDE = "Ungültiger Währungscode. Es sind nur 3-stellige Codes erlaubt."
|
||||
})
|
||||
End If
|
||||
Next
|
||||
@@ -76,7 +79,8 @@ Public Class Validator
|
||||
pResult.ValidationErrors.Add(New ZugferdValidationError() With {
|
||||
.ElementName = oNode.Name.LocalName,
|
||||
.ElementValue = oCurrencyID,
|
||||
.ErrorMessage = "Invalid currencyID. Only 3-Character codes or empty values are allowed."
|
||||
.ErrorMessage = "Invalid currencyID. Only 3-Character codes or empty values are allowed.",
|
||||
.ErrorMessageDE = "Ungültige WährungsID. Es sind nur 3-Zeichen lange Codes oder ein leerer Wert erlaubt."
|
||||
})
|
||||
End If
|
||||
Next
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -11,4 +11,25 @@
|
||||
''' Document version, eg. ZUGFeRD Schema version
|
||||
''' </summary>
|
||||
Public Specification As String
|
||||
|
||||
''' <summary>
|
||||
''' XML Pfad, für Anzeige in Ablehnungsmail
|
||||
''' </summary>
|
||||
Public XMLPath As String
|
||||
|
||||
''' <summary>
|
||||
''' (Daten-)Typ des Knoten
|
||||
''' 0 = Default / Text
|
||||
''' 1 = Datum
|
||||
''' 2 = Gleitkomma
|
||||
''' 3 = Attachment-Felder
|
||||
''' 4 = Elemente einer Liste, vgl Currency
|
||||
''' </summary>
|
||||
Public ItemType As Integer
|
||||
|
||||
''' <summary>
|
||||
''' BT-Feld-Bezeichnung
|
||||
''' </summary>
|
||||
Public EN16931_ID As String
|
||||
|
||||
End Class
|
||||
@@ -1,11 +1,47 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="FirebirdSql.Data.FirebirdClient" publicKeyToken="3750abcc3150b00c" culture="neutral"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-7.5.0.0" newVersion="7.5.0.0"/>
|
||||
<assemblyIdentity name="FirebirdSql.Data.FirebirdClient" publicKeyToken="3750abcc3150b00c" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-7.5.0.0" newVersion="7.5.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-13.0.0.0" newVersion="13.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-6.0.1.0" newVersion="6.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.4.0" newVersion="4.0.4.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Numerics.Vectors" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.1.5.0" newVersion="4.1.5.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Security.Cryptography.Pkcs" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-8.0.0.1" newVersion="8.0.0.1" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.IO.Packaging" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-8.0.0.1" newVersion="8.0.0.1" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Text.Json" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-8.0.0.6" newVersion="8.0.0.6" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/></startup></configuration>
|
||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" /></startup></configuration>
|
||||
|
||||
@@ -1,5 +1,32 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Newtonsoft.Json" version="12.0.3" targetFramework="net461" />
|
||||
<package id="BouncyCastle.Cryptography" version="2.5.0" targetFramework="net462" />
|
||||
<package id="DocumentFormat.OpenXml" version="3.2.0" targetFramework="net462" />
|
||||
<package id="DocumentFormat.OpenXml.Framework" version="3.2.0" targetFramework="net462" />
|
||||
<package id="GdPicture" version="14.3.3" targetFramework="net462" />
|
||||
<package id="GdPicture.runtimes.windows" version="14.3.3" targetFramework="net462" />
|
||||
<package id="Microsoft.AspNet.WebApi.Client" version="6.0.0" targetFramework="net462" />
|
||||
<package id="Microsoft.Bcl.AsyncInterfaces" version="8.0.0" targetFramework="net462" />
|
||||
<package id="Microsoft.CSharp" version="4.7.0" targetFramework="net462" />
|
||||
<package id="Microsoft.VisualBasic" version="10.3.0" targetFramework="net462" />
|
||||
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net462" />
|
||||
<package id="Newtonsoft.Json.Bson" version="1.0.2" targetFramework="net462" />
|
||||
<package id="NLog" version="5.0.5" targetFramework="net461" />
|
||||
<package id="OpenMcdf" version="2.4.1" targetFramework="net462" />
|
||||
<package id="protobuf-net" version="3.2.46" targetFramework="net462" />
|
||||
<package id="protobuf-net.Core" version="3.2.46" targetFramework="net462" />
|
||||
<package id="RtfPipe" version="2.0.7677.4303" targetFramework="net462" />
|
||||
<package id="System.Buffers" version="4.6.0" targetFramework="net462" />
|
||||
<package id="System.CodeDom" version="8.0.0" targetFramework="net462" />
|
||||
<package id="System.Collections.Immutable" version="8.0.0" targetFramework="net462" />
|
||||
<package id="System.IO.Packaging" version="8.0.1" targetFramework="net462" />
|
||||
<package id="System.Management" version="8.0.0" targetFramework="net462" />
|
||||
<package id="System.Memory" version="4.6.0" targetFramework="net462" />
|
||||
<package id="System.Numerics.Vectors" version="4.6.0" targetFramework="net462" />
|
||||
<package id="System.Runtime.CompilerServices.Unsafe" version="6.1.0" targetFramework="net462" />
|
||||
<package id="System.Security.Cryptography.Pkcs" version="8.0.1" targetFramework="net462" />
|
||||
<package id="System.Text.Encodings.Web" version="8.0.0" targetFramework="net462" />
|
||||
<package id="System.Text.Json" version="8.0.6" targetFramework="net462" />
|
||||
<package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net462" />
|
||||
<package id="System.ValueTuple" version="4.5.0" targetFramework="net462" />
|
||||
</packages>
|
||||
@@ -8,8 +8,8 @@ Public Class ADSyncJob
|
||||
Inherits JobBase
|
||||
Implements IJob(Of ADSyncArgs)
|
||||
|
||||
Public Sub New(LogConfig As LogConfig, Firebird As Firebird, MSSQL As MSSQLServer)
|
||||
MyBase.New(LogConfig, Firebird, MSSQL)
|
||||
Public Sub New(LogConfig As LogConfig, MSSQL As MSSQLServer)
|
||||
MyBase.New(LogConfig, MSSQL)
|
||||
End Sub
|
||||
|
||||
Public Sub Start(Arguments As ADSyncArgs) Implements IJob(Of ADSyncArgs).Start
|
||||
@@ -31,7 +31,7 @@ Public Class ADSyncJob
|
||||
|
||||
For Each oGroup In oGroups
|
||||
_Logger.Debug("Syncing Group [{0}]", oGroup)
|
||||
Dim oSyncedUsers = oSync.SyncUsersForGroup(oGroup, oAttributeMappings, _Firebird, _MSSQL, Arguments.UserFilter)
|
||||
Dim oSyncedUsers = oSync.SyncUsersForGroup(oGroup, oAttributeMappings, _MSSQL, Arguments.UserFilter)
|
||||
|
||||
If oSyncedUsers Is Nothing Then
|
||||
_Logger.Warn("Group [{0}] could not be synced!", oGroup)
|
||||
|
||||
@@ -1,13 +1,51 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" />
|
||||
</startup>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<assemblyIdentity name="GdPicture.NET.14" publicKeyToken="f52a2e60ad468dbb" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-14.3.9.0" newVersion="14.3.9.0" />
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="FirebirdSql.Data.FirebirdClient" publicKeyToken="3750abcc3150b00c" culture="neutral"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-7.5.0.0" newVersion="7.5.0.0"/>
|
||||
<assemblyIdentity name="FirebirdSql.Data.FirebirdClient" publicKeyToken="3750abcc3150b00c" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-7.5.0.0" newVersion="7.5.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-6.0.1.0" newVersion="6.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.4.0" newVersion="4.0.4.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-13.0.0.0" newVersion="13.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Numerics.Vectors" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.1.5.0" newVersion="4.1.5.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Security.Cryptography.Pkcs" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-8.0.0.1" newVersion="8.0.0.1" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.IO.Packaging" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-8.0.0.1" newVersion="8.0.0.1" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Text.Json" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-8.0.0.6" newVersion="8.0.0.6" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
Imports System.Collections.Generic
|
||||
Imports System.IO
|
||||
Imports DigitalData.Modules.Interfaces.PropertyValues
|
||||
Imports DigitalData.Modules.Interfaces.ZUGFeRDInterface
|
||||
|
||||
Public Class Exceptions
|
||||
@@ -7,11 +8,13 @@ Public Class Exceptions
|
||||
Inherits ApplicationException
|
||||
|
||||
Public ReadOnly File As FileInfo
|
||||
Public ReadOnly MissingProperties As List(Of MissingProperty)
|
||||
|
||||
Public Sub New(File As FileInfo)
|
||||
MyBase.New()
|
||||
Public Sub New(pFile As FileInfo, pMissingProperties As List(Of MissingProperty))
|
||||
MyBase.New($"Missing values in [{pFile.Name}]")
|
||||
|
||||
Me.File = File
|
||||
Me.File = pFile
|
||||
Me.MissingProperties = pMissingProperties
|
||||
End Sub
|
||||
End Class
|
||||
|
||||
@@ -73,8 +76,11 @@ Public Class Exceptions
|
||||
Public Class MD5HashException
|
||||
Inherits ApplicationException
|
||||
|
||||
Public Sub New(pInfo As String)
|
||||
MyBase.New(pInfo)
|
||||
Public ReadOnly FileName As String
|
||||
|
||||
Public Sub New(pMessage As String, pFileName As String)
|
||||
MyBase.New(pMessage)
|
||||
FileName = pFileName
|
||||
End Sub
|
||||
End Class
|
||||
End Class
|
||||
|
||||
@@ -1,29 +1,24 @@
|
||||
Option Explicit On
|
||||
|
||||
Imports System.Collections.Generic
|
||||
Imports System.Data
|
||||
Imports System.IO
|
||||
Imports System.Linq
|
||||
Imports System.Net.NetworkInformation
|
||||
Imports DigitalData.Modules.Config
|
||||
Imports DigitalData.Modules.Database
|
||||
Imports DigitalData.Modules.Interfaces
|
||||
Imports DigitalData.Modules.Jobs.GraphQL
|
||||
Imports DigitalData.Modules.Language
|
||||
Imports DigitalData.Modules.Logging
|
||||
Imports Newtonsoft.Json.Linq
|
||||
|
||||
Public Class GraphQLJob
|
||||
Inherits JobBase
|
||||
Implements IJob(Of GraphQLArgs)
|
||||
|
||||
Private _GraphQL As GraphQLInterface = Nothing
|
||||
Private _Model As GraphQLModel
|
||||
Private _Writer As GraphQLWriter
|
||||
|
||||
Private Const PLACEHOLDER_STATIC = "STATIC:"
|
||||
Private Const JOB_NAME = "GraphQL Job"
|
||||
|
||||
Public Sub New(LogConfig As LogConfig, MSSQL As MSSQLServer)
|
||||
MyBase.New(LogConfig, Nothing, MSSQL)
|
||||
MyBase.New(LogConfig, MSSQL)
|
||||
End Sub
|
||||
|
||||
Public Sub Start(Args As GraphQLArgs) Implements IJob(Of GraphQLArgs).Start
|
||||
@@ -34,6 +29,9 @@ Public Class GraphQLJob
|
||||
With oConfigManager.Config
|
||||
_GraphQL = New GraphQLInterface(_LogConfig, .BaseUrl, .Email, .Password, .CertificateFingerprint)
|
||||
End With
|
||||
_Logger.Info($"baseUrl is: {oConfigManager.Config.BaseUrl}")
|
||||
_Model = New GraphQLModel(_LogConfig, _MSSQL)
|
||||
_Writer = New GraphQLWriter(_LogConfig, _MSSQL)
|
||||
|
||||
' Login to get cookie
|
||||
_Logger.Debug("Logging in")
|
||||
@@ -44,41 +42,7 @@ Public Class GraphQLJob
|
||||
|
||||
_Logger.Debug("Loading Queries")
|
||||
|
||||
' Load query data from TBCUST_JOBRUNNER_QUERY
|
||||
Dim oQueryTable As DataTable = _MSSQL.GetDatatable("SELECT * FROM TBCUST_JOBRUNNER_QUERY ORDER BY SEQUENCE")
|
||||
Dim oQueryList As New List(Of Query)
|
||||
|
||||
' Save query data to business objects
|
||||
For Each oRow As DataRow In oQueryTable.Rows
|
||||
Dim oQuery As New Query With {
|
||||
.Id = oRow.Item("GUID"),
|
||||
.Name = oRow.Item("TITLE"),
|
||||
.ClearBeforeFill = oRow.ItemEx("CLEAR_BEFORE_FILL", False),
|
||||
.ConnectionId = oRow.ItemEx("CON_ID", 1), ' TODO: Connection String?
|
||||
.DestinationTable = oRow.ItemEx("DESTINATION_TABLE", String.Empty),
|
||||
.OperationName = oRow.ItemEx("OPERATION_NAME", String.Empty),
|
||||
.MappingBasePath = oRow.ItemEx("MAPPING_BASE_PATH", String.Empty),
|
||||
.QueryString = oRow.ItemEx("QUERY_STRING", String.Empty)
|
||||
}
|
||||
|
||||
If oQuery.DestinationTable = String.Empty Then
|
||||
_Logger.Warn("Value [DestinationTable] could not be read. Configuration incomplete.")
|
||||
End If
|
||||
|
||||
If oQuery.OperationName = String.Empty Then
|
||||
_Logger.Warn("Value [OperationName] could not be read. Configuration incomplete.")
|
||||
End If
|
||||
|
||||
If oQuery.MappingBasePath = String.Empty Then
|
||||
_Logger.Warn("Value [MappingBasePath] could not be read. Configuration incomplete.")
|
||||
End If
|
||||
|
||||
If oQuery.QueryString = String.Empty Then
|
||||
_Logger.Warn("Value [QueryString] could not be read. Configuration incomplete.")
|
||||
End If
|
||||
|
||||
oQueryList.Add(oQuery)
|
||||
Next
|
||||
Dim oQueryList = _Model.GetQueryList()
|
||||
|
||||
_Logger.Debug("Running [{0}] queries.", oQueryList.Count)
|
||||
|
||||
@@ -120,8 +84,16 @@ Public Class GraphQLJob
|
||||
|
||||
' Clear Table before inserting
|
||||
If pQuery.ClearBeforeFill = True Then
|
||||
If DeleteWithQueryName(pQuery) = False Then
|
||||
Throw New ApplicationException($"Error while clearing table before fill for Query [{pQuery.Name}]")
|
||||
If DeleteHistoryTable(pQuery) = False Then
|
||||
Throw New ApplicationException($"Error while dropping history table before fill for Query [{pQuery.Name}]")
|
||||
End If
|
||||
|
||||
If CreateHistoryTable(pQuery) = False Then
|
||||
Throw New ApplicationException($"Error while creating history table before fill for Query [{pQuery.Name}]")
|
||||
End If
|
||||
|
||||
If TruncateTable(pQuery) = False Then
|
||||
Throw New ApplicationException($"Error while truncating table before fill for Query [{pQuery.Name}]")
|
||||
End If
|
||||
End If
|
||||
|
||||
@@ -134,31 +106,22 @@ Public Class GraphQLJob
|
||||
End If
|
||||
|
||||
' get the data from GraphQL
|
||||
_Logger.Info("Getting data..", pQuery.Name)
|
||||
_Logger.Info("Getting data from GraphQL..", pQuery.Name)
|
||||
Dim oDataResponse = _GraphQL.GetData(pQuery.QueryString, pQuery.OperationName)
|
||||
Dim oResult As String
|
||||
Dim oJsonResult As String
|
||||
|
||||
' write data to string
|
||||
Using oStream = oDataResponse.GetResponseStream()
|
||||
Using oReader As New StreamReader(oStream)
|
||||
oResult = oReader.ReadToEnd()
|
||||
oJsonResult = oReader.ReadToEnd()
|
||||
End Using
|
||||
End Using
|
||||
|
||||
' Fill the query object with field mapping data from TBCUST_JOBRUNNER_QUERY_MAPPING
|
||||
Dim oSQL As String = "SELECT t2.* FROM TBCUST_JOBRUNNER_QUERY_MAPPING t
|
||||
JOIN TBCUST_JOBRUNNER_MAPPING t2 ON t.MAPPING_ID = t2.GUID
|
||||
WHERE t.QUERY_ID = {0}"
|
||||
Dim oMappingTable As DataTable = _MSSQL.GetDatatable(String.Format(oSQL, pQuery.Id))
|
||||
For Each oMapping As DataRow In oMappingTable.Rows
|
||||
pQuery.MappingFields.Add(New GraphQL.FieldMapping With {
|
||||
.DestinationColumn = oMapping.Item("DestinationColumn"),
|
||||
.SourcePath = oMapping.Item("SourcePath")
|
||||
})
|
||||
Next
|
||||
_Logger.Debug("Writing JSON data to database..")
|
||||
|
||||
' Handle the response from GraphQL and insert Data
|
||||
Dim oWriteDataResult As GraphQL.Query = WriteNewQueryData(oResult, pQuery, oDatabase)
|
||||
'Dim oWriteDataResult As Query = WriteNewQueryData(oResult, pQuery, oDatabase)
|
||||
Dim oWriteDataResult As Query = _Writer.WriteNewQueryData(oJsonResult, pQuery, JOB_NAME)
|
||||
|
||||
If IsNothing(oWriteDataResult) Then
|
||||
Throw New ApplicationException($"Error while handling Result of Query [{pQuery.Name}]")
|
||||
@@ -197,12 +160,34 @@ Public Class GraphQLJob
|
||||
End Try
|
||||
End Function
|
||||
|
||||
Private Function DeleteWithQueryName(pQuery)
|
||||
Dim oDeleteSQL = $"TRUNCATE TABLE {pQuery.DestinationTable}"
|
||||
Return _MSSQL.ExecuteNonQuery(oDeleteSQL)
|
||||
Private Function DeleteHistoryTable(pQuery As Query) As Boolean
|
||||
Dim oHistoryTableName = $"{pQuery.DestinationTable}_HISTORY"
|
||||
Dim oDeleteHistorySQL = $"
|
||||
IF (EXISTS (SELECT *
|
||||
FROM INFORMATION_SCHEMA.TABLES
|
||||
WHERE TABLE_SCHEMA = 'dbo'
|
||||
AND TABLE_NAME = '{oHistoryTableName}'))
|
||||
BEGIN
|
||||
DROP TABLE {oHistoryTableName};
|
||||
END"
|
||||
|
||||
Return _MSSQL.ExecuteNonQuery(oDeleteHistorySQL)
|
||||
End Function
|
||||
|
||||
Private Function DeleteWithStatus(pQuery As Query, pStatus As Integer)
|
||||
Private Function TruncateTable(pQuery As Query)
|
||||
Dim oDeleteTableSQL = $"TRUNCATE TABLE {pQuery.DestinationTable}"
|
||||
|
||||
Return _MSSQL.ExecuteNonQuery(oDeleteTableSQL)
|
||||
End Function
|
||||
|
||||
Private Function CreateHistoryTable(pQuery As Query) As Boolean
|
||||
Dim oHistoryTableName = $"{pQuery.DestinationTable}_HISTORY"
|
||||
Dim oFillHistorySQL = $"SELECT * INTO {oHistoryTableName} FROM {pQuery.DestinationTable}"
|
||||
|
||||
Return _MSSQL.ExecuteNonQuery(oFillHistorySQL)
|
||||
End Function
|
||||
|
||||
Private Function DeleteWithStatus(pQuery As Query, pStatus As Integer) As Boolean
|
||||
Dim oDeleteSQL = $"DELETE FROM {pQuery.DestinationTable} WHERE STATUS = {pStatus} AND ADDED_QUERY_ID = '{pQuery.Id}'"
|
||||
Return _MSSQL.ExecuteNonQuery(oDeleteSQL)
|
||||
End Function
|
||||
@@ -212,72 +197,6 @@ Public Class GraphQLJob
|
||||
Return _MSSQL.ExecuteNonQuery(oResetSQL)
|
||||
End Function
|
||||
|
||||
Private Function WriteNewQueryData(JsonString As String, QueryData As GraphQL.Query, DB As Database.MSSQLServer) As GraphQL.Query
|
||||
Dim oObj As JObject = JObject.Parse(JsonString)
|
||||
Dim oResultList As JToken
|
||||
|
||||
If _GraphQL.ReadJSONPathFragmented(oObj, QueryData.MappingBasePath) = False Then
|
||||
_Logger.Warn("There is an error in the MappingBasePath [{1}] configuration of query [{0}]", QueryData.Name, QueryData.MappingBasePath)
|
||||
End If
|
||||
|
||||
Try
|
||||
oResultList = oObj.SelectToken(QueryData.MappingBasePath, errorWhenNoMatch:=True)
|
||||
Catch ex As Exception
|
||||
_Logger.Warn("WriteNewQueryData: Could not find BasePath: [{0}] for query [{1}]", QueryData.MappingBasePath, QueryData.Name)
|
||||
_Logger.Error(ex)
|
||||
Return Nothing
|
||||
End Try
|
||||
|
||||
If oResultList Is Nothing Then
|
||||
_Logger.Warn("WriteNewQueryData: Could not find BasePath: [{0}] for query [{1}]", QueryData.MappingBasePath, QueryData.Name)
|
||||
Return Nothing
|
||||
End If
|
||||
|
||||
_Logger.Info("WriteNewQueryData: Processing Queue [{0}] with [{1}] Items", QueryData.Name, oResultList.Count)
|
||||
|
||||
For Each oResultItem As JToken In oResultList
|
||||
Try
|
||||
' ADDED_WHO, ADDED_QUERY_ID are system fields which are used to correctly fill
|
||||
' and delete rows in the destination table without touching rows from other queries
|
||||
Dim oKeys As New List(Of String) From {"ADDED_WHO", "ADDED_QUERY_ID", "STATUS"}
|
||||
Dim oValues As New List(Of String) From {JOB_NAME, QueryData.Id, "1"}
|
||||
|
||||
For Each oMapping In QueryData.MappingFields
|
||||
Dim oValue As String = String.Empty
|
||||
|
||||
If oMapping.SourcePath.StartsWith(PLACEHOLDER_STATIC) Then
|
||||
oValue = oMapping.SourcePath.Replace(PLACEHOLDER_STATIC, String.Empty)
|
||||
Else
|
||||
Dim oToken = oResultItem.SelectToken(oMapping.SourcePath)
|
||||
|
||||
If oToken Is Nothing Then
|
||||
_Logger.Warn("WriteNewQueryData: Could not find value at SourcePath: {0}", oMapping.SourcePath)
|
||||
oValue = String.Empty
|
||||
Else
|
||||
oValue = oToken.ToString
|
||||
End If
|
||||
End If
|
||||
|
||||
oValues.Add(oValue)
|
||||
oKeys.Add(oMapping.DestinationColumn)
|
||||
Next
|
||||
|
||||
Dim oColumnString = String.Join(",", oKeys.ToArray)
|
||||
|
||||
Dim oValueList = oValues.Select(Function(Value) $"'{Value.EscapeForSQL}'").ToList()
|
||||
Dim oValueString = String.Join(",", oValueList)
|
||||
|
||||
Dim oSQL As String = $"INSERT INTO {QueryData.DestinationTable} ({oColumnString}) VALUES ({oValueString})"
|
||||
|
||||
DB.ExecuteNonQuery(oSQL)
|
||||
Catch ex As Exception
|
||||
_Logger.Error(ex)
|
||||
End Try
|
||||
Next
|
||||
|
||||
Return QueryData
|
||||
End Function
|
||||
|
||||
Public Function ShouldStart(Arguments As GraphQLArgs) As Boolean Implements IJob(Of GraphQLArgs).ShouldStart
|
||||
Return Arguments.Enabled
|
||||
End Function
|
||||
|
||||
86
Jobs/GraphQL/GraphQLModel.vb
Normal file
86
Jobs/GraphQL/GraphQLModel.vb
Normal file
@@ -0,0 +1,86 @@
|
||||
Imports System.Collections.Generic
|
||||
Imports System.Data
|
||||
Imports DigitalData.Modules.Base
|
||||
Imports DigitalData.Modules.Database
|
||||
Imports DigitalData.Modules.Jobs.GraphQL
|
||||
Imports DigitalData.Modules.Logging
|
||||
|
||||
Public Class GraphQLModel
|
||||
Private Database As MSSQLServer
|
||||
Private LogConfig As LogConfig
|
||||
Private Logger As Logger
|
||||
|
||||
Public Sub New(pLogConfig As LogConfig, pDatabase As MSSQLServer)
|
||||
Database = pDatabase
|
||||
LogConfig = pLogConfig
|
||||
Logger = pLogConfig.GetLogger()
|
||||
End Sub
|
||||
|
||||
Public Function GetQueryList() As List(Of Query)
|
||||
Try
|
||||
Dim oQueryTable As DataTable = Database.GetDatatable("SELECT * FROM TBCUST_JOBRUNNER_QUERY WHERE ACTIVE = 1 ORDER BY SEQUENCE")
|
||||
Dim oQueryList As New List(Of Query)
|
||||
|
||||
For Each oRow As DataRow In oQueryTable.Rows
|
||||
Dim oQuery As New Query With {
|
||||
.Id = oRow.Item("GUID"),
|
||||
.Name = oRow.Item("TITLE"),
|
||||
.ClearBeforeFill = oRow.ItemEx("CLEAR_BEFORE_FILL", False),
|
||||
.ConnectionId = oRow.ItemEx("CON_ID", 1), ' TODO: Connection String?
|
||||
.DestinationTable = oRow.ItemEx("DESTINATION_TABLE", String.Empty),
|
||||
.OperationName = oRow.ItemEx("OPERATION_NAME", String.Empty),
|
||||
.MappingBasePath = oRow.ItemEx("MAPPING_BASE_PATH", String.Empty),
|
||||
.QueryString = oRow.ItemEx("QUERY_STRING", String.Empty)
|
||||
}
|
||||
|
||||
If oQuery.DestinationTable = String.Empty Then
|
||||
Logger.Warn("Value [DestinationTable] could not be read. Configuration incomplete.")
|
||||
End If
|
||||
|
||||
If oQuery.OperationName = String.Empty Then
|
||||
Logger.Warn("Value [OperationName] could not be read. Configuration incomplete.")
|
||||
End If
|
||||
|
||||
If oQuery.MappingBasePath = String.Empty Then
|
||||
Logger.Warn("Value [MappingBasePath] could not be read. Configuration incomplete.")
|
||||
End If
|
||||
|
||||
If oQuery.QueryString = String.Empty Then
|
||||
Logger.Warn("Value [QueryString] could not be read. Configuration incomplete.")
|
||||
End If
|
||||
|
||||
oQuery.MappingFields = GetQueryMapping(oQuery.Id)
|
||||
|
||||
oQueryList.Add(oQuery)
|
||||
Next
|
||||
|
||||
Return oQueryList
|
||||
Catch ex As Exception
|
||||
Logger.Error(ex)
|
||||
Return New List(Of Query)
|
||||
End Try
|
||||
End Function
|
||||
|
||||
Public Function GetQueryMapping(pQueryId As Integer) As List(Of FieldMapping)
|
||||
Try
|
||||
Dim oSQL As String = "SELECT t2.* FROM TBCUST_JOBRUNNER_QUERY_MAPPING t
|
||||
JOIN TBCUST_JOBRUNNER_MAPPING t2 ON t.MAPPING_ID = t2.GUID
|
||||
WHERE t.QUERY_ID = {0}"
|
||||
Dim oMappingTable As DataTable = Database.GetDatatable(String.Format(oSQL, pQueryId))
|
||||
Dim oMappings As New List(Of FieldMapping)
|
||||
|
||||
For Each oMapping As DataRow In oMappingTable.Rows
|
||||
oMappings.Add(New FieldMapping With {
|
||||
.DestinationColumn = oMapping.Item("DestinationColumn"),
|
||||
.SourcePath = oMapping.Item("SourcePath")
|
||||
})
|
||||
Next
|
||||
|
||||
Return oMappings
|
||||
Catch ex As Exception
|
||||
Logger.Error(ex)
|
||||
Return New List(Of FieldMapping)
|
||||
End Try
|
||||
End Function
|
||||
|
||||
End Class
|
||||
178
Jobs/GraphQL/GraphQLWriter.vb
Normal file
178
Jobs/GraphQL/GraphQLWriter.vb
Normal file
@@ -0,0 +1,178 @@
|
||||
Imports System
|
||||
Imports System.Collections.Generic
|
||||
Imports System.Data
|
||||
Imports System.Data.SqlClient
|
||||
Imports System.Linq
|
||||
Imports DigitalData.Modules.Database
|
||||
Imports DigitalData.Modules.Jobs.GraphQL
|
||||
Imports DigitalData.Modules.Logging
|
||||
Imports Newtonsoft.Json.Linq
|
||||
|
||||
Public Class GraphQLWriter
|
||||
Private ReadOnly Database As MSSQLServer
|
||||
Private ReadOnly LogConfig As LogConfig
|
||||
Private ReadOnly Logger As Logger
|
||||
|
||||
Private Const PLACEHOLDER_STATIC = "STATIC:"
|
||||
|
||||
Public Sub New(pLogConfig As LogConfig, pDatabase As MSSQLServer)
|
||||
Database = pDatabase
|
||||
LogConfig = pLogConfig
|
||||
Logger = pLogConfig.GetLogger()
|
||||
End Sub
|
||||
|
||||
Public Function WriteNewQueryData(pJsonString As String, pQueryData As Query, pJobName As String) As GraphQL.Query
|
||||
Try
|
||||
Logger.Debug("Parsing JSON...")
|
||||
|
||||
Dim oObj As JObject = JObject.Parse(pJsonString)
|
||||
Dim oResultList As JToken
|
||||
|
||||
If ValidateJSONPath(oObj, pQueryData.MappingBasePath) = False Then
|
||||
Logger.Warn("There is an error in the MappingBasePath [{1}] configuration of query [{0}]", pQueryData.Name, pQueryData.MappingBasePath)
|
||||
End If
|
||||
|
||||
Try
|
||||
oResultList = oObj.SelectToken(pQueryData.MappingBasePath, errorWhenNoMatch:=True)
|
||||
Catch ex As Exception
|
||||
Logger.Warn("Could not find BasePath: [{0}] for query [{1}]", pQueryData.MappingBasePath, pQueryData.Name)
|
||||
Logger.Error(ex)
|
||||
Return Nothing
|
||||
End Try
|
||||
|
||||
If oResultList Is Nothing Then
|
||||
Logger.Warn("Could not find BasePath: [{0}] for query [{1}]", pQueryData.MappingBasePath, pQueryData.Name)
|
||||
Return Nothing
|
||||
End If
|
||||
|
||||
Logger.Info("Processing Query [{0}] with [{1}] Items", pQueryData.Name, oResultList.Count)
|
||||
|
||||
Dim oTable As New DataTable
|
||||
Dim oColumnList = pQueryData.MappingFields.Select(Function(f) f.DestinationColumn).ToList()
|
||||
|
||||
For Each oColumnName In oColumnList
|
||||
oTable.Columns.Add(oColumnName)
|
||||
Next
|
||||
|
||||
oTable.Columns.Add("ADDED_WHO")
|
||||
oTable.Columns.Add("ADDED_QUERY_ID")
|
||||
oTable.Columns.Add("STATUS")
|
||||
|
||||
Logger.Debug("Creating DataTable..")
|
||||
|
||||
For Each oResultItem As JToken In oResultList
|
||||
Dim oRow = FillRowFromJson(pQueryData, oResultItem, pJobName, oTable)
|
||||
|
||||
If oRow Is Nothing Then
|
||||
Logger.Error("DataRow could not be created!")
|
||||
Continue For
|
||||
End If
|
||||
|
||||
oTable.Rows.Add(oRow)
|
||||
Next
|
||||
oTable.AcceptChanges()
|
||||
|
||||
Logger.Debug("Starting Bulk Insert..")
|
||||
|
||||
'Bulk insert
|
||||
Dim oBulkResult = BulkInsert(oTable, pQueryData.DestinationTable, oColumnList)
|
||||
|
||||
If oBulkResult = False Then
|
||||
Logger.Error("Bulk Insert for Query [{0}] failed!", pQueryData.Name)
|
||||
End If
|
||||
|
||||
Logger.Info("Bulk Insert finished. [{0}] rows inserted.", oTable.Rows.Count)
|
||||
|
||||
Return pQueryData
|
||||
|
||||
Catch ex As Exception
|
||||
Logger.Error(ex)
|
||||
Return Nothing
|
||||
|
||||
End Try
|
||||
End Function
|
||||
|
||||
Private Function FillRowFromJson(pQueryData As Query, pToken As JToken, pJobName As String, pTable As DataTable) As DataRow
|
||||
Try
|
||||
Dim oValuesNew As New Dictionary(Of String, String)
|
||||
Dim oRow As DataRow = pTable.NewRow()
|
||||
|
||||
For Each oMapping In pQueryData.MappingFields
|
||||
Dim oValue As String = String.Empty
|
||||
|
||||
If oMapping.SourcePath.StartsWith(PLACEHOLDER_STATIC) Then
|
||||
oValue = oMapping.SourcePath.Replace(PLACEHOLDER_STATIC, String.Empty)
|
||||
Else
|
||||
Dim oToken = pToken.SelectToken(oMapping.SourcePath)
|
||||
|
||||
If oToken Is Nothing Then
|
||||
Logger.Warn("WriteNewQueryData: Could not find value at SourcePath: {0}", oMapping.SourcePath)
|
||||
oValue = String.Empty
|
||||
Else
|
||||
oValue = oToken.ToString
|
||||
End If
|
||||
End If
|
||||
|
||||
oValuesNew.Add(oMapping.DestinationColumn, oValue)
|
||||
Next
|
||||
|
||||
oValuesNew.Add("ADDED_WHO", pJobName)
|
||||
oValuesNew.Add("ADDED_QUERY_ID", pQueryData.Id)
|
||||
oValuesNew.Add("STATUS", "1")
|
||||
|
||||
For Each oColumn As DataColumn In pTable.Columns
|
||||
oRow.Item(oColumn.ColumnName) = oValuesNew.Item(oColumn.ColumnName)
|
||||
Next
|
||||
|
||||
Return oRow
|
||||
Catch ex As Exception
|
||||
Logger.Error(ex)
|
||||
Return Nothing
|
||||
End Try
|
||||
End Function
|
||||
|
||||
Private Function BulkInsert(pTable As DataTable, pDestinationTable As String, pColumns As List(Of String)) As Boolean
|
||||
Using oConnection = Database.GetConnection()
|
||||
Using oBulkCopy = New SqlBulkCopy(oConnection)
|
||||
|
||||
oBulkCopy.DestinationTableName = pDestinationTable
|
||||
For Each oColumn In pColumns
|
||||
oBulkCopy.ColumnMappings.Add(New SqlBulkCopyColumnMapping(oColumn, oColumn))
|
||||
Next
|
||||
|
||||
Try
|
||||
oBulkCopy.WriteToServer(pTable)
|
||||
Catch ex As Exception
|
||||
Logger.Error(ex)
|
||||
Return False
|
||||
End Try
|
||||
End Using
|
||||
End Using
|
||||
|
||||
Return True
|
||||
End Function
|
||||
|
||||
Public Function ValidateJSONPath(pObject As Newtonsoft.Json.Linq.JObject, pJsonPath As String) As Boolean
|
||||
Dim oSplitPath As List(Of String) = pJsonPath.Split(".").ToList()
|
||||
Dim oCurrentPath As String = String.Empty
|
||||
|
||||
For Each oPart In oSplitPath
|
||||
If oCurrentPath = String.Empty Then
|
||||
oCurrentPath = oPart
|
||||
Else
|
||||
oCurrentPath &= "." & oPart
|
||||
End If
|
||||
|
||||
Logger.Debug("Selecting Path Fragment [{0}]", oCurrentPath)
|
||||
|
||||
Try
|
||||
pObject.SelectToken(oCurrentPath, errorWhenNoMatch:=True)
|
||||
Catch ex As Exception
|
||||
Logger.Warn("Path Fragment [{0}] did not return a valid token", oCurrentPath)
|
||||
Return False
|
||||
End Try
|
||||
Next
|
||||
|
||||
Return True
|
||||
End Function
|
||||
End Class
|
||||
@@ -4,13 +4,11 @@ Imports DigitalData.Modules.Logging
|
||||
Public Class JobBase
|
||||
Protected _LogConfig As LogConfig
|
||||
Protected _Logger As Logger
|
||||
Protected _Firebird As Firebird
|
||||
Protected _MSSQL As MSSQLServer
|
||||
|
||||
Public Sub New(LogConfig As LogConfig, Firebird As Firebird, MSSQL As MSSQLServer)
|
||||
Public Sub New(LogConfig As LogConfig, MSSQL As MSSQLServer)
|
||||
_LogConfig = LogConfig
|
||||
_Logger = LogConfig.GetLogger()
|
||||
_Firebird = Firebird
|
||||
_MSSQL = MSSQL
|
||||
End Sub
|
||||
End Class
|
||||
|
||||
@@ -4,6 +4,8 @@ Public Class JobConfig
|
||||
Public Property Name As JobType
|
||||
Public Property Enabled As Boolean = False
|
||||
Public Property StartWithoutDelay As Boolean = False
|
||||
|
||||
' https://www.quartz-scheduler.net/documentation/quartz-3.x/how-tos/crontrigger.html
|
||||
Public Property CronSchedule As String = ""
|
||||
|
||||
Public Property ArgsString As String = ""
|
||||
|
||||
193
Jobs/Jobs.vbproj
193
Jobs/Jobs.vbproj
@@ -14,6 +14,8 @@
|
||||
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<TargetFrameworkProfile />
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
@@ -65,22 +67,6 @@
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Base\Base.vbproj">
|
||||
<Project>{6ea0c51f-c2b1-4462-8198-3de0b32b74f8}</Project>
|
||||
<Name>Base</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Config\Config.vbproj">
|
||||
<Project>{44982f9b-6116-44e2-85d0-f39650b1ef99}</Project>
|
||||
<Name>Config</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Database\Database.vbproj">
|
||||
<Project>{eaf0ea75-5fa7-485d-89c7-b2d843b03a96}</Project>
|
||||
<Name>Database</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Filesystem\Filesystem.vbproj">
|
||||
<Project>{991d0231-4623-496d-8bd0-9ca906029cbc}</Project>
|
||||
<Name>Filesystem</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Interfaces\Interfaces.vbproj">
|
||||
<Project>{ab6f09bf-e794-4f6a-94bb-c97c0ba84d64}</Project>
|
||||
<Name>Interfaces</Name>
|
||||
@@ -96,10 +82,16 @@
|
||||
<Compile Include="GraphQL\GraphQLArgs.vb" />
|
||||
<Compile Include="GraphQL\GraphQLConfig.vb" />
|
||||
<Compile Include="GraphQL\GraphQLJob.vb" />
|
||||
<Compile Include="GraphQL\GraphQLModel.vb" />
|
||||
<Compile Include="GraphQL\GraphQLQuery.vb" />
|
||||
<Compile Include="GraphQL\GraphQLWriter.vb" />
|
||||
<Compile Include="ZUGFeRD\ErrorCode.vb" />
|
||||
<Compile Include="ZUGFeRD\EmailData.vb" />
|
||||
<Compile Include="ZUGFeRD\EmailFunctions.vb" />
|
||||
<Compile Include="ZUGFeRD\EmailStrings.vb" />
|
||||
<Compile Include="ZUGFeRD\FileFunctions.vb" />
|
||||
<Compile Include="ZUGFeRD\HashFunctions.vb" />
|
||||
<Compile Include="ZUGFeRD\HistoryFunctions.vb" />
|
||||
<Compile Include="ZUGFeRD\ImportZUGFeRDFiles.vb" />
|
||||
<Compile Include="ZUGFeRD\WorkerArgs.vb" />
|
||||
<Compile Include="Exceptions.vb" />
|
||||
@@ -114,31 +106,190 @@
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="ZUGFeRD\XRechnungStrings.vb" />
|
||||
<Compile Include="ZUGFeRD\XRechnungViewDocument.vb" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="DigitalData.Modules.Language, Version=1.7.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\Language\bin\Debug\DigitalData.Modules.Language.dll</HintPath>
|
||||
<Reference Include="BouncyCastle.Cryptography, Version=2.0.0.0, Culture=neutral, PublicKeyToken=072edcf4a5328938, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\BouncyCastle.Cryptography.2.5.0\lib\net461\BouncyCastle.Cryptography.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="DigitalData.Modules.Base">
|
||||
<HintPath>..\Base\bin\Debug\DigitalData.Modules.Base.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="DigitalData.Modules.Config">
|
||||
<HintPath>..\Config\bin\Debug\DigitalData.Modules.Config.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="DigitalData.Modules.Database">
|
||||
<HintPath>..\Database\bin\Debug\DigitalData.Modules.Database.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="DigitalData.Modules.Logging">
|
||||
<HintPath>..\Logging\bin\Debug\DigitalData.Modules.Logging.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="DocumentFormat.OpenXml, Version=3.2.0.0, Culture=neutral, PublicKeyToken=8fb06cb64d019a17, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\DocumentFormat.OpenXml.3.2.0\lib\net46\DocumentFormat.OpenXml.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="DocumentFormat.OpenXml.Framework, Version=3.2.0.0, Culture=neutral, PublicKeyToken=8fb06cb64d019a17, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\DocumentFormat.OpenXml.Framework.3.2.0\lib\net46\DocumentFormat.OpenXml.Framework.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="FirebirdSql.Data.FirebirdClient, Version=7.5.0.0, Culture=neutral, PublicKeyToken=3750abcc3150b00c, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\FirebirdSql.Data.FirebirdClient.7.5.0\lib\net452\FirebirdSql.Data.FirebirdClient.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GdPicture.NET.14, Version=14.3.19.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.19\lib\net462\GdPicture.NET.14.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GdPicture.NET.14.barcode.1d.writer, Version=14.3.19.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.19\lib\net462\GdPicture.NET.14.barcode.1d.writer.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GdPicture.NET.14.barcode.2d.writer, Version=14.3.19.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.19\lib\net462\GdPicture.NET.14.barcode.2d.writer.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GdPicture.NET.14.CAD, Version=14.3.19.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.19\lib\net462\GdPicture.NET.14.CAD.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GdPicture.NET.14.CAD.DWG, Version=14.3.19.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.19\lib\net462\GdPicture.NET.14.CAD.DWG.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GdPicture.NET.14.Common, Version=14.3.19.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.19\lib\net462\GdPicture.NET.14.Common.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GdPicture.NET.14.Document, Version=14.3.19.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.19\lib\net462\GdPicture.NET.14.Document.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GdPicture.NET.14.Email, Version=14.3.19.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.19\lib\net462\GdPicture.NET.14.Email.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GdPicture.NET.14.HTML, Version=14.3.19.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.19\lib\net462\GdPicture.NET.14.HTML.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GdPicture.NET.14.Imaging, Version=14.3.19.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.19\lib\net462\GdPicture.NET.14.Imaging.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GdPicture.NET.14.Imaging.Formats, Version=14.3.19.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.19\lib\net462\GdPicture.NET.14.Imaging.Formats.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GdPicture.NET.14.Imaging.Formats.Conversion, Version=14.3.19.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.19\lib\net462\GdPicture.NET.14.Imaging.Formats.Conversion.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GdPicture.NET.14.Imaging.Rendering, Version=14.3.19.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.19\lib\net462\GdPicture.NET.14.Imaging.Rendering.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GdPicture.NET.14.MSOfficeBinary, Version=14.3.19.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.19\lib\net462\GdPicture.NET.14.MSOfficeBinary.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GdPicture.NET.14.OpenDocument, Version=14.3.19.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.19\lib\net462\GdPicture.NET.14.OpenDocument.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GdPicture.NET.14.OpenXML, Version=14.3.19.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.19\lib\net462\GdPicture.NET.14.OpenXML.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GdPicture.NET.14.OpenXML.Templating, Version=14.3.19.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.19\lib\net462\GdPicture.NET.14.OpenXML.Templating.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GdPicture.NET.14.PDF, Version=14.3.19.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.19\lib\net462\GdPicture.NET.14.PDF.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GdPicture.NET.14.RTF, Version=14.3.19.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.19\lib\net462\GdPicture.NET.14.RTF.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GdPicture.NET.14.SVG, Version=14.3.19.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.19\lib\net462\GdPicture.NET.14.SVG.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GdPicture.NET.14.wia.gateway, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6973b5c22dcf45f7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.19\lib\net462\GdPicture.NET.14.wia.gateway.dll</HintPath>
|
||||
<EmbedInteropTypes>True</EmbedInteropTypes>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Bcl.AsyncInterfaces.8.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
<Reference Include="NativeSDK.Settings, Version=14.3.19.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.19\lib\net462\NativeSDK.Settings.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="NativeSDK.Settings.Edition, Version=14.3.19.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\GdPicture.14.3.19\lib\net462\NativeSDK.Settings.Edition.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json.Bson, Version=1.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Newtonsoft.Json.Bson.1.0.2\lib\net45\Newtonsoft.Json.Bson.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="NLog, Version=5.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NLog.5.0.5\lib\net46\NLog.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="OpenMcdf, Version=2.4.1.0, Culture=neutral, PublicKeyToken=fdbb1629d7c00800, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\OpenMcdf.2.4.1\lib\net40\OpenMcdf.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="protobuf-net, Version=3.0.0.0, Culture=neutral, PublicKeyToken=257b51d87d2e4d67, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\protobuf-net.3.2.46\lib\net462\protobuf-net.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="protobuf-net.Core, Version=3.0.0.0, Culture=neutral, PublicKeyToken=257b51d87d2e4d67, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\protobuf-net.Core.3.2.46\lib\net462\protobuf-net.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RtfPipe, Version=2.0.7677.4303, Culture=neutral, PublicKeyToken=5f6ab4ce530296d2, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\RtfPipe.2.0.7677.4303\lib\net45\RtfPipe.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Buffers, Version=4.0.4.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Buffers.4.6.0\lib\net462\System.Buffers.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Collections.Immutable, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Collections.Immutable.8.0.0\lib\net462\System.Collections.Immutable.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.IO.Compression" />
|
||||
<Reference Include="System.IO.Packaging, Version=8.0.0.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.IO.Packaging.8.0.1\lib\net462\System.IO.Packaging.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Management" />
|
||||
<Reference Include="System.Memory, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Memory.4.6.0\lib\net462\System.Memory.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Net.Http.Formatting, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.AspNet.WebApi.Client.6.0.0\lib\net45\System.Net.Http.Formatting.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Numerics" />
|
||||
<Reference Include="System.Numerics.Vectors, Version=4.1.5.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Numerics.Vectors.4.6.0\lib\net462\System.Numerics.Vectors.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=6.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.6.1.0\lib\net462\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Serialization" />
|
||||
<Reference Include="System.Security" />
|
||||
<Reference Include="System.Security.Cryptography.Pkcs, Version=8.0.0.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Security.Cryptography.Pkcs.8.0.1\lib\net462\System.Security.Cryptography.Pkcs.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ServiceModel" />
|
||||
<Reference Include="System.Text.Encodings.Web, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Text.Encodings.Web.8.0.0\lib\net462\System.Text.Encodings.Web.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Text.Json, Version=8.0.0.6, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Text.Json.8.0.6\lib\net462\System.Text.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Transactions" />
|
||||
<Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.ValueTuple.4.5.0\lib\net461\System.ValueTuple.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.XML.Linq" />
|
||||
<Reference Include="WindowsBase" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>powershell.exe -command "& { &'$(SolutionDir)copy-binary.ps1' '$(TargetPath)' '$(TargetFileName)' '$(ConfigurationName)' '$(ProjectName)' }"</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\packages\GdPicture.runtimes.windows.14.3.19\build\net462\GdPicture.runtimes.windows.targets" Condition="Exists('..\packages\GdPicture.runtimes.windows.14.3.19\build\net462\GdPicture.runtimes.windows.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>Dieses Projekt verweist auf mindestens ein NuGet-Paket, das auf diesem Computer fehlt. Verwenden Sie die Wiederherstellung von NuGet-Paketen, um die fehlenden Dateien herunterzuladen. Weitere Informationen finden Sie unter "http://go.microsoft.com/fwlink/?LinkID=322105". Die fehlende Datei ist "{0}".</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\GdPicture.runtimes.windows.14.3.19\build\net462\GdPicture.runtimes.windows.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\GdPicture.runtimes.windows.14.3.19\build\net462\GdPicture.runtimes.windows.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -12,8 +12,8 @@ Imports System.Runtime.InteropServices
|
||||
<Assembly: AssemblyDescription("")>
|
||||
<Assembly: AssemblyCompany("Digital Data")>
|
||||
<Assembly: AssemblyProduct("Modules.Jobs")>
|
||||
<Assembly: AssemblyCopyright("Copyright © 2023")>
|
||||
<Assembly: AssemblyTrademark("1.15.0.0")>
|
||||
<Assembly: AssemblyCopyright("Copyright © 2025")>
|
||||
<Assembly: AssemblyTrademark("3.0.3.0")>
|
||||
|
||||
<Assembly: ComVisible(False)>
|
||||
|
||||
@@ -30,5 +30,5 @@ Imports System.Runtime.InteropServices
|
||||
' Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
|
||||
' übernehmen, indem Sie "*" eingeben:
|
||||
|
||||
<Assembly: AssemblyVersion("1.15.0.0")>
|
||||
<Assembly: AssemblyFileVersion("1.15.0.0")>
|
||||
<Assembly: AssemblyVersion("3.5.0.0")>
|
||||
<Assembly: AssemblyFileVersion("3.5.0.0")>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Public Class EmailData
|
||||
Public Attachment As String = ""
|
||||
Public Subject As String
|
||||
Public From As String
|
||||
Public Subject As String = ""
|
||||
Public From As String = ""
|
||||
End Class
|
||||
@@ -1,119 +1,196 @@
|
||||
Imports DigitalData.Modules.Logging
|
||||
Imports DigitalData.Modules.Database
|
||||
Imports DigitalData.Modules.Language
|
||||
Imports System.Collections.Generic
|
||||
Imports System.Data
|
||||
Imports System.IO
|
||||
Imports System.Data.SqlClient
|
||||
Imports System.IO
|
||||
Imports DigitalData.Modules.Base
|
||||
Imports DigitalData.Modules.Database
|
||||
Imports DigitalData.Modules.Interfaces.PropertyValues
|
||||
Imports DigitalData.Modules.Logging
|
||||
|
||||
Public Class EmailFunctions
|
||||
Private ReadOnly _logConfig As LogConfig
|
||||
Private ReadOnly _logger As Logger
|
||||
Private ReadOnly _mssql As MSSQLServer
|
||||
Private ReadOnly _firebird As Firebird
|
||||
Namespace ZUGFeRD
|
||||
Public Class EmailFunctions
|
||||
Private ReadOnly _logConfig As LogConfig
|
||||
Private ReadOnly _logger As Logger
|
||||
Private ReadOnly _mssql As MSSQLServer
|
||||
|
||||
Public Sub New(LogConfig As LogConfig, MSSQL As MSSQLServer, Firebird As Firebird)
|
||||
_logConfig = LogConfig
|
||||
_logger = _logConfig.GetLogger()
|
||||
_mssql = MSSQL
|
||||
_firebird = Firebird
|
||||
End Sub
|
||||
Public Sub New(LogConfig As LogConfig, MSSQL As MSSQLServer)
|
||||
_logConfig = LogConfig
|
||||
_logger = _logConfig.GetLogger()
|
||||
_mssql = MSSQL
|
||||
End Sub
|
||||
|
||||
Public Sub AddToEmailQueueFB(MessageId As String, BodyText As String, EmailData As EmailData, NamePortal As String)
|
||||
If EmailData Is Nothing Then
|
||||
_logger.Warn("EmailData is empty. Email will not be sent!")
|
||||
Exit Sub
|
||||
End If
|
||||
''' <summary>
|
||||
''' Method to decide wether we use the old or the new
|
||||
''' Rejection E-mail method.
|
||||
'''
|
||||
''' TODO we have no information about the language of the receiver at the moment
|
||||
''' </summary>
|
||||
''' <param name="pMessageId">E-Mail Message ID</param>
|
||||
''' <param name="pTransaction">DB Transaction</param>
|
||||
''' <param name="pBodyText">Body Text</param>
|
||||
''' <param name="pEmailData">Email Data object</param>
|
||||
''' <param name="pSourceProcedure">Exception Title</param>
|
||||
''' <param name="pEmailAccountId">Sending Profile from config</param>
|
||||
''' <param name="pNamePortal">Name of the Portal from config</param>
|
||||
''' <param name="pTemplateId">ID for E-Mail-Template from config</param>
|
||||
''' <param name="pErrorCode">Error Code</param>
|
||||
''' <param name="pParameter1">Zusätzlicher Parameter 1</param>
|
||||
''' <param name="pParameter2">Zusätzlicher Parameter 2</param>
|
||||
Public Sub AddToEmailQueueMSSQL(pMessageId As String, pTransaction As SqlTransaction, pBodyText As String, pEmailData As EmailData, pSourceProcedure As String,
|
||||
pEmailAccountId As Integer, pNamePortal As String, pTemplateId As Integer, pErrorCode As ErrorCode,
|
||||
pParameter1 As String, pParameter2 As String)
|
||||
|
||||
Try
|
||||
Dim oJobId = RandomValue(1, 10000)
|
||||
Dim oReference = MessageId
|
||||
Dim oEmailTo = ""
|
||||
Dim oSubject = EmailStrings.EMAIL_SUBJECT_REJECTED.Replace(EmailStrings.constNAME_ZUGFERD_PORTAL, NamePortal)
|
||||
Dim oAccountId = 1
|
||||
Dim oCreatedWho = "ZUGFeRD Service"
|
||||
Dim oFinalBodyText = String.Format(EmailStrings.EMAIL_WRAPPING_TEXT.Replace(EmailStrings.constNAME_ZUGFERD_PORTAL, NamePortal), BodyText)
|
||||
Dim useLegacyMethod = True
|
||||
Dim oErrorCode As String = String.Empty
|
||||
|
||||
Dim oEmailAddress = EmailData.From
|
||||
Dim oAttachment = EmailData.Attachment
|
||||
' ErrorCode valid?
|
||||
If pErrorCode <> ErrorCode.Unknown Then
|
||||
Dim intCode As Integer = DirectCast(pErrorCode, Integer)
|
||||
oErrorCode = $"{EmailStrings.ErrorCodePraefix}{intCode}"
|
||||
|
||||
If IsNothing(oEmailAddress) OrElse String.IsNullOrWhiteSpace(oEmailAddress) Then
|
||||
_logger.Warn("Could not find email-address for MessageId {0}", MessageId)
|
||||
oEmailTo = String.Empty
|
||||
Else
|
||||
oEmailTo = oEmailAddress
|
||||
End If
|
||||
|
||||
_logger.Debug("Generated Email:")
|
||||
_logger.Debug("To: {0}", oEmailTo)
|
||||
_logger.Debug("Subject: {0}", oSubject)
|
||||
_logger.Debug("Body {0}", oFinalBodyText)
|
||||
Dim osql = $"select * from TBEDM_EMAIL_QUEUE where REFERENCE1 = '{oReference} and EMAIL_TO = ''{oEmailTo}' and EMAIL_SUBJ = '{oSubject}'"
|
||||
|
||||
Dim oDTResult As DataTable = _firebird.GetDatatable(osql)
|
||||
|
||||
If oDTResult.Rows.Count = 0 Then
|
||||
Dim oSQLInsert = $"INSERT INTO TBEDM_EMAIL_QUEUE "
|
||||
oSQLInsert &= "(JOB_ID, REFERENCE1, EMAIL_ACCOUNT_ID, EMAIL_TO, EMAIL_SUBJ, EMAIL_BODY, CREATEDWHO, EMAIL_ATTMT1) VALUES "
|
||||
oSQLInsert &= $"({oJobId}, '{oReference}', {oAccountId}, '{oEmailTo}', '{oSubject}', '{oFinalBodyText.Replace("'", "''")}', '{oCreatedWho}', '{oAttachment}')"
|
||||
_firebird.ExecuteNonQuery(oSQLInsert)
|
||||
_logger.Debug("Email Queue updated for MessageId {0}.", MessageId, oEmailTo)
|
||||
Else
|
||||
_logger.Debug("Email has already been sent!!")
|
||||
End If
|
||||
Catch ex As Exception
|
||||
_logger.Error(ex)
|
||||
End Try
|
||||
End Sub
|
||||
Public Sub AddToEmailQueueMSSQL(MessageId As String, BodyText As String, pEmailData As EmailData, SourceProcedure As String, pEmailAccountId As Integer, NamePortal As String)
|
||||
If pEmailData Is Nothing Then
|
||||
_logger.Warn("EmailData is empty. Email will not be sent!")
|
||||
Exit Sub
|
||||
End If
|
||||
|
||||
Try
|
||||
Dim oJobId = RandomValue(1, 10000)
|
||||
Dim oReference = MessageId
|
||||
Dim oEmailTo = ""
|
||||
Dim oSubject = EmailStrings.EMAIL_SUBJECT_REJECTED.Replace(EmailStrings.constNAME_ZUGFERD_PORTAL, NamePortal)
|
||||
Dim oCreatedWho = "ZUGFeRD Service"
|
||||
|
||||
Dim oMaskedBodyText = BodyText.Replace("'", "''")
|
||||
Dim oSubjectBodyText = String.Format(EmailStrings.EMAIL_SUBJECT_TEXT.Replace(EmailStrings.constNAME_ZUGFERD_PORTAL, NamePortal), pEmailData.Subject).Replace("'", "''")
|
||||
Dim oCompleteBodyText = oMaskedBodyText & oSubjectBodyText
|
||||
|
||||
Dim oFinalBodyText = String.Format(EmailStrings.EMAIL_WRAPPING_TEXT.Replace(EmailStrings.constNAME_ZUGFERD_PORTAL, NamePortal), oCompleteBodyText)
|
||||
|
||||
Dim oEmailAddress = pEmailData.From
|
||||
Dim oAttachmentPath = pEmailData.Attachment
|
||||
If oAttachmentPath <> String.Empty Then
|
||||
_logger.Debug($"Attachment_String [{oAttachmentPath}]!")
|
||||
If IO.File.Exists(oAttachmentPath) = False Then
|
||||
_logger.Info($"Attachment.File [{oAttachmentPath}] is not existing!!!")
|
||||
Dim oSQL = $"SELECT COUNT(*) FROM TBDD_GUI_LANGUAGE_PHRASE WHERE TITLE = '{oErrorCode}'"
|
||||
If _mssql.GetScalarValue(oSQL) > 0 Then
|
||||
useLegacyMethod = False
|
||||
Else
|
||||
_logger.Warn($"Rejection reason [{oErrorCode}] not found in TBDD_GUI_LANGUAGE_PHRASE!")
|
||||
End If
|
||||
End If
|
||||
Dim oAttachmentPathEscaped = oAttachmentPath.Replace("'", "''")
|
||||
|
||||
If IsNothing(oEmailAddress) OrElse String.IsNullOrWhiteSpace(oEmailAddress) Then
|
||||
_logger.Warn("Could not find email-address for MessageId {0}", MessageId)
|
||||
oEmailTo = String.Empty
|
||||
' Gibt es das Template in TBDD_EMAIL_TEMPLATE?
|
||||
If useLegacyMethod = False AndAlso pTemplateId > 0 Then
|
||||
Try
|
||||
Dim oSQL = $"SELECT COUNT(*) FROM TBDD_EMAIL_TEMPLATE WHERE GUID = {pTemplateId}"
|
||||
If _mssql.GetScalarValue(oSQL) <= 0 Then
|
||||
_logger.Warn($"EMAIL_TEMPLATE [{pTemplateId}] not found in TBDD_EMAIL_TEMPLATE!")
|
||||
useLegacyMethod = True
|
||||
End If
|
||||
Catch ex As Exception
|
||||
_logger.Error(ex)
|
||||
useLegacyMethod = True
|
||||
End Try
|
||||
|
||||
Else
|
||||
oEmailTo = oEmailAddress
|
||||
_logger.Debug($"RejectionTemplateId not configured!")
|
||||
useLegacyMethod = True
|
||||
End If
|
||||
|
||||
_logger.Debug("Generated Email:")
|
||||
_logger.Debug("To: {0}", oEmailTo)
|
||||
_logger.Debug("Subject: {0}", oSubject)
|
||||
_logger.Debug("Body {0}", oFinalBodyText)
|
||||
Dim osql = $"Select MAX(GUID) FROM TBEMLP_HISTORY WHERE EMAIL_MSGID = '{MessageId}'"
|
||||
Dim oHistoryID = _mssql.GetScalarValue(osql)
|
||||
' Check if Stored Procedure PRDD_SEND_REJECTION_MAIL exists
|
||||
If useLegacyMethod = False Then
|
||||
Try
|
||||
Dim oSQL = $"SELECT COUNT(*) FROM sys.objects WHERE type = 'P' AND OBJECT_ID = OBJECT_ID('dbo.PRDD_SEND_REJECTION_MAIL')"
|
||||
If _mssql.GetScalarValue(oSQL) <= 0 Then
|
||||
_logger.Warn($"Procedure ['PRDD_SEND_REJECTION_MAIL'] not found in Database!")
|
||||
useLegacyMethod = True
|
||||
End If
|
||||
Catch ex As Exception
|
||||
_logger.Error(ex)
|
||||
useLegacyMethod = True
|
||||
End Try
|
||||
End If
|
||||
|
||||
'osql = $"select * from TBEMLP_EMAIL_OUT where REFERENCE_ID = {oHistoryID} and EMAIL_ADRESS = '{oEmailTo}' and EMAIL_SUBJ = '{oSubject}'"
|
||||
If useLegacyMethod = True Then
|
||||
_logger.Warn("New rejection mail logic is not configured correctly, use legacy logic instead!")
|
||||
AddToEmailQueueMSSQL(pMessageId, pBodyText, pEmailData, pSourceProcedure, pEmailAccountId, pNamePortal)
|
||||
Else
|
||||
_logger.Debug("New rejection mail logic is configured!")
|
||||
AddToEmailQueueMSSQL(pMessageId, pTransaction, pTemplateId, oErrorCode, pEmailAccountId, pParameter1, pParameter2)
|
||||
End If
|
||||
|
||||
'Dim oDTResult As DataTable = _mssql.GetDatatable(osql)
|
||||
End Sub
|
||||
|
||||
If IsNumeric(oHistoryID) Then
|
||||
Dim oInsert = $"INSERT INTO [dbo].[TBEMLP_EMAIL_OUT] (
|
||||
[REMINDER_TYPE_ID]
|
||||
|
||||
''' <summary>
|
||||
''' Function calls SP PRDD_SEND_REJECTION_MAIL
|
||||
''' for sending rejection mail.
|
||||
''' </summary>
|
||||
''' <param name="pMessageId">E-Mail Message ID</param>
|
||||
''' <param name="pTransaction">DB Transaction</param>
|
||||
''' <param name="pTemplateId">GUID for TBDD_EMAIL_TEMPLATE from config</param>
|
||||
''' <param name="pErrorCode">ErrorID (TBDD_GUI_LANGUAGE_PHRASE)</param>
|
||||
''' <param name="pEmailAccountId">Sending profile from config</param>
|
||||
''' <param name="pParameter1">Zusätzlicher Parameter 1</param>
|
||||
''' <param name="pParameter2">Zusätzlicher Parameter 2</param>
|
||||
Private Sub AddToEmailQueueMSSQL(pMessageId As String, pTransaction As SqlTransaction, pTemplateId As Integer, pErrorCode As String, pEmailAccountId As Integer,
|
||||
pParameter1 As String, pParameter2 As String)
|
||||
|
||||
If pParameter1.IsNullOrEmpty Then
|
||||
pParameter1 = ""
|
||||
Else
|
||||
pParameter1 = pParameter1.Replace("'", "''")
|
||||
End If
|
||||
|
||||
If pParameter2.IsNullOrEmpty Then
|
||||
pParameter2 = ""
|
||||
Else
|
||||
pParameter2 = pParameter2.Replace("'", "''")
|
||||
End If
|
||||
|
||||
Try
|
||||
Dim oExecute = $"EXECUTE dbo.PRDD_SEND_REJECTION_MAIL
|
||||
'{pMessageId}'
|
||||
, 0
|
||||
, {pEmailAccountId}
|
||||
, 'ZUGFeRD Service'
|
||||
, {pTemplateId}
|
||||
, '{pErrorCode}'
|
||||
, '{pParameter1}'
|
||||
, '{pParameter2}'
|
||||
, 77"
|
||||
|
||||
_mssql.ExecuteNonQuery(oExecute, pTransaction)
|
||||
|
||||
Catch ex As Exception
|
||||
_logger.Error(ex)
|
||||
End Try
|
||||
|
||||
End Sub
|
||||
|
||||
Private Sub AddToEmailQueueMSSQL(MessageId As String, BodyText As String, pEmailData As EmailData, SourceProcedure As String, pEmailAccountId As Integer, NamePortal As String)
|
||||
If pEmailData Is Nothing Then
|
||||
_logger.Warn("EmailData is empty. Email will not be sent!")
|
||||
Exit Sub
|
||||
End If
|
||||
|
||||
Try
|
||||
Dim oJobId = RandomValue(1, 10000)
|
||||
Dim oReference = MessageId
|
||||
Dim oEmailTo = ""
|
||||
Dim oSubject = EmailStrings.EMAIL_SUBJECT_REJECTED.Replace(EmailStrings.constNAME_ZUGFERD_PORTAL, NamePortal)
|
||||
Dim oCreatedWho = "ZUGFeRD Service"
|
||||
|
||||
Dim oMaskedBodyText = BodyText.Replace("'", "''")
|
||||
Dim oSubjectBodyText = String.Format(EmailStrings.EMAIL_SUBJECT_TEXT.Replace(EmailStrings.constNAME_ZUGFERD_PORTAL, NamePortal), pEmailData.Subject).Replace("'", "''")
|
||||
Dim oCompleteBodyText = oMaskedBodyText & oSubjectBodyText
|
||||
|
||||
Dim oFinalBodyText = String.Format(EmailStrings.EMAIL_WRAPPING_TEXT.Replace(EmailStrings.constNAME_ZUGFERD_PORTAL, NamePortal), oCompleteBodyText)
|
||||
|
||||
Dim oEmailAddress = pEmailData.From
|
||||
Dim oAttachmentPath = pEmailData.Attachment
|
||||
If oAttachmentPath <> String.Empty Then
|
||||
_logger.Debug($"Attachment_String [{oAttachmentPath}]!")
|
||||
If IO.File.Exists(oAttachmentPath) = False Then
|
||||
_logger.Info($"Attachment.File [{oAttachmentPath}] is not existing!!!")
|
||||
End If
|
||||
End If
|
||||
Dim oAttachmentPathEscaped = oAttachmentPath.Replace("'", "''")
|
||||
|
||||
If IsNothing(oEmailAddress) OrElse String.IsNullOrWhiteSpace(oEmailAddress) Then
|
||||
_logger.Warn("Could not find email-address for MessageId {0}", MessageId)
|
||||
oEmailTo = String.Empty
|
||||
Else
|
||||
oEmailTo = oEmailAddress
|
||||
End If
|
||||
|
||||
_logger.Debug("Generated Email:")
|
||||
_logger.Debug("To: {0}", oEmailTo)
|
||||
_logger.Debug("Subject: {0}", oSubject)
|
||||
_logger.Debug("Body {0}", oFinalBodyText)
|
||||
Dim osql = $"Select MAX(GUID) FROM TBEMLP_HISTORY WHERE EMAIL_MSGID = '{MessageId}'"
|
||||
Dim oHistoryID = _mssql.GetScalarValue(osql)
|
||||
|
||||
If IsNumeric(oHistoryID) Then
|
||||
Dim oInsert = $"INSERT INTO [dbo].[TBEMLP_EMAIL_OUT]
|
||||
([REMINDER_TYPE_ID]
|
||||
,[SENDING_PROFILE]
|
||||
,[REFERENCE_ID]
|
||||
,[REFERENCE_STRING]
|
||||
@@ -136,79 +213,86 @@ Public Class EmailFunctions
|
||||
,'{SourceProcedure}'
|
||||
,'{oCreatedWho}'
|
||||
,'{oAttachmentPathEscaped}')"
|
||||
_mssql.ExecuteNonQuery(oInsert)
|
||||
Else
|
||||
'If oDTResult.Rows.Count = 0 Then
|
||||
' _logger.Debug("Email has already been sent!!")
|
||||
'Else
|
||||
_logger.Warn("Could not get oHistoryID in AddToEmailQueueMSSQL!!")
|
||||
' End If
|
||||
End If
|
||||
Catch ex As Exception
|
||||
_logger.Error(ex)
|
||||
End Try
|
||||
End Sub
|
||||
_mssql.ExecuteNonQuery(oInsert)
|
||||
Else
|
||||
_logger.Warn("Could not get oHistoryID in AddToEmailQueueMSSQL!!")
|
||||
End If
|
||||
Catch ex As Exception
|
||||
_logger.Error(ex)
|
||||
End Try
|
||||
End Sub
|
||||
|
||||
Public Function GetEmailDataForMessageId(MessageId As String) As EmailData
|
||||
Dim oSQL = $"SELECT EMAIL_FROM, EMAIL_SUBJECT, EMAIL_ATTMT1 FROM TBEDM_EMAIL_PROFILER_HISTORY WHERE EMAIL_MSGID = '{MessageId}'"
|
||||
Try
|
||||
Dim oDatatable = _firebird.GetDatatable(oSQL)
|
||||
Dim oRow As DataRow
|
||||
Public Function GetEmailDataForMessageId(MessageId As String) As EmailData
|
||||
Dim oSQL = $"SELECT EMAIL_FROM, EMAIL_SUBJECT FROM TBEMLP_HISTORY WHERE EMAIL_MSGID = '{MessageId}'"
|
||||
Try
|
||||
Dim oDatatable = _mssql.GetDatatable(oSQL)
|
||||
Dim oRow As DataRow
|
||||
|
||||
If oDatatable.Rows.Count = 0 Then
|
||||
_logger.Warn("Got no results for MessageId {0}", MessageId)
|
||||
If oDatatable.Rows.Count = 0 Then
|
||||
_logger.Warn("Got no results for MessageId {0}", MessageId)
|
||||
Return Nothing
|
||||
ElseIf oDatatable.Rows.Count > 1 Then
|
||||
_logger.Warn("Got too many results for MessageId {0}. Using last row.", MessageId)
|
||||
End If
|
||||
|
||||
_logger.Debug("Got Email Data for FileId {0}", MessageId)
|
||||
oRow = oDatatable.Rows.Item(oDatatable.Rows.Count - 1)
|
||||
|
||||
Dim oFromDefault = String.Format("No Sender found for ({0})", MessageId)
|
||||
Dim oFrom = oRow.ItemEx("EMAIL_FROM", oFromDefault)
|
||||
|
||||
Dim oSubjectDefault = String.Format("No Subject found for ({0})", MessageId)
|
||||
Dim oSubject = oRow.ItemEx("EMAIL_SUBJECT", oSubjectDefault)
|
||||
|
||||
_logger.Info("Email Data for [{0}] fetched!", MessageId)
|
||||
Return New EmailData() With {
|
||||
.From = oFrom,
|
||||
.Subject = oSubject
|
||||
}
|
||||
|
||||
Catch ex As Exception
|
||||
_logger.Warn("Could not fetch Email Data for FileId {0}", MessageId)
|
||||
Return Nothing
|
||||
ElseIf oDatatable.Rows.Count > 1 Then
|
||||
_logger.Warn("Got too many results for MessageId {0}. Using last row.", MessageId)
|
||||
End Try
|
||||
End Function
|
||||
|
||||
Public Function GetOriginalEmailPath(OriginalEmailDirectory As String, MessageId As String) As String
|
||||
Dim oAttachmentFile = MessageId & ".eml"
|
||||
Dim oAttachmentPath = Path.Combine(OriginalEmailDirectory, oAttachmentFile)
|
||||
|
||||
If File.Exists(oAttachmentPath) Then
|
||||
Return oAttachmentPath
|
||||
Else
|
||||
_logger.Warn("Email File {0} does not exist. Empty String will be returned.", oAttachmentPath)
|
||||
Return String.Empty
|
||||
End If
|
||||
End Function
|
||||
|
||||
Private Function RandomValue(lowerBound As Integer, upperBound As Integer) As Integer
|
||||
Dim oRandomValue = CInt(Math.Floor((upperBound - lowerBound + 1) * Rnd())) + lowerBound
|
||||
Return oRandomValue
|
||||
End Function
|
||||
|
||||
Public Function CreateBodyForMissingProperties(OriginalFilename As String, MissingProperties As List(Of MissingProperty)) As String
|
||||
Dim oBody = String.Format(EmailStrings.EMAIL_MISSINGPROPERTIES_1, OriginalFilename)
|
||||
|
||||
If MissingProperties.Count > 0 Then
|
||||
oBody &= $"{vbNewLine}{vbNewLine}"
|
||||
oBody &= EmailStrings.EMAIL_MISSINGPROPERTIES_2
|
||||
oBody &= $"{vbNewLine}{vbNewLine}"
|
||||
|
||||
For Each prop In MissingProperties
|
||||
oBody &= $"- {prop.Description}"
|
||||
Next
|
||||
End If
|
||||
|
||||
_logger.Debug("Got Email Data for FileId {0}", MessageId)
|
||||
oRow = oDatatable.Rows.Item(oDatatable.Rows.Count - 1)
|
||||
Return oBody
|
||||
End Function
|
||||
|
||||
Dim oFromDefault = String.Format("No Sender found for ({0})", MessageId)
|
||||
Dim oFrom = oRow.ItemEx("EMAIL_FROM", oFromDefault)
|
||||
Public Function CreateBodyForUnhandledException(MessageId As String, Exception As Exception) As String
|
||||
Dim oBody = String.Format(EmailStrings.EMAIL_UNHANDLED_EXCEPTION, MessageId, Exception.Message, Exception.StackTrace)
|
||||
|
||||
Dim oAttachmentDefault = String.Format("No Attachment found for ({0})", MessageId)
|
||||
Dim oAttachment = oRow.ItemEx("EMAIL_ATTMT1", oAttachmentDefault)
|
||||
|
||||
Dim oSubjectDefault = String.Format("No Subject found for ({0})", MessageId)
|
||||
Dim oSubject = oRow.ItemEx("EMAIL_SUBJECT", oSubjectDefault)
|
||||
|
||||
Return New EmailData() With {
|
||||
.From = oFrom,
|
||||
.Attachment = oAttachment,
|
||||
.Subject = oSubject
|
||||
}
|
||||
Catch ex As Exception
|
||||
_logger.Warn("Could not fetch Email Data for FileId {0}", MessageId)
|
||||
Return Nothing
|
||||
End Try
|
||||
End Function
|
||||
|
||||
Public Function GetOriginalEmailPath(OriginalEmailDirectory As String, MessageId As String) As String
|
||||
Dim oAttachmentDirectory = OriginalEmailDirectory
|
||||
Dim oAttachmentFile = MessageId & ".eml"
|
||||
Dim oAttachmentPath = Path.Combine(oAttachmentDirectory, oAttachmentFile)
|
||||
|
||||
If File.Exists(oAttachmentPath) Then
|
||||
Return oAttachmentPath
|
||||
Else
|
||||
_logger.Warn("Email File {0} does not exist. Empty String will be returned.", oAttachmentPath)
|
||||
Return String.Empty
|
||||
End If
|
||||
End Function
|
||||
|
||||
Public Function GetEmailPathWithSubjectAsName(RejectedEmailDirectory As String, UncleanedSubject As String) As String
|
||||
Dim oCleanSubject = String.Join("", UncleanedSubject.Split(Path.GetInvalidPathChars()))
|
||||
Dim oAttachmentDirectory = RejectedEmailDirectory
|
||||
Dim oAttachmentFile = oCleanSubject & ".eml"
|
||||
Dim oAttachmentPath = Path.Combine(oAttachmentDirectory, oAttachmentFile)
|
||||
|
||||
Return oAttachmentPath
|
||||
End Function
|
||||
|
||||
Private Function RandomValue(lowerBound As Integer, upperBound As Integer) As Integer
|
||||
Dim oRandomValue = CInt(Math.Floor((upperBound - lowerBound + 1) * Rnd())) + lowerBound
|
||||
Return oRandomValue
|
||||
End Function
|
||||
End Class
|
||||
Return oBody
|
||||
End Function
|
||||
End Class
|
||||
End Namespace
|
||||
|
||||
@@ -3,31 +3,40 @@
|
||||
Public Const EMAIL_WRAPPING_TEXT = "<html><body style=''font-family:""Arial"";font-size:10.0pt''>Sehr geehrte Damen und Herren,<br/><br/>
|
||||
das @NAME_ZUGFERD_PORTAL zur Verarbeitung der Eingangsrechnungen im ZUGFeRD-Format konnte die von Ihnen gesandte Rechnung
|
||||
leider nicht verarbeiten! <br><br> Grund: {0}<p>Bitte prüfen Sie die Datei und nehmen Sie bei Bedarf mit uns Kontakt auf.<p>
|
||||
Vielen Dank für Ihr Verständnis.<br>Mit freundlichen Grüßen<br>Ihre IT-Abteilung</body></html>"
|
||||
Vielen Dank für Ihr Verständnis.<br>Mit freundlichen Grüßen<br>Ihre WISAG</body></html>"
|
||||
Public Const EMAIL_SUBJECT_TEXT = "<p>Der Betreff der Original-Email war: <em>{0}</em></p>"
|
||||
|
||||
Public Const EMAIL_SUBJECT_REJECTED = "@NAME_ZUGFERD_PORTAL: Beleg abgelehnt"
|
||||
Public Const EMAIL_SUBJECT_EXCEPTION = "@NAME_ZUGFERD_PORTAL: Unbehandelte Ausnahme"
|
||||
|
||||
' OutOfMemoryException = 20009
|
||||
' UnhandledException = 20010
|
||||
' FileMoveException = 200011
|
||||
Public Const EMAIL_UNHANDLED_EXCEPTION = """
|
||||
<p>Beim Verarbeiten der Datei mit der Message ID '{0}' ist ein schwerer Fehler aufgetreten.</p>
|
||||
<p>Fehlerbeschreibung: {1}</p>
|
||||
<pre>{2}</pre>
|
||||
"""
|
||||
|
||||
' MissingValueException = 20007
|
||||
Public Const EMAIL_MISSINGPROPERTIES_1 = "<p>Die angehängte Datei entspricht nicht dem WISAG ZUGFeRD-Format: {0}</p>"
|
||||
Public Const EMAIL_MISSINGPROPERTIES_2 = "<p>Die folgenden Eigenschaften wurden als ERFORDERLICH eingestuft, wurden aber nicht gefunden:<p/>"
|
||||
Public Const EMAIL_MISSINGPROPERTIES_2 = "<p>Die folgenden Eigenschaften wurden als ERFORDERLICH eingestuft, wurden aber nicht gefunden:</p>"
|
||||
|
||||
Public Const EMAIL_MD5_ERROR = "<p>Die von Ihnen gesendete Rechnung wurde bereits von unserem System verarbeitet.</p>"
|
||||
' MD5HashException = 20002
|
||||
Public Const EMAIL_MD5_ERROR = "<p>Die von Ihnen gesendete Rechnung ({0}) wurde bereits von unserem System verarbeitet.</p>"
|
||||
|
||||
' ValidationException = 20001
|
||||
Public Const EMAIL_VALIDATION_ERROR = "
|
||||
<p>Die von Ihnen gesendete Rechnung hat die ZUGFeRD Validierung nicht bestanden.</p>
|
||||
<p>Die folgenden Felder sind nicht korrekt:<ul>{0}</ul></p>"
|
||||
|
||||
Public Const EMAIL_TOO_MUCH_FERDS = "<p>In Ihrer Email ({0}) sind mehr als ein ZUGFeRD Dokument enthalten. Bitte prüfen Sie Rechnung an Anhänge. Nur eine Rechnung darf das ZUGFeRD-Format enthalten</p>"
|
||||
' TooMuchFerdsException = 20005
|
||||
Public Const EMAIL_TOO_MUCH_FERDS = "<p>In Ihrer Email ({0}) sind mehr als ein ZUGFeRD Dokument enthalten. Bitte prüfen Sie die Rechnungsanhänge. Nur eine Rechnung darf das ZUGFeRD-Format enthalten.</p>"
|
||||
|
||||
' NoFerdsException = 20006
|
||||
Public Const EMAIL_NO_FERDS = "<p>Ihre Email ({0}) enthielt keine ZUGFeRD-Dokumente.</p>"
|
||||
|
||||
' FileSizeLimitReachedException = 20008
|
||||
Public Const EMAIL_FILE_SIZE_REACHED = "
|
||||
<p>Die von Ihnen gesendete Rechnung oder einer der Rechnungs-Anhänge überschreitet die erlaubte Größe von <strong>{0} MB</strong>.</p>
|
||||
<p>Die folgende Datei hat die erlaubte Größe überschritten:<ul>
|
||||
@@ -35,14 +44,23 @@
|
||||
</ul></p>
|
||||
"
|
||||
|
||||
' InvalidFerdException = 20004
|
||||
Public Const EMAIL_INVALID_DOCUMENT = "
|
||||
<p>Ihre Email ({0}) enthielt ein ZUGFeRD Dokument, welches aber inkorrekt formatiert wurde.</p>
|
||||
<p>Mögliche Gründe für ein inkorrektes Format:<ul>
|
||||
<li>Betrags-Werte weisen ungültiges Format auf (z.B. 25,01 anstatt 25.01)</li>
|
||||
<p>Mögliche Gründe für ein inkorrektes Format sind:<ul>
|
||||
<li>Betragswerte weisen ein ungültiges Format auf (z.B. 25,01 anstatt 25.01)</li>
|
||||
<li>Eins der folgenden Zeichen wird nicht XML-codiert verwendet: &, <, > oder ".</li>
|
||||
</ul></p>
|
||||
"
|
||||
|
||||
' UnsupportedFerdException = 20003
|
||||
Public Const EMAIL_UNSUPPORTED_DOCUMENT = "
|
||||
<p>Ihre Email ({0}) enthielt ein ZUGFeRD Format ({1}), welches zur Zeit noch nicht freigeschaltet ist.</p>
|
||||
"
|
||||
|
||||
''' <summary>
|
||||
''' Präfix für den verwendeten ErrorCode
|
||||
''' Beispiel: ZUGFERD_Rejection_20001
|
||||
''' </summary>
|
||||
Public Const ErrorCodePraefix = "ZUGFERD_Rejection_"
|
||||
End Class
|
||||
|
||||
14
Jobs/ZUGFeRD/ErrorCode.vb
Normal file
14
Jobs/ZUGFeRD/ErrorCode.vb
Normal file
@@ -0,0 +1,14 @@
|
||||
Public Enum ErrorCode
|
||||
Unknown = 0
|
||||
ValidationException = 20001
|
||||
MD5HashException = 20002
|
||||
UnsupportedFerdException = 20003
|
||||
InvalidFerdException = 20004
|
||||
TooMuchFerdsException = 20005
|
||||
NoFerdsException = 20006
|
||||
MissingValueException = 20007
|
||||
FileSizeLimitReachedException = 20008
|
||||
OutOfMemoryException = 20009
|
||||
UnhandledException = 20010
|
||||
FileMoveException = 200011
|
||||
End Enum
|
||||
223
Jobs/ZUGFeRD/FileFunctions.vb
Normal file
223
Jobs/ZUGFeRD/FileFunctions.vb
Normal file
@@ -0,0 +1,223 @@
|
||||
Imports System.Collections.Generic
|
||||
Imports System.IO
|
||||
Imports System.Linq
|
||||
Imports DigitalData.Modules.Base
|
||||
Imports DigitalData.Modules.Database
|
||||
Imports DigitalData.Modules.Interfaces
|
||||
Imports DigitalData.Modules.Logging
|
||||
|
||||
Namespace ZUGFeRD
|
||||
Public Class FileFunctions
|
||||
Private ReadOnly _logConfig As LogConfig
|
||||
Private ReadOnly _logger As Logger
|
||||
Private ReadOnly _filesystem As FilesystemEx
|
||||
Private ReadOnly _email As ZUGFeRD.EmailFunctions
|
||||
|
||||
Public Sub New(pLogConfig As LogConfig, pMSSQL As MSSQLServer)
|
||||
_logConfig = pLogConfig
|
||||
_logger = _logConfig.GetLogger()
|
||||
_email = New EmailFunctions(pLogConfig, pMSSQL)
|
||||
_filesystem = New FilesystemEx(pLogConfig)
|
||||
End Sub
|
||||
|
||||
Public Function CheckFileAge(oFiles As List(Of FileInfo), pMinFileAge As Integer)
|
||||
Return oFiles.Where(Function(f) Now.Subtract(f.CreationTime).Minutes < pMinFileAge).Any()
|
||||
End Function
|
||||
|
||||
Public Sub MoveFiles(
|
||||
pArgs As WorkerArgs,
|
||||
pMessageId As String,
|
||||
pFiles As List(Of FileInfo),
|
||||
pAttachmentFiles As List(Of FileInfo),
|
||||
pEmbeddedAttachments As List(Of PDFEmbeds.EmbeddedFile),
|
||||
pMoveDirectory As String,
|
||||
pIsSuccess As Boolean)
|
||||
|
||||
Dim oFinalMoveDirectory As String = pMoveDirectory
|
||||
Dim oDateSubDirectoryName As String = Now.ToString("yyyy\\MM\\dd")
|
||||
Dim oAttachmentDirectory As String = Path.Combine(oFinalMoveDirectory, pArgs.AttachmentsSubDirectory, oDateSubDirectoryName)
|
||||
|
||||
' Files will be moved to a subfolder for the current day if they are rejected
|
||||
If Not pIsSuccess Then
|
||||
oFinalMoveDirectory = Path.Combine(oFinalMoveDirectory, oDateSubDirectoryName)
|
||||
End If
|
||||
|
||||
' Create directories if they don't exist
|
||||
If Not Directory.Exists(oFinalMoveDirectory) Then
|
||||
Try
|
||||
Directory.CreateDirectory(oFinalMoveDirectory)
|
||||
Catch ex As Exception
|
||||
_logger.Error(ex)
|
||||
End Try
|
||||
End If
|
||||
|
||||
If Not Directory.Exists(oAttachmentDirectory) And pAttachmentFiles.Count > 0 Then
|
||||
Try
|
||||
Directory.CreateDirectory(oAttachmentDirectory)
|
||||
Catch ex As Exception
|
||||
_logger.Error(ex)
|
||||
End Try
|
||||
End If
|
||||
|
||||
' Filter out Attachments from `Files`
|
||||
Dim oInvoiceFiles As List(Of FileInfo) = pFiles.Except(pAttachmentFiles).ToList()
|
||||
|
||||
' Move PDF/A Files
|
||||
For Each oFile In oInvoiceFiles
|
||||
Try
|
||||
Dim oFilePath = _filesystem.GetVersionedFilename(Path.Combine(oFinalMoveDirectory, oFile.Name))
|
||||
|
||||
_filesystem.MoveTo(oFile.FullName, oFilePath, oFinalMoveDirectory)
|
||||
|
||||
_logger.Info("File moved to {0}", oFilePath)
|
||||
Catch ex As Exception
|
||||
_logger.Warn("Could not move file {0}", oFile.FullName)
|
||||
_logger.Error(ex)
|
||||
End Try
|
||||
Next
|
||||
|
||||
' Move non-PDF/A Email Attachments/Files
|
||||
For Each oFile In pAttachmentFiles
|
||||
Try
|
||||
Dim oFilePath = _filesystem.GetVersionedFilename(Path.Combine(oAttachmentDirectory, oFile.Name))
|
||||
_filesystem.MoveTo(oFile.FullName, oFilePath, oAttachmentDirectory)
|
||||
_logger.Info("Attachment moved to {0}", oFilePath)
|
||||
Catch ex As Exception
|
||||
_logger.Warn("Could not move attachment {0}", oFile.FullName)
|
||||
_logger.Error(ex)
|
||||
End Try
|
||||
Next
|
||||
|
||||
' Write Embedded Files to disk
|
||||
For Each oResult In pEmbeddedAttachments
|
||||
Try
|
||||
Dim oFileName As String = $"{pMessageId}~{oResult.FileName}"
|
||||
Dim oFilePath As String = Path.Combine(oAttachmentDirectory, oFileName)
|
||||
|
||||
If Not File.Exists(oAttachmentDirectory) Then
|
||||
Directory.CreateDirectory(oAttachmentDirectory)
|
||||
End If
|
||||
System.IO.File.WriteAllBytes(oFilePath, oResult.FileContents)
|
||||
If CheckBytes(oFilePath, oResult.FileContents) = True Then
|
||||
If FileOpenwithError(oFilePath) Then
|
||||
_logger.Info("Embedded Attachment moved to {0}", oFilePath)
|
||||
Else
|
||||
_logger.Info("File is corrupt. Deleting the created file ...")
|
||||
File.Delete(oFilePath)
|
||||
End If
|
||||
Else
|
||||
_logger.Info("File is corrupt (CheckBytes). Deleting the created file ...")
|
||||
File.Delete(oFilePath)
|
||||
End If
|
||||
'Using oWriter As New FileStream(oFilePath, FileMode.Create)
|
||||
' oWriter.Write(oResult.FileContents, 0, oResult.FileContents.Length)
|
||||
|
||||
'End Using
|
||||
Catch ex As Exception
|
||||
_logger.Warn("Could not save embedded attachment {0}", oResult.FileName)
|
||||
_logger.Error(ex)
|
||||
End Try
|
||||
Next
|
||||
|
||||
_logger.Info("Finished moving files")
|
||||
End Sub
|
||||
Private Function CheckBytes(oFilePath As String, oFileContents As IEnumerable(Of Byte)) As Boolean
|
||||
Dim savedBytes() As Byte = System.IO.File.ReadAllBytes(oFilePath)
|
||||
|
||||
If savedBytes.SequenceEqual(oFileContents) Then
|
||||
Return True
|
||||
Else
|
||||
Return False
|
||||
End If
|
||||
End Function
|
||||
Public Function MoveAndRenameEmailToRejected(pArgs As WorkerArgs, pMessageId As String) As EmailData
|
||||
_logger.Info("Moving Mail with MessageId [{0}] to Rejected folder", pMessageId)
|
||||
_logger.Debug("Fetching Email Data")
|
||||
|
||||
Dim oEmailData = _email.GetEmailDataForMessageId(pMessageId)
|
||||
_logger.Debug("Email Data fetched!")
|
||||
|
||||
Dim oSource = _email.GetOriginalEmailPath(pArgs.OriginalEmailDirectory, pMessageId)
|
||||
_logger.Debug("Original email path: [{0}]", oSource)
|
||||
|
||||
If oSource = String.Empty Then
|
||||
_logger.Warn("Original Email for [{0}] could not be found. Exiting.", pMessageId)
|
||||
Return New EmailData()
|
||||
End If
|
||||
|
||||
Dim oDateSubDirectoryName As String = Now.ToString("yyyy-MM-dd")
|
||||
Dim oDestination As String
|
||||
|
||||
Dim oRejectedDirectory As String = Path.Combine(pArgs.RejectedEmailDirectory, oDateSubDirectoryName)
|
||||
|
||||
' Create the destination directory if it does not exist
|
||||
_logger.Debug("Creating destination directory [{0}]", oRejectedDirectory)
|
||||
If Not Directory.Exists(oRejectedDirectory) Then
|
||||
Try
|
||||
Directory.CreateDirectory(oRejectedDirectory)
|
||||
Catch ex As Exception
|
||||
_logger.Error(ex)
|
||||
End Try
|
||||
End If
|
||||
|
||||
' If oEmailData is Nothing, TBEDM_EMAIL_PROFILER_HISTORY for MessageId was not found.
|
||||
' This only should happen when testing and db-tables are deleted frequently
|
||||
If oEmailData Is Nothing Then
|
||||
oDestination = GetEmailPathWithSubjectAsName(oRejectedDirectory, pMessageId)
|
||||
Else
|
||||
oDestination = GetEmailPathWithSubjectAsName(oRejectedDirectory, StringEx.ConvertTextToSlug(oEmailData.Subject))
|
||||
End If
|
||||
|
||||
_logger.Debug("Destination for eml file is {0}", oDestination)
|
||||
|
||||
Dim oFinalFileName = _filesystem.GetVersionedFilename(oDestination)
|
||||
|
||||
_logger.Debug("Versioned filename for eml file is {0}", oFinalFileName)
|
||||
|
||||
If oEmailData Is Nothing Then
|
||||
_logger.Warn("Could not get Email Data from Database. File {0} will not be moved!", oSource)
|
||||
Return New EmailData()
|
||||
End If
|
||||
|
||||
'---------------------------
|
||||
|
||||
Try
|
||||
_logger.Info("Moving email from {0} to {1}", oSource, oFinalFileName)
|
||||
File.Move(oSource, oFinalFileName)
|
||||
oEmailData.Attachment = oFinalFileName
|
||||
Catch ex As Exception
|
||||
_logger.Warn("File {0} could not be moved! Original Filename will be used!", oSource)
|
||||
_logger.Error(ex)
|
||||
oEmailData.Attachment = oSource
|
||||
End Try
|
||||
|
||||
_logger.Info("Email [{0}] moved to rejected folder!", pMessageId)
|
||||
|
||||
Return oEmailData
|
||||
End Function
|
||||
Private Function FileOpenwithError(pFilePath As String) As Boolean
|
||||
Try
|
||||
Using fs As FileStream = File.Open(pFilePath, FileMode.Open, FileAccess.Read, FileShare.None)
|
||||
Return True ' Datei kann geöffnet werden
|
||||
End Using
|
||||
Catch ex As IOException
|
||||
_logger.Info("file [{0}] could not be opened! Error IOException: [{1}]", pFilePath, ex.Message)
|
||||
Return False ' Datei ist gesperrt oder existiert nicht
|
||||
Catch ex As Exception
|
||||
_logger.Info("file [{0}] could not be opened! Error: [{1}]", pFilePath, ex.Message)
|
||||
Return False ' Andere Fehler
|
||||
End Try
|
||||
End Function
|
||||
Public Function GetEmailPathWithSubjectAsName(RejectedEmailDirectory As String, UncleanedSubject As String) As String
|
||||
Dim oCleanSubject = String.Join("", UncleanedSubject.Split(Path.GetInvalidPathChars()))
|
||||
Dim oAttachmentDirectory = RejectedEmailDirectory
|
||||
Dim oAttachmentFile = oCleanSubject & ".eml"
|
||||
_logger.Debug("Email Filename is [{0}]", oAttachmentFile)
|
||||
|
||||
Dim oAttachmentPath = Path.Combine(oAttachmentDirectory, oAttachmentFile)
|
||||
|
||||
Return oAttachmentPath
|
||||
End Function
|
||||
End Class
|
||||
|
||||
End Namespace
|
||||
122
Jobs/ZUGFeRD/HashFunctions.vb
Normal file
122
Jobs/ZUGFeRD/HashFunctions.vb
Normal file
@@ -0,0 +1,122 @@
|
||||
Imports DigitalData.Modules.Base
|
||||
Imports DigitalData.Modules.Database
|
||||
Imports DigitalData.Modules.Jobs.Exceptions
|
||||
Imports DigitalData.Modules.Logging
|
||||
Imports System.Data
|
||||
Imports System.IO
|
||||
Imports System.Security.Cryptography
|
||||
|
||||
Public Class HashFunctions
|
||||
Inherits BaseClass
|
||||
|
||||
Private ReadOnly Database As MSSQLServer
|
||||
|
||||
Public Sub New(pLogConfig As LogConfig, pDatabase As MSSQLServer)
|
||||
MyBase.New(pLogConfig)
|
||||
Database = pDatabase
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' Generates the MD5 Checksum of a file and checks it against the histroy table TBEDM_ZUGFERD_HISTORY_IN
|
||||
''' </summary>
|
||||
''' <param name="pFilePath">The path of the file to be checked</param>
|
||||
''' <param name="pIgnoreRejectionStatus">Should the check take into account the rejection status of the file?</param>
|
||||
''' <returns>The MD5 Checksum of the file, or an empty string, if the Checksum could not be created</returns>
|
||||
''' <exception cref="MD5HashException">Throws, when the file should be rejected, ie. if it already exists in the table</exception>
|
||||
Public Function GenerateAndCheck_MD5Sum(pFile As FileInfo, pMessageId As String, pIgnoreRejectionStatus As Boolean) As String
|
||||
Dim oMD5CheckSum = CreateMD5(pFile.FullName)
|
||||
|
||||
' Exit if MD5 could not be created
|
||||
If oMD5CheckSum = String.Empty Then
|
||||
Logger.Warn("MD5 Checksum is nothing for file [{0}]!", pFile.FullName)
|
||||
Return oMD5CheckSum
|
||||
End If
|
||||
|
||||
' Check if Checksum exists in History Table
|
||||
Dim oCheckCommand = $"SELECT * FROM TBEMLP_HISTORY WHERE GUID = (SELECT MAX(GUID) FROM TBEMLP_HISTORY WHERE UPPER(MD5HASH) = UPPER('{oMD5CheckSum}'))"
|
||||
Dim oTable As DataTable = Database.GetDatatable(oCheckCommand, MSSQLServer.TransactionMode.NoTransaction)
|
||||
|
||||
' If History entries could not be fetched, just return the MD5 Checksum
|
||||
If IsNothing(oTable) Then
|
||||
Logger.Warn("Be careful: oExistsDT is nothing for file [{0}]!", pFile.FullName)
|
||||
Return oMD5CheckSum
|
||||
End If
|
||||
|
||||
' If Checksum does not exist in History entries, just return the MD5 Checksum
|
||||
If oTable.Rows.Count = 0 Then
|
||||
Logger.Debug("File [{0}] was not found in History!", pFile.FullName)
|
||||
Return oMD5CheckSum
|
||||
End If
|
||||
|
||||
' ====================================================
|
||||
' Checksum exists in History entries, reject!
|
||||
' ====================================================
|
||||
|
||||
Dim oRejected As Boolean
|
||||
Dim oHistoryId As Integer
|
||||
|
||||
' Try to read Rejected Status and History Id
|
||||
Try
|
||||
Dim oRow As DataRow = oTable.Rows.Item(0)
|
||||
oRejected = oRow.ItemEx("CUST_REJECTED", False)
|
||||
oHistoryId = oRow.Item("GUID")
|
||||
|
||||
Catch ex As Exception
|
||||
Logger.Warn("Error while converting REJECTED: " & ex.Message)
|
||||
oRejected = False
|
||||
|
||||
End Try
|
||||
|
||||
Dim oOriginalName As Object = GetOriginalFilename(pFile.Name)
|
||||
Logger.Info("File with MessageId [{0}] and Filename [{1}] has already been processed.", pMessageId, oOriginalName)
|
||||
|
||||
' If the file was already rejected, it is allowed to be processed again,
|
||||
' even if the Checksum exists in the history entries (default case)
|
||||
' Which means, if it was not rejected before, it will be rejected in any case!
|
||||
'
|
||||
' This logic can be overwritten by the IgnoreRejectionStatus parameter.
|
||||
' If it is set to true, the file will be rejected if the file exists in the history entries,
|
||||
' regardless of the rejected parameter.
|
||||
|
||||
If oRejected = True And pIgnoreRejectionStatus = True Then
|
||||
Logger.Info("ZuGFeRDFile already has been processed, but Rejection Status will be ignored!")
|
||||
ElseIf oRejected = False Then
|
||||
Logger.Info("ZuGFeRDFile already has been processed. Will be rejected.")
|
||||
Throw New MD5HashException($"There is already an identical invoice! - HistoryID [{oHistoryId}] - Case 1", oOriginalName)
|
||||
Else
|
||||
Logger.Info("ZuGFeRDFile already has been processed. Will be rejected.")
|
||||
Throw New MD5HashException($"There is already an identical invoice! - HistoryID [{oHistoryId}] - Case 2", oOriginalName)
|
||||
End If
|
||||
|
||||
Return oMD5CheckSum
|
||||
End Function
|
||||
|
||||
Public Function GetOriginalFilename(pFilename As String) As String
|
||||
' Try to get the original filename from Attachment table
|
||||
' If this fails, falls back to the new filename (<msgid>~Attm<i>.ext)
|
||||
Dim oSQL = $"SELECT EMAIL_ATTMT FROM TBEMLP_HISTORY_ATTACHMENT WHERE EMAIL_ATTMT_INDEX = '{pFilename}'"
|
||||
Dim oEmailAttachment = Database.GetScalarValue(oSQL, MSSQLServer.TransactionMode.NoTransaction)
|
||||
Dim oOriginalName = ObjectEx.NotNull(oEmailAttachment, pFilename)
|
||||
Return oOriginalName
|
||||
End Function
|
||||
|
||||
Private Function CreateMD5(pFilename As String) As String
|
||||
Try
|
||||
Dim oMD5 As New MD5CryptoServiceProvider
|
||||
Dim oHash As Byte()
|
||||
Dim oHashString As String
|
||||
Dim oResult As String = ""
|
||||
|
||||
Using oFileStream As New FileStream(pFilename, FileMode.Open, FileAccess.Read, FileShare.Read, 8192)
|
||||
oHash = oMD5.ComputeHash(oFileStream)
|
||||
oHashString = BitConverter.ToString(oHash)
|
||||
End Using
|
||||
|
||||
oResult = oHashString.Replace("-", "")
|
||||
Return oResult
|
||||
Catch ex As Exception
|
||||
Logger.Error(ex)
|
||||
Return ""
|
||||
End Try
|
||||
End Function
|
||||
End Class
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user