Projektdateien hinzufügen.
This commit is contained in:
parent
94e28499ef
commit
edb5dca10d
25
FileInterface.sln
Normal file
25
FileInterface.sln
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.0.31912.275
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileInterface", "FileInterface\FileInterface.csproj", "{1DCDC78F-3042-44C5-91CC-1AFB1C752386}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{1DCDC78F-3042-44C5-91CC-1AFB1C752386}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{1DCDC78F-3042-44C5-91CC-1AFB1C752386}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{1DCDC78F-3042-44C5-91CC-1AFB1C752386}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{1DCDC78F-3042-44C5-91CC-1AFB1C752386}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {F96FA68E-090C-49D8-A249-4452537D06C3}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
42
FileInterface/App.config
Normal file
42
FileInterface/App.config
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<configuration>
|
||||||
|
<startup>
|
||||||
|
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
|
||||||
|
</startup>
|
||||||
|
<appSettings>
|
||||||
|
<add key="AppID" value="Testclient" />
|
||||||
|
<add key="StationNr" value="1017VFE010100110" />
|
||||||
|
<add key="Server_URL" value="http://ksbrose:8080/mes" />
|
||||||
|
<add key="CF_Name" value="HUF.MachineIN" /> <!--initiale CF, wird für INterface benötigt-->
|
||||||
|
<add key="ClientNO" value="01" /> <!--Grundeinstellung-->
|
||||||
|
<add key="SourcePath" value="c:\test" /> <!--Einlesepathder Dateien-->
|
||||||
|
<add key="Destination" value="c:\temp" /> <!--Ausgabepfad, nach verarbeiung, erschieben der zu verarbeitende Datei in ordner-->
|
||||||
|
<add key="Designator" value="#" /> <!--Trenner,für Zeilenumbruch, splitten in Javacscrt dann möglich um aus String wieder Zeilen zu erhaltem-->
|
||||||
|
<add key="Filetyp" value="*.csv" />
|
||||||
|
<add key="Wait" value="5000" /> <!--Wartezyklus für Polling, Interface reagiert auf Event. Falls durch störung Events verloren gehen, holt der Timer diese Dateien ab -->
|
||||||
|
<add key="FileStamp_older_in_Minutes" value="3" /> <!--Timer holt dateien ab, Zeitstempel älter als 3 Minuten, da sonst der Eventhandler zusammen mit Timer versucht die Datei zu parsen -->
|
||||||
|
<add key="MODE" value="0" /> <!--MODE Füe CF, steuernde Wirkung auf CF-->
|
||||||
|
<add key="PANEL_MODE" value="0" /> <!--MODE Füe CF, steuernde Wirkung auf CF-->
|
||||||
|
<add key="Resultfile" value="false" /> <!--Antworfile aus cf false, keine Antwort. oder Pfadangabe c:\result. 2 Outargs nötig, Outarg[0]= Dateiname, Outarg[1]= inhalt als string-->
|
||||||
|
<add key="Logfilesize" value="10" />
|
||||||
|
<add key="Loginfo" value="error" />
|
||||||
|
<add key="PROCESS_FILES_PATH" value="false" /> <!--Separater Pfad (false oder c:\prozessfiepfad)für timer oder event für 2. CF (verarbeiten von Prozessdaten)-->
|
||||||
|
<add key="CF_Processfiles" value="HUF.MachineOUT" /><!--CF für Prozessdaten, 2.Event-->
|
||||||
|
<add key="PROCESS_MODE" value="0" /> <!--MODE Füe CF, steuernde Wirkung auf CF-->
|
||||||
|
<!--Wenn Prozessdaten im gleichen Pfad sind, Datei beginnt mit rcfilename, begnnt mit rc sonst false-->
|
||||||
|
<add key="Check_starts_with" value="false" />
|
||||||
|
|
||||||
|
</appSettings>
|
||||||
|
<system.web>
|
||||||
|
<membership defaultProvider="ClientAuthenticationMembershipProvider">
|
||||||
|
<providers>
|
||||||
|
<add name="ClientAuthenticationMembershipProvider" type="System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" />
|
||||||
|
</providers>
|
||||||
|
</membership>
|
||||||
|
<roleManager defaultProvider="ClientRoleProvider" enabled="true">
|
||||||
|
<providers>
|
||||||
|
<add name="ClientRoleProvider" type="System.Web.ClientServices.Providers.ClientRoleProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" cacheTimeout="86400" />
|
||||||
|
</providers>
|
||||||
|
</roleManager>
|
||||||
|
</system.web>
|
||||||
|
</configuration>
|
||||||
96
FileInterface/CodeFile1.cs
Normal file
96
FileInterface/CodeFile1.cs
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
|
||||||
|
namespace com.itac.mes.imsapi.client.dotnet
|
||||||
|
{
|
||||||
|
class IMSApiDotNetTestclientBase
|
||||||
|
{
|
||||||
|
public const int FILL_WITH_SPACE = 50;
|
||||||
|
|
||||||
|
|
||||||
|
public static String fillWithSpace(String value)
|
||||||
|
{
|
||||||
|
StringBuilder line = new StringBuilder(value);
|
||||||
|
while (line.Length < FILL_WITH_SPACE)
|
||||||
|
{
|
||||||
|
line.Append(' ');
|
||||||
|
}
|
||||||
|
return line.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static MethodInfo dectectMethod(Type testClientClass, String name)
|
||||||
|
{
|
||||||
|
MethodInfo result = null;
|
||||||
|
MethodInfo[] methods = testClientClass.GetMethods();
|
||||||
|
ArrayList hits = new ArrayList();
|
||||||
|
for (int m = 0; m < methods.Length; m++)
|
||||||
|
{
|
||||||
|
if (methods[m].Name.ToLower().StartsWith(("test_" + name).ToLower()))
|
||||||
|
{
|
||||||
|
hits.Add(methods[m]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hits.Count == 0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else if (hits.Count == 1)
|
||||||
|
{
|
||||||
|
result = (MethodInfo)hits[0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int m = 0; m < hits.Count; m++)
|
||||||
|
{
|
||||||
|
Console.Out.WriteLine((m + 1) + ": " + ((MethodInfo)hits[m]).Name.Substring(5));
|
||||||
|
}
|
||||||
|
Console.Out.WriteLine("Choose index of function <1-" + hits.Count + ">: ");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int index = Int32.Parse(getInput());
|
||||||
|
if (index > 0 && index <= hits.Count)
|
||||||
|
{
|
||||||
|
result = (MethodInfo)hits[index - 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (FormatException fe)
|
||||||
|
{
|
||||||
|
Console.Out.WriteLine("Invalid input.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getInput()
|
||||||
|
{
|
||||||
|
return Console.ReadLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getInputNoEcho()
|
||||||
|
{
|
||||||
|
StringBuilder line = new StringBuilder();
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
ConsoleKeyInfo info = Console.ReadKey(true);
|
||||||
|
if (info.Key == ConsoleKey.Enter)
|
||||||
|
{
|
||||||
|
Console.Out.WriteLine();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (info.Key == ConsoleKey.Backspace)
|
||||||
|
{
|
||||||
|
line.Remove(line.Length - 1, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
line.Append(info.KeyChar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return line.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
94
FileInterface/FileInterface.csproj
Normal file
94
FileInterface/FileInterface.csproj
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{1DCDC78F-3042-44C5-91CC-1AFB1C752386}</ProjectGuid>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<RootNamespace>FileInterface</RootNamespace>
|
||||||
|
<AssemblyName>FileInterface</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||||
|
<Deterministic>true</Deterministic>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<Prefer32Bit>false</Prefer32Bit>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="IMSApiDotNet">
|
||||||
|
<HintPath>..\..\..\..\..\..\test\imsapi-dotnet-9.20.00-24-net4\IMSApiDotNet.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="System" />
|
||||||
|
<Reference Include="System.Configuration" />
|
||||||
|
<Reference Include="System.Configuration.ConfigurationManager, Version=6.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\System.Configuration.ConfigurationManager.6.0.0\lib\net461\System.Configuration.ConfigurationManager.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Data.OracleClient" />
|
||||||
|
<Reference Include="System.Net" />
|
||||||
|
<Reference Include="System.Security" />
|
||||||
|
<Reference Include="System.Security.AccessControl, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\System.Security.AccessControl.6.0.0\lib\net461\System.Security.AccessControl.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Security.Permissions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\System.Security.Permissions.6.0.0\lib\net461\System.Security.Permissions.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Security.Principal.Windows, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\System.Security.Principal.Windows.5.0.0\lib\net461\System.Security.Principal.Windows.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.ServiceProcess" />
|
||||||
|
<Reference Include="System.Transactions" />
|
||||||
|
<Reference Include="System.Web.Extensions" />
|
||||||
|
<Reference Include="System.Xml.Linq" />
|
||||||
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
|
<Reference Include="Microsoft.CSharp" />
|
||||||
|
<Reference Include="System.Data" />
|
||||||
|
<Reference Include="System.Net.Http" />
|
||||||
|
<Reference Include="System.Xml" />
|
||||||
|
<Reference Include="WindowsBase" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="CodeFile1.cs" />
|
||||||
|
<Compile Include="OnChangedProcess.cs" />
|
||||||
|
<Compile Include="Program.cs" />
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="Properties\Resources.Designer.cs">
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DesignTime>True</DesignTime>
|
||||||
|
<DependentUpon>Resources.resx</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="App.config" />
|
||||||
|
<None Include="packages.config" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Include="Properties\Resources.resx">
|
||||||
|
<Generator>ResXFileCodeGenerator</Generator>
|
||||||
|
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||||
|
</EmbeddedResource>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
</Project>
|
||||||
74
FileInterface/OnChangedProcess.cs
Normal file
74
FileInterface/OnChangedProcess.cs
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Configuration;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading;
|
||||||
|
using com.itac.mes.imsapi.client.dotnet;
|
||||||
|
|
||||||
|
// Stellen Sie sicher, dass Sie die richtigen Namensräume für Ihre IMSApi-Objekte importieren
|
||||||
|
using com.itac.mes.imsapi.domain;
|
||||||
|
using com.itac.mes.imsapi.domain.container;
|
||||||
|
|
||||||
|
public static class OnChangedProcess
|
||||||
|
{
|
||||||
|
public static void OnChanged(IMSApiSessionContextStruct sessionContext, object source, FileSystemEventArgs e)
|
||||||
|
{
|
||||||
|
string processpath = ConfigurationManager.AppSettings["PROCESS_FILES_PATH"];
|
||||||
|
string designator = ConfigurationManager.AppSettings["Designator"];
|
||||||
|
string mode = "MODE|" + ConfigurationManager.AppSettings["MODE"];
|
||||||
|
string panelmode = "PANEL_MODE|" + ConfigurationManager.AppSettings["PANEL_MODE"];
|
||||||
|
string processmode = "PROCESS_MODE|" + ConfigurationManager.AppSettings["PROCESS_MODE"];
|
||||||
|
string station = "ST|" + ConfigurationManager.AppSettings["StationNr"];
|
||||||
|
|
||||||
|
string filename = e.Name;
|
||||||
|
string filecontentprocess = "";
|
||||||
|
string parameters = "";
|
||||||
|
IIMSApiDotNet imsapi = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Lesen der Datei
|
||||||
|
using (StreamReader r = new StreamReader(e.FullPath))
|
||||||
|
{
|
||||||
|
filecontentprocess = r.ReadToEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zusammenfassen der Dateiinhalte mit Designator
|
||||||
|
List<string> lines = new List<string>(filecontentprocess.Split(new string[] { "\r\n" }, StringSplitOptions.None));
|
||||||
|
parameters = string.Join(designator, lines);
|
||||||
|
|
||||||
|
// Ihre IMSApi-Aufruflogik
|
||||||
|
string[] outargs;
|
||||||
|
string customErrorString;
|
||||||
|
int result = imsapi.customFunction(sessionContext, ConfigurationManager.AppSettings["CF_Processfiles"], new string[] { station, mode, panelmode, processmode, "FILENAME|" + filename, "RAW|" + parameters }, out outargs, out customErrorString);
|
||||||
|
|
||||||
|
// Protokollierung und Dateiverschiebung
|
||||||
|
HandleResultAndMoveFile(result, customErrorString, e.FullPath, processpath, filename);
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Fehler bei der Verarbeitung der Datei {filename}: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void HandleResultAndMoveFile(int result, string customErrorString, string originalFilePath, string destinationPath, string filename)
|
||||||
|
{
|
||||||
|
// Protokollierung
|
||||||
|
LogResult(result, customErrorString);
|
||||||
|
|
||||||
|
// Verschieben der Datei in den processed_done Ordner
|
||||||
|
string newPath = Path.Combine(destinationPath, "processed_done", filename);
|
||||||
|
if (!Directory.Exists(Path.GetDirectoryName(newPath)))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(Path.GetDirectoryName(newPath));
|
||||||
|
}
|
||||||
|
File.Move(originalFilePath, newPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void LogResult(int result, string customErrorString)
|
||||||
|
{
|
||||||
|
// Implementieren Sie Ihre Logik hier
|
||||||
|
}
|
||||||
|
}
|
||||||
754
FileInterface/Program.cs
Normal file
754
FileInterface/Program.cs
Normal file
@ -0,0 +1,754 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.ServiceProcess;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Configuration;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using com.itac.mes.imsapi.client.dotnet;
|
||||||
|
using com.itac.mes.imsapi.domain.container;
|
||||||
|
|
||||||
|
namespace Service
|
||||||
|
{
|
||||||
|
public static class Program
|
||||||
|
{
|
||||||
|
public const string ServiceName = "FileInterface";
|
||||||
|
private static TestClient _testClient;
|
||||||
|
|
||||||
|
public class Service : ServiceBase
|
||||||
|
{
|
||||||
|
public Service()
|
||||||
|
{
|
||||||
|
ServiceName = Program.ServiceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnStart(string[] args)
|
||||||
|
{
|
||||||
|
Program.Start(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnStop()
|
||||||
|
{
|
||||||
|
Program.Stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Main(string[] args)
|
||||||
|
{
|
||||||
|
if (!Environment.UserInteractive)
|
||||||
|
{
|
||||||
|
using (var service = new Service())
|
||||||
|
{
|
||||||
|
ServiceBase.Run(service);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TestClient.DisableQuickEditMode();
|
||||||
|
Start(args);
|
||||||
|
|
||||||
|
Console.WriteLine("Service läuft im Konsolenmodus. Zum Beenden ENTER drücken.");
|
||||||
|
Console.ReadLine();
|
||||||
|
|
||||||
|
Stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Start(string[] args)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_testClient = new TestClient();
|
||||||
|
_testClient.Start(args);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Trace.TraceError("Fatal error while starting service: " + ex);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Stop()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_testClient?.Stop();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Trace.TraceError("Fatal error while stopping service: " + ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TestClient
|
||||||
|
{
|
||||||
|
private static IIMSApiDotNet imsapi = null;
|
||||||
|
private static bool initialized = false;
|
||||||
|
private static IMSApiSessionContextStruct sessionContext = null;
|
||||||
|
private static readonly Dictionary<long, IMSApiSessionContextStruct> allSessions = new Dictionary<long, IMSApiSessionContextStruct>();
|
||||||
|
|
||||||
|
private readonly object processingLock = new object();
|
||||||
|
private readonly HashSet<string> filesInProgress = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
private volatile bool isRunning = false;
|
||||||
|
private Thread cleaningThread;
|
||||||
|
private FileSystemWatcher sourceWatcher;
|
||||||
|
private FileSystemWatcher processWatcher;
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
|
static extern IntPtr GetStdHandle(int nStdHandle);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
|
static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
|
static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode);
|
||||||
|
|
||||||
|
const int STD_INPUT_HANDLE = -10;
|
||||||
|
const uint ENABLE_QUICK_EDIT = 0x0040;
|
||||||
|
|
||||||
|
private volatile bool fileProcessed = false;
|
||||||
|
|
||||||
|
public void Start(string[] args)
|
||||||
|
{
|
||||||
|
SetupLogging();
|
||||||
|
Trace.TraceInformation("Starting TestClient");
|
||||||
|
|
||||||
|
InitializeApi();
|
||||||
|
|
||||||
|
if (!initialized)
|
||||||
|
{
|
||||||
|
Trace.TraceError("Initialization of IMSApi failed. Exiting TestClient");
|
||||||
|
throw new Exception("Initialization of IMSApi failed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
Login();
|
||||||
|
|
||||||
|
isRunning = true;
|
||||||
|
|
||||||
|
StartWatchers();
|
||||||
|
StartCleaningThread();
|
||||||
|
|
||||||
|
Trace.TraceInformation("TestClient started successfully");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Stop()
|
||||||
|
{
|
||||||
|
Trace.TraceInformation("Stopping TestClient");
|
||||||
|
isRunning = false;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
sourceWatcher?.Dispose();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Trace.TraceError("Error disposing sourceWatcher: " + ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
processWatcher?.Dispose();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Trace.TraceError("Error disposing processWatcher: " + ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (cleaningThread != null && cleaningThread.IsAlive)
|
||||||
|
{
|
||||||
|
if (!cleaningThread.Join(5000))
|
||||||
|
{
|
||||||
|
Trace.TraceWarning("Cleaning thread did not stop within timeout.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Trace.TraceError("Error while stopping cleaning thread: " + ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
Trace.TraceInformation("TestClient stopped");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void StartWatchers()
|
||||||
|
{
|
||||||
|
string sourcePath = ConfigurationManager.AppSettings["SourcePath"];
|
||||||
|
string fileType = ConfigurationManager.AppSettings["Filetyp"];
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(sourcePath) &&
|
||||||
|
!string.Equals(sourcePath, "false", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
sourceWatcher = new FileSystemWatcher
|
||||||
|
{
|
||||||
|
Path = sourcePath,
|
||||||
|
NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastWrite | NotifyFilters.CreationTime,
|
||||||
|
Filter = fileType,
|
||||||
|
IncludeSubdirectories = false,
|
||||||
|
EnableRaisingEvents = false
|
||||||
|
};
|
||||||
|
|
||||||
|
sourceWatcher.Created += OnSourceFileCreatedOrChanged;
|
||||||
|
sourceWatcher.Changed += OnSourceFileCreatedOrChanged;
|
||||||
|
sourceWatcher.EnableRaisingEvents = true;
|
||||||
|
|
||||||
|
Trace.TraceInformation("Source watcher started on path: " + sourcePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
string processFilesPath = ConfigurationManager.AppSettings["PROCESS_FILES_PATH"];
|
||||||
|
if (!string.IsNullOrWhiteSpace(processFilesPath) &&
|
||||||
|
!string.Equals(processFilesPath, "false", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
processWatcher = new FileSystemWatcher
|
||||||
|
{
|
||||||
|
Path = processFilesPath,
|
||||||
|
NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastWrite | NotifyFilters.CreationTime,
|
||||||
|
Filter = fileType,
|
||||||
|
IncludeSubdirectories = false,
|
||||||
|
EnableRaisingEvents = false
|
||||||
|
};
|
||||||
|
|
||||||
|
processWatcher.Created += OnProcessFileCreatedOrChanged;
|
||||||
|
processWatcher.Changed += OnProcessFileCreatedOrChanged;
|
||||||
|
processWatcher.EnableRaisingEvents = true;
|
||||||
|
|
||||||
|
Trace.TraceInformation("Process watcher started on path: " + processFilesPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void StartCleaningThread()
|
||||||
|
{
|
||||||
|
cleaningThread = new Thread(CleaningLoop)
|
||||||
|
{
|
||||||
|
IsBackground = true,
|
||||||
|
Name = "FileInterfaceCleaningThread"
|
||||||
|
};
|
||||||
|
cleaningThread.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CleaningLoop()
|
||||||
|
{
|
||||||
|
while (isRunning)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int waitTime = int.Parse(ConfigurationManager.AppSettings["Wait"]);
|
||||||
|
Thread.Sleep(waitTime);
|
||||||
|
|
||||||
|
if (!isRunning)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!fileProcessed)
|
||||||
|
{
|
||||||
|
CleanOldFiles();
|
||||||
|
}
|
||||||
|
|
||||||
|
fileProcessed = false;
|
||||||
|
GC.Collect();
|
||||||
|
}
|
||||||
|
catch (ThreadInterruptedException)
|
||||||
|
{
|
||||||
|
Trace.TraceInformation("Cleaning loop interrupted.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Trace.TraceError("Error in cleaning loop: " + ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnSourceFileCreatedOrChanged(object source, FileSystemEventArgs e)
|
||||||
|
{
|
||||||
|
TryProcessFromWatcher(e.FullPath, e.Name, ResolveConfigFile(e.Name));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnProcessFileCreatedOrChanged(object source, FileSystemEventArgs e)
|
||||||
|
{
|
||||||
|
string configFile = ConfigurationManager.AppSettings["CF_Processfiles"];
|
||||||
|
TryProcessFromWatcher(e.FullPath, e.Name, configFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
private string ResolveConfigFile(string fileName)
|
||||||
|
{
|
||||||
|
string startsWith = ConfigurationManager.AppSettings["Check_starts_with"];
|
||||||
|
if (!string.IsNullOrWhiteSpace(startsWith) &&
|
||||||
|
!string.Equals(startsWith, "false", StringComparison.OrdinalIgnoreCase) &&
|
||||||
|
Path.GetFileName(fileName).StartsWith(startsWith, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return ConfigurationManager.AppSettings["CF_Name"];
|
||||||
|
}
|
||||||
|
|
||||||
|
return ConfigurationManager.AppSettings["CF_Processfiles"];
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TryProcessFromWatcher(string filePath, string fileName, string configFile)
|
||||||
|
{
|
||||||
|
if (!isRunning)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(filePath))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!MarkFileAsInProgress(filePath))
|
||||||
|
{
|
||||||
|
Trace.TraceInformation("Skipping already running file: " + filePath);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ThreadPool.QueueUserWorkItem(_ =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
lock (processingLock)
|
||||||
|
{
|
||||||
|
ProcessFile(filePath, fileName, configFile);
|
||||||
|
fileProcessed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Trace.TraceError($"Unhandled error in watcher processing for file '{filePath}': {ex}");
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
UnmarkFileAsInProgress(filePath);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool MarkFileAsInProgress(string filePath)
|
||||||
|
{
|
||||||
|
lock (filesInProgress)
|
||||||
|
{
|
||||||
|
return filesInProgress.Add(NormalizePath(filePath));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UnmarkFileAsInProgress(string filePath)
|
||||||
|
{
|
||||||
|
lock (filesInProgress)
|
||||||
|
{
|
||||||
|
filesInProgress.Remove(NormalizePath(filePath));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsFileInProgress(string filePath)
|
||||||
|
{
|
||||||
|
lock (filesInProgress)
|
||||||
|
{
|
||||||
|
return filesInProgress.Contains(NormalizePath(filePath));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string NormalizePath(string filePath)
|
||||||
|
{
|
||||||
|
return Path.GetFullPath(filePath).Trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ProcessFile(string filePath, string fileName, string configFile)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!File.Exists(filePath))
|
||||||
|
{
|
||||||
|
Trace.TraceWarning($"File not found: {filePath}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!WaitForFileReady(filePath, retries: 20, delayMs: 500))
|
||||||
|
{
|
||||||
|
throw new IOException($"File '{filePath}' is not ready for reading.");
|
||||||
|
}
|
||||||
|
|
||||||
|
string fileContent = File.ReadAllText(filePath);
|
||||||
|
string designator = ConfigurationManager.AppSettings["Designator"];
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(designator))
|
||||||
|
{
|
||||||
|
throw new Exception("Designator value is not set in the configuration.");
|
||||||
|
}
|
||||||
|
|
||||||
|
string parameters = BuildRawParameters(fileContent, designator);
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(parameters))
|
||||||
|
{
|
||||||
|
throw new Exception($"File '{fileName}' contains no valid elements after parsing.");
|
||||||
|
}
|
||||||
|
|
||||||
|
Trace.TraceInformation($"Processing file '{fileName}' with config '{configFile}'");
|
||||||
|
|
||||||
|
string[] outArgs;
|
||||||
|
string customErrorString;
|
||||||
|
|
||||||
|
int result = imsapi.customFunction(sessionContext, configFile, new[]
|
||||||
|
{
|
||||||
|
"ST|" + ConfigurationManager.AppSettings["StationNr"],
|
||||||
|
"MODE|" + ConfigurationManager.AppSettings["MODE"],
|
||||||
|
"PANEL_MODE|" + ConfigurationManager.AppSettings["PANEL_MODE"],
|
||||||
|
"PROCESS_MODE|" + ConfigurationManager.AppSettings["PROCESS_MODE"],
|
||||||
|
"FILENAME|" + fileName,
|
||||||
|
"RAW|" + parameters
|
||||||
|
}, out outArgs, out customErrorString);
|
||||||
|
|
||||||
|
LogResult(result, customErrorString, outArgs, fileName, parameters);
|
||||||
|
HandleResult(result, filePath, fileName, outArgs);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Trace.TraceError($"Error processing file '{filePath}': {ex}");
|
||||||
|
MoveFileToDirectory(
|
||||||
|
filePath,
|
||||||
|
Path.Combine(ConfigurationManager.AppSettings["Destination"], "unprocessed", fileName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string BuildRawParameters(string fileContent, string designator)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(fileContent))
|
||||||
|
return string.Empty;
|
||||||
|
|
||||||
|
var parts = fileContent
|
||||||
|
.Split(new[] { "\r\n", "\n", "\r" }, StringSplitOptions.None)
|
||||||
|
.Select(x => x?.Trim())
|
||||||
|
.Where(x => !string.IsNullOrWhiteSpace(x))
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
return string.Join(designator, parts);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool WaitForFileReady(string path, int retries, int delayMs)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < retries; i++)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (FileStream stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.None))
|
||||||
|
{
|
||||||
|
if (stream.Length >= 0)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IOException)
|
||||||
|
{
|
||||||
|
Thread.Sleep(delayMs);
|
||||||
|
}
|
||||||
|
catch (UnauthorizedAccessException)
|
||||||
|
{
|
||||||
|
Thread.Sleep(delayMs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LogResult(int result, string customErrorString, string[] outArgs, string fileName, string parameters)
|
||||||
|
{
|
||||||
|
string logInfo = ConfigurationManager.AppSettings["Loginfo"];
|
||||||
|
|
||||||
|
if ((logInfo == "error" && result != 0) || logInfo != "error")
|
||||||
|
{
|
||||||
|
Trace.TraceInformation("Date: " + DateTime.Now.ToString("dd-MM-yyyy HH:mm:ss"));
|
||||||
|
Trace.TraceInformation("File: " + fileName);
|
||||||
|
Trace.TraceInformation("Result: " + result);
|
||||||
|
Trace.TraceInformation("ErrorString: " + (customErrorString ?? string.Empty));
|
||||||
|
Trace.TraceInformation("RAW length: " + parameters.Length);
|
||||||
|
|
||||||
|
if (outArgs != null && outArgs.Length > 0)
|
||||||
|
{
|
||||||
|
Trace.TraceInformation("OutArgs: " + string.Join(" | ", outArgs));
|
||||||
|
}
|
||||||
|
|
||||||
|
Trace.Flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleResult(int result, string filePath, string fileName, string[] outArgs)
|
||||||
|
{
|
||||||
|
string destinationPath = ConfigurationManager.AppSettings["Destination"];
|
||||||
|
string processedDir = Path.Combine(destinationPath, result == 0 ? "processed" : "error");
|
||||||
|
|
||||||
|
MoveFileToDirectory(filePath, Path.Combine(processedDir, fileName));
|
||||||
|
|
||||||
|
if (result == 0 &&
|
||||||
|
outArgs != null &&
|
||||||
|
outArgs.Length >= 2 &&
|
||||||
|
!string.Equals(ConfigurationManager.AppSettings["Resultfile"], "false", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
WriteResultFile(outArgs[0], outArgs[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WriteResultFile(string resultFileName, string resultFileContent)
|
||||||
|
{
|
||||||
|
string resultPathRoot = ConfigurationManager.AppSettings["Resultfile"];
|
||||||
|
string resultFilePath = Path.Combine(resultPathRoot, resultFileName);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(resultPathRoot);
|
||||||
|
File.WriteAllText(resultFilePath, resultFileContent ?? string.Empty);
|
||||||
|
}
|
||||||
|
catch (IOException ioe)
|
||||||
|
{
|
||||||
|
Trace.TraceError($"Error writing result file '{resultFilePath}': {ioe}");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Trace.TraceError($"Unexpected error writing result file '{resultFilePath}': {ex}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MoveFileToDirectory(string sourceFilePath, string destinationFilePath)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!File.Exists(sourceFilePath))
|
||||||
|
{
|
||||||
|
Trace.TraceWarning($"File not found when trying to move: {sourceFilePath}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string destinationDirectory = Path.GetDirectoryName(destinationFilePath);
|
||||||
|
if (!string.IsNullOrWhiteSpace(destinationDirectory))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(destinationDirectory);
|
||||||
|
}
|
||||||
|
|
||||||
|
File.Copy(sourceFilePath, destinationFilePath, true);
|
||||||
|
File.Delete(sourceFilePath);
|
||||||
|
|
||||||
|
Trace.TraceInformation($"Moved file '{sourceFilePath}' to '{destinationFilePath}'");
|
||||||
|
}
|
||||||
|
catch (IOException ioe)
|
||||||
|
{
|
||||||
|
Trace.TraceError($"Error moving file from '{sourceFilePath}' to '{destinationFilePath}': {ioe}");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Trace.TraceError($"Unexpected error moving file from '{sourceFilePath}' to '{destinationFilePath}': {ex}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CleanOldFiles()
|
||||||
|
{
|
||||||
|
string sourcePath = ConfigurationManager.AppSettings["SourcePath"];
|
||||||
|
string processPath = ConfigurationManager.AppSettings["PROCESS_FILES_PATH"];
|
||||||
|
string destinationPath = ConfigurationManager.AppSettings["Destination"];
|
||||||
|
string processedDoneDir = Path.Combine(destinationPath, "processed_done");
|
||||||
|
|
||||||
|
lock (processingLock)
|
||||||
|
{
|
||||||
|
ProcessFilesInPath(
|
||||||
|
sourcePath,
|
||||||
|
ConfigurationManager.AppSettings["CF_Name"],
|
||||||
|
useStartsWithLogic: true);
|
||||||
|
|
||||||
|
ProcessFilesInPath(
|
||||||
|
processPath,
|
||||||
|
ConfigurationManager.AppSettings["CF_Processfiles"],
|
||||||
|
useStartsWithLogic: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateDirectoryIfNotExists(processedDoneDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ProcessFilesInPath(string path, string fallbackCustomFunction, bool useStartsWithLogic)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(path) ||
|
||||||
|
string.Equals(path, "false", StringComparison.OrdinalIgnoreCase) ||
|
||||||
|
!Directory.Exists(path))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string filter = ConfigurationManager.AppSettings["Filetyp"];
|
||||||
|
int ageLimit = int.Parse(ConfigurationManager.AppSettings["FileStamp_older_in_Minutes"]);
|
||||||
|
|
||||||
|
var files = Directory.GetFiles(path, filter);
|
||||||
|
|
||||||
|
foreach (var file in files)
|
||||||
|
{
|
||||||
|
if (!isRunning)
|
||||||
|
return;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (IsFileInProgress(file))
|
||||||
|
{
|
||||||
|
Trace.TraceInformation("Skipping cleanup for file already in progress: " + file);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileInfo fileInfo = new FileInfo(file);
|
||||||
|
TimeSpan fileAge = DateTime.UtcNow - fileInfo.LastWriteTimeUtc;
|
||||||
|
|
||||||
|
if (fileAge.TotalMinutes <= ageLimit)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!MarkFileAsInProgress(file))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string configFile = useStartsWithLogic
|
||||||
|
? ResolveConfigFile(fileInfo.Name)
|
||||||
|
: fallbackCustomFunction;
|
||||||
|
|
||||||
|
ProcessFile(file, fileInfo.Name, configFile);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
UnmarkFileAsInProgress(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Trace.TraceError($"Error while cleaning old file '{file}': {ex}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetupLogging()
|
||||||
|
{
|
||||||
|
string exePath = Assembly.GetExecutingAssembly().Location;
|
||||||
|
string exeDir = Path.GetDirectoryName(exePath);
|
||||||
|
if (string.IsNullOrWhiteSpace(exeDir))
|
||||||
|
exeDir = AppDomain.CurrentDomain.BaseDirectory;
|
||||||
|
|
||||||
|
DirectoryCheckAndCreate(exeDir);
|
||||||
|
|
||||||
|
string logPath = Path.Combine(exeDir, "IMSApiDotNet.log");
|
||||||
|
|
||||||
|
bool listenerExists = Trace.Listeners
|
||||||
|
.OfType<TextWriterTraceListener>()
|
||||||
|
.Any(l => string.Equals(l.Name, "IMSApiFileListener", StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
|
if (!listenerExists)
|
||||||
|
{
|
||||||
|
var traceListener = new TextWriterTraceListener(logPath, "IMSApiFileListener");
|
||||||
|
Trace.Listeners.Add(traceListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
Trace.AutoFlush = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeApi()
|
||||||
|
{
|
||||||
|
IMSApiDotNet.setProperty("itac.appid", ConfigurationManager.AppSettings["AppID"]);
|
||||||
|
IMSApiDotNet.setProperty("itac.artes.clusternodes", ConfigurationManager.AppSettings["Server_URL"]);
|
||||||
|
|
||||||
|
string exePath = Assembly.GetExecutingAssembly().Location;
|
||||||
|
IMSApiDotNet.setProperty("itac.propdir", Path.GetDirectoryName(exePath));
|
||||||
|
|
||||||
|
imsapi = IMSApiDotNet.loadLibrary();
|
||||||
|
|
||||||
|
if (imsapi == null)
|
||||||
|
throw new Exception("IMSApiDotNet.loadLibrary() returned null.");
|
||||||
|
|
||||||
|
test_imsapiGetLibraryVersion();
|
||||||
|
test_imsapiInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Login()
|
||||||
|
{
|
||||||
|
Trace.TraceInformation("calling regLogin()");
|
||||||
|
test_regLogin();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void test_imsapiGetLibraryVersion()
|
||||||
|
{
|
||||||
|
if (imsapi.imsapiGetLibraryVersion(out string version) != IMSApiDotNetConstants.RES_OK)
|
||||||
|
{
|
||||||
|
Trace.TraceError("Error getting library version.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Trace.TraceInformation($"Library Version: {version}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void test_imsapiInit()
|
||||||
|
{
|
||||||
|
if (imsapi.imsapiInit() != IMSApiDotNetConstants.RES_OK)
|
||||||
|
{
|
||||||
|
Trace.TraceError("Initialization of IMSApi failed.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
initialized = true;
|
||||||
|
Trace.TraceInformation("IMSApi initialized successfully.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void test_regLogin()
|
||||||
|
{
|
||||||
|
var sessValData = new IMSApiSessionValidationStruct
|
||||||
|
{
|
||||||
|
stationNumber = ConfigurationManager.AppSettings["StationNr"],
|
||||||
|
client = ConfigurationManager.AppSettings["CleintNO"],
|
||||||
|
registrationType = "S"
|
||||||
|
};
|
||||||
|
|
||||||
|
if (imsapi.regLogin(sessValData, out var newSessionContext) != IMSApiDotNetConstants.RES_OK)
|
||||||
|
{
|
||||||
|
Trace.TraceError("Login failed.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sessionContext = newSessionContext;
|
||||||
|
|
||||||
|
if (!allSessions.ContainsKey(sessionContext.sessionId))
|
||||||
|
{
|
||||||
|
allSessions.Add(sessionContext.sessionId, sessionContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
Trace.TraceInformation("Login successful.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void DisableQuickEditMode()
|
||||||
|
{
|
||||||
|
IntPtr consoleHandle = GetStdHandle(STD_INPUT_HANDLE);
|
||||||
|
if (GetConsoleMode(consoleHandle, out uint consoleMode))
|
||||||
|
{
|
||||||
|
consoleMode &= ~ENABLE_QUICK_EDIT;
|
||||||
|
SetConsoleMode(consoleHandle, consoleMode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void DirectoryCheckAndCreate(string exePath)
|
||||||
|
{
|
||||||
|
string destination = ConfigurationManager.AppSettings["Destination"];
|
||||||
|
|
||||||
|
CreateDirectoryIfNotExists(Path.Combine(destination, "processed"));
|
||||||
|
CreateDirectoryIfNotExists(Path.Combine(destination, "error"));
|
||||||
|
CreateDirectoryIfNotExists(Path.Combine(destination, "unprocessed"));
|
||||||
|
CreateDirectoryIfNotExists(Path.Combine(destination, "processed_done"));
|
||||||
|
|
||||||
|
CreateFileIfNotExists(Path.Combine(exePath, "ihas.properties"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CreateDirectoryIfNotExists(string path)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrWhiteSpace(path) && !Directory.Exists(path))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CreateFileIfNotExists(string path)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrWhiteSpace(path) && !File.Exists(path))
|
||||||
|
{
|
||||||
|
using (File.Create(path)) { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
36
FileInterface/Properties/AssemblyInfo.cs
Normal file
36
FileInterface/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// Allgemeine Informationen über eine Assembly werden über die folgenden
|
||||||
|
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
|
||||||
|
// die einer Assembly zugeordnet sind.
|
||||||
|
[assembly: AssemblyTitle("FileInterface")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("iTAC Software AG")]
|
||||||
|
[assembly: AssemblyProduct("FileInterface")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © iTAC Software AG 2022")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly
|
||||||
|
// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von
|
||||||
|
// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen.
|
||||||
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
|
||||||
|
[assembly: Guid("1dcdc78f-3042-44c5-91cc-1afb1c752386")]
|
||||||
|
|
||||||
|
// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
|
||||||
|
//
|
||||||
|
// Hauptversion
|
||||||
|
// Nebenversion
|
||||||
|
// Buildnummer
|
||||||
|
// Revision
|
||||||
|
//
|
||||||
|
// Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden,
|
||||||
|
// indem Sie "*" wie unten gezeigt eingeben:
|
||||||
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||||
144
FileInterface/Properties/Resources.Designer.cs
generated
Normal file
144
FileInterface/Properties/Resources.Designer.cs
generated
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// Dieser Code wurde von einem Tool generiert.
|
||||||
|
// Laufzeitversion:4.0.30319.42000
|
||||||
|
//
|
||||||
|
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
|
||||||
|
// der Code erneut generiert wird.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace FileInterface.Properties {
|
||||||
|
using System;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
|
||||||
|
/// </summary>
|
||||||
|
// Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
|
||||||
|
// -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
|
||||||
|
// Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
|
||||||
|
// mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
|
||||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
|
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
|
internal class Resources {
|
||||||
|
|
||||||
|
private static global::System.Resources.ResourceManager resourceMan;
|
||||||
|
|
||||||
|
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||||
|
|
||||||
|
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||||
|
internal Resources() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
|
||||||
|
/// </summary>
|
||||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||||
|
get {
|
||||||
|
if (object.ReferenceEquals(resourceMan, null)) {
|
||||||
|
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("FileInterface.Properties.Resources", typeof(Resources).Assembly);
|
||||||
|
resourceMan = temp;
|
||||||
|
}
|
||||||
|
return resourceMan;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
|
||||||
|
/// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
|
||||||
|
/// </summary>
|
||||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static global::System.Globalization.CultureInfo Culture {
|
||||||
|
get {
|
||||||
|
return resourceCulture;
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
resourceCulture = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sucht eine lokalisierte Zeichenfolge, die FileInterface ähnelt.
|
||||||
|
/// </summary>
|
||||||
|
internal static string AppID {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("AppID", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sucht eine lokalisierte Zeichenfolge, die ähnelt.
|
||||||
|
/// </summary>
|
||||||
|
internal static string CF_Name {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("CF_Name", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sucht eine lokalisierte Zeichenfolge, die 01 ähnelt.
|
||||||
|
/// </summary>
|
||||||
|
internal static string ClientNO {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("ClientNO", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sucht eine lokalisierte Zeichenfolge, die c:\temp ähnelt.
|
||||||
|
/// </summary>
|
||||||
|
internal static string Destination {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("Destination", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sucht eine lokalisierte Zeichenfolge, die ähnelt.
|
||||||
|
/// </summary>
|
||||||
|
internal static string MODE {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("MODE", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sucht eine lokalisierte Zeichenfolge, die off ähnelt.
|
||||||
|
/// </summary>
|
||||||
|
internal static string resultfile {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("resultfile", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sucht eine lokalisierte Zeichenfolge, die http://ksbrose:8080/mes ähnelt.
|
||||||
|
/// </summary>
|
||||||
|
internal static string Server_URL {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("Server_URL", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sucht eine lokalisierte Zeichenfolge, die c:\test ähnelt.
|
||||||
|
/// </summary>
|
||||||
|
internal static string SourcePath {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("SourcePath", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sucht eine lokalisierte Zeichenfolge, die 1017VFE010100110 ähnelt.
|
||||||
|
/// </summary>
|
||||||
|
internal static string StationNr {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("StationNr", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
147
FileInterface/Properties/Resources.resx
Normal file
147
FileInterface/Properties/Resources.resx
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<data name="AppID" xml:space="preserve">
|
||||||
|
<value>FileInterface</value>
|
||||||
|
</data>
|
||||||
|
<data name="CF_Name" xml:space="preserve">
|
||||||
|
<value />
|
||||||
|
</data>
|
||||||
|
<data name="ClientNO" xml:space="preserve">
|
||||||
|
<value>01</value>
|
||||||
|
</data>
|
||||||
|
<data name="Destination" xml:space="preserve">
|
||||||
|
<value>c:\temp</value>
|
||||||
|
</data>
|
||||||
|
<data name="MODE" xml:space="preserve">
|
||||||
|
<value />
|
||||||
|
</data>
|
||||||
|
<data name="resultfile" xml:space="preserve">
|
||||||
|
<value>off</value>
|
||||||
|
</data>
|
||||||
|
<data name="Server_URL" xml:space="preserve">
|
||||||
|
<value>http://ksbrose:8080/mes</value>
|
||||||
|
</data>
|
||||||
|
<data name="SourcePath" xml:space="preserve">
|
||||||
|
<value>c:\test</value>
|
||||||
|
</data>
|
||||||
|
<data name="StationNr" xml:space="preserve">
|
||||||
|
<value>1017VFE010100110</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
||||||
8
FileInterface/packages.config
Normal file
8
FileInterface/packages.config
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<packages>
|
||||||
|
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net48" />
|
||||||
|
<package id="System.Configuration.ConfigurationManager" version="6.0.0" targetFramework="net48" />
|
||||||
|
<package id="System.Security.AccessControl" version="6.0.0" targetFramework="net48" />
|
||||||
|
<package id="System.Security.Permissions" version="6.0.0" targetFramework="net48" />
|
||||||
|
<package id="System.Security.Principal.Windows" version="5.0.0" targetFramework="net48" />
|
||||||
|
</packages>
|
||||||
4
readme_de.txt
Normal file
4
readme_de.txt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
Das FileInterface ist ein automatisierter Windows-Dienst zur Verarbeitung von Eingabedateien.
|
||||||
|
Es überwacht ein Verzeichnis, liest neue Dateien ein, bereitet deren Inhalte roh auf (z. B. Entfernen leerer Zeilen und Zusammenführen mit einem Trenner) und übergibt die Daten anschließend an eine IMS Custom Function (CF) zur weiteren Verarbeitung im System.
|
||||||
|
|
||||||
|
Das Interface dient als flexible Schnittstelle zwischen Dateiquellen (z. B. Maschinen, Fremdsysteme) und der MES-/IMS-Logik.
|
||||||
4
readme_en.txt
Normal file
4
readme_en.txt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
The FileInterface is an automated Windows service for processing input files.
|
||||||
|
It monitors a directory, reads incoming files, performs raw parsing (e.g. removing empty lines and joining content using a separator), and forwards the data to an IMS custom function (CF) for further processing.
|
||||||
|
|
||||||
|
The interface acts as a flexible bridge between file-based sources (e.g. machines or external systems) and MES/IMS logic.
|
||||||
Loading…
x
Reference in New Issue
Block a user