initialize
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
namespace com.itac.mes.simm
|
||||
{
|
||||
/// <summary>
|
||||
/// possible values for the configuration settings
|
||||
/// </summary>
|
||||
public enum ConfigCode
|
||||
|
||||
{
|
||||
OFF = 0,
|
||||
MES = 1,
|
||||
SIMM = 2
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using Asm.As.Oib.Client;
|
||||
using Asm.As.Oib.SiplaceSetupCenter.Contracts.Data;
|
||||
using com.itac.mes.imsapi;
|
||||
using com.itac.mes.imsapi.domain.container;
|
||||
using com.itac.mes.tools;
|
||||
|
||||
namespace com.itac.mes
|
||||
{
|
||||
|
||||
|
||||
class ContainerCheckThread
|
||||
{
|
||||
|
||||
private static string attributeName = "SIMM-ManualSetToZero";
|
||||
public static int MIN_INTERVAL_SECONDS = 10;
|
||||
|
||||
private TimeSpan interval;
|
||||
private Thread thread;
|
||||
private IIMSApi imsapi;
|
||||
private SetupCenterNotificationClient setupCenterNotificationClient;
|
||||
private string stationNumber;
|
||||
private IMSApiSessionContextStruct sessionContext;
|
||||
private imsapi.domain.container.KeyValue[] materialBinFilters = new imsapi.domain.container.KeyValue[] { new imsapi.domain.container.KeyValue("MATERIAL_BIN_NUMBER", "*") };
|
||||
private AttributeInfo[] attributes = new AttributeInfo[] { new AttributeInfo(attributeName, "1") };
|
||||
private string[] materialBinResultKeys = new string[] { "MATERIAL_BIN_NUMBER" };
|
||||
|
||||
|
||||
|
||||
public ContainerCheckThread(TimeSpan interval, IIMSApi imsapi, IMSApiSessionContextStruct sessionContext, SetupCenterNotificationClient setupCenterNotificationClient, String stationNumber)
|
||||
{
|
||||
// none of those values must be null
|
||||
this.interval = interval;
|
||||
this.imsapi = imsapi;
|
||||
this.setupCenterNotificationClient = setupCenterNotificationClient;
|
||||
this.stationNumber = stationNumber;
|
||||
this.sessionContext = sessionContext;
|
||||
if (interval.TotalSeconds >= MIN_INTERVAL_SECONDS)
|
||||
{
|
||||
thread = new Thread(CheckContainers);
|
||||
}
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
if (thread != null)
|
||||
{
|
||||
thread.Start();
|
||||
}
|
||||
}
|
||||
|
||||
public void CheckContainers()
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "start checking empty containers in MES (having attribute " + attributeName + "==1)");
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
string[] resultValues;
|
||||
int objectType = 2;
|
||||
string attributeValue = "1";
|
||||
int maxRows = 100;
|
||||
imsapi.domain.container.KeyValue[] attributeFilters = new imsapi.domain.container.KeyValue[0];
|
||||
// getContainers with attribute
|
||||
int returnCode = imsapi.attribGetObjectsForAttributeValues(sessionContext, stationNumber, objectType, attributeName, attributeValue, maxRows, attributeFilters, materialBinResultKeys, out resultValues);
|
||||
if (returnCode == 0)
|
||||
{
|
||||
// for every container:
|
||||
// send this info to setupCenter and close them within SC
|
||||
// if OK remove the attribute from the container, otherwise set appropriate attribute value
|
||||
foreach (String containerId in resultValues)
|
||||
{
|
||||
consumePackagingUnitInSetupCenter(containerId);
|
||||
}
|
||||
}
|
||||
else if (returnCode == -932 || returnCode > 0)
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "no empty containers found");
|
||||
}
|
||||
else if (returnCode < 0)
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Error, "failed to retrieve empty containers from MES, apiRet Code=" + returnCode);
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, "processing empty containers failed", exception);
|
||||
}
|
||||
finally
|
||||
{
|
||||
DateTime nextRun = DateTime.Now + interval;
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "next run for checking empty containers (having attribute " + attributeName + "==1) in " + interval + " at " + nextRun.ToLongTimeString());
|
||||
Thread.Sleep(interval);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void consumePackagingUnitInSetupCenter(string containerId)
|
||||
{
|
||||
// create an ASM packaging unit; for delete it is sufficient to have an UID only
|
||||
PackagingUnit packagingUnit = new PackagingUnit();
|
||||
packagingUnit.UID = containerId;
|
||||
PackagingUnitConsumedReport packUnitConsumedReport = new PackagingUnitConsumedReport();
|
||||
PackagingUnitLocation packagingUnitLocation = new PackagingUnitLocation();
|
||||
packagingUnitLocation.PackagingUnit = packagingUnit;
|
||||
packUnitConsumedReport.PackagingUnitLocations = new List<PackagingUnitLocation> { packagingUnitLocation };
|
||||
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "raise delete packagingUnit " + containerId + " in SetupCenter");
|
||||
try
|
||||
{
|
||||
setupCenterNotificationClient.RaisePackagingUnitConsumed(packUnitConsumedReport);
|
||||
// delete Packaging unite succeeded
|
||||
// remove attribute from container
|
||||
/* example call:
|
||||
attribRemoveAttributeValue()
|
||||
stationNumber= 01010010
|
||||
objectType= 2
|
||||
objectNumber= 000197630005
|
||||
objectDetail= -1
|
||||
attributeCode= SIMM - ManualSetToZero
|
||||
attributeValueKey= 1
|
||||
------------------------------------------------------------------
|
||||
Result_attribRemoveAttributeValue
|
||||
.return_value= 0 ''
|
||||
*/
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "remove attribute " + attributeName + " from container " + containerId);
|
||||
int objectType = 2;
|
||||
string objectDetail = "-1";
|
||||
string attributeValueKey = "1";
|
||||
int retValue = imsapi.attribRemoveAttributeValue(sessionContext, stationNumber, objectType, containerId, objectDetail, attributeName, attributeValueKey);
|
||||
if (retValue != 0)
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Error, "removing attribute " + attributeName + " from container " + containerId + " failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "removing attribute " + attributeName + " from container " + containerId + " succeded");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Error, "raise consumed event for packagingUnit " + containerId + " failed", e);
|
||||
// modify attribute value
|
||||
|
||||
/* example call
|
||||
attribAppendAttributeValues()
|
||||
stationNumber= 01010010
|
||||
objectType= 2
|
||||
objectNumber= 000197630005
|
||||
objectDetail= -1
|
||||
bookDate= -1
|
||||
allowOverWrite= 1
|
||||
attributeUploadKeys.length= 3
|
||||
attributeUploadKeys[0]= ATTRIBUTE_CODE
|
||||
attributeUploadKeys[1]= ATTRIBUTE_VALUE
|
||||
attributeUploadKeys[2]= ERROR_CODE
|
||||
attributeUploadValues.length= 3
|
||||
attributeUploadValues[0]= SIMM - ManualSetToZero
|
||||
attributeUploadValues[1]= 3
|
||||
attributeUploadValues[2]= 0
|
||||
------------------------------------------------------------------
|
||||
Result_attribAppendAttributeValues
|
||||
.return_value= 0 ''
|
||||
.attributeResultValues[] empty
|
||||
*/
|
||||
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "update attribute " + attributeName + " from container " + containerId + " to value 2");
|
||||
int objectType = 2;
|
||||
string objectDetail = "-1";
|
||||
long bookDate = -1;
|
||||
int allowOverwrite = 1;
|
||||
string[] attributeUploadKeys = new string[] { "ATTRIBUTE_CODE", "ATTRIBUTE_VALUE", "ERROR_CODE" };
|
||||
string[] attributeUploadValues = new string[] { attributeName, "2", "0" };
|
||||
string[] attributeResultValues = null;
|
||||
int retValue = imsapi.attribAppendAttributeValues(sessionContext, stationNumber, objectType, containerId, objectDetail,
|
||||
bookDate, allowOverwrite, attributeUploadKeys, attributeUploadValues, out attributeResultValues);
|
||||
if (retValue != 0)
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Error, "setting attribute " + attributeName + " from container " + containerId + " to value 2 failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using com.itac.mes.imsapi;
|
||||
|
||||
namespace com.itac.mes.imsapi.data
|
||||
{
|
||||
public class MaterialBinBooking
|
||||
{
|
||||
public static string[] MAXIMAL_INFORMATION = new string[] { "ERROR_CODE", "MATERIAL_BIN_NUMBER", "MATERIAL_BIN_QTY_ACTUAL", "QUANTITY", "TRANSACTION_CODE" };
|
||||
|
||||
[ImsApiKey(Key = "MATERIAL_BIN_NUMBER")]
|
||||
public string materialBinNumber;
|
||||
|
||||
[ImsApiKey(Key = "MATERIAL_BIN_QTY_ACTUAL")]
|
||||
public int materialBinQuantityActual = 0;
|
||||
|
||||
[ImsApiKey(Key = "QUANTITY")]
|
||||
public int quantity = 0;
|
||||
|
||||
[ImsApiKey(Key = "TRANSACTION_CODE")]
|
||||
public string transactionCode;
|
||||
|
||||
[ImsApiKey(Key = "ERROR_CODE")]
|
||||
public int errorCode = 0;
|
||||
|
||||
|
||||
|
||||
public int CompareTo(MaterialBinBooking obj)
|
||||
{
|
||||
if (materialBinNumber == null) return -1;
|
||||
if (obj == null) return 1;
|
||||
return materialBinNumber.CompareTo(obj.materialBinNumber);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
namespace com.itac.mes.proxy
|
||||
{
|
||||
public class MslLevel
|
||||
{
|
||||
/// <summary>
|
||||
/// SetupCenter has it's own values for the MSL Levels. These are defined as constants
|
||||
/// This function returns the value from MsdLevel as a String (lower case);
|
||||
/// </summary>
|
||||
/// <param name="mslLevel"></param>
|
||||
/// <returns></returns>
|
||||
public static string toString(int msdLevel)
|
||||
{
|
||||
switch (msdLevel)
|
||||
{
|
||||
case 1: return "1";
|
||||
case 2: return "2";
|
||||
case 3: return "2a";
|
||||
case 4: return "3";
|
||||
case 5: return "4";
|
||||
case 6: return "5";
|
||||
case 7: return "5a";
|
||||
case 8: return "6";
|
||||
default: return "1";
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// convert a level as it is used in iTAC.MES.Suite to a value used in SetupCenter
|
||||
/// </summary>
|
||||
/// <param name="itacLevel"></param>
|
||||
/// <returns></returns>
|
||||
|
||||
public static int toCode(string itacLevel)
|
||||
{
|
||||
switch (itacLevel)
|
||||
{
|
||||
case "1": return 1;
|
||||
case "2": return 2;
|
||||
case "2a": case "2A": return 3;
|
||||
case "3": return 4;
|
||||
case "4": return 5;
|
||||
case "5": return 6;
|
||||
case "5a": case "5A": return 7;
|
||||
case "6": return 8;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,594 @@
|
||||
#region Namespace
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.ServiceModel;
|
||||
using com.itac.mes.tools;
|
||||
using com.itac.mes.proxy;
|
||||
|
||||
using Imsapi = com.itac.mes.imsapi.domain.container;
|
||||
using Asm.As.Oib.SiplaceSetupCenter.Contracts.Data;
|
||||
using Asm.As.Oib.SiplaceSetupCenter.Contracts.Service;
|
||||
using OibClient = Asm.As.Oib.Client;
|
||||
using com.itac.mes.imsapi.domain.container;
|
||||
using System.Collections.Generic;
|
||||
using com.itac.mes.imsapi;
|
||||
using com.itac.mes.imsapi.data;
|
||||
using System.Configuration;
|
||||
using com.itac.mes.simm;
|
||||
#endregion
|
||||
|
||||
|
||||
namespace Itac.Oib
|
||||
{
|
||||
|
||||
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
|
||||
public class SetupCenterExternalControlReceiver : ISiplaceSetupCenterExternalControl, IDisposable, IReceiver
|
||||
{
|
||||
#region Fields
|
||||
|
||||
private readonly OibClient.OibSetupCenterExternalControlEvents _oibSetupCenterExternalControlEvents;
|
||||
|
||||
private IIMSApi imsapi;
|
||||
private IMSApiSessionContextStruct sessionContext;
|
||||
private ItacXmlSerializer serializer;
|
||||
|
||||
private long firstASMTime = new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks;
|
||||
private long msdOpenTime = DateTime.MinValue.Ticks;
|
||||
private long lastItacTimeTicks = new DateTime(3000, 12, 31, 23, 59, 59, DateTimeKind.Utc).Ticks;
|
||||
private long firstItacTimeTicks = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// the station Number is configured, must not be empty and MUST exist and valid!!!
|
||||
/// if the stationNumber is not valid (licensed etc) all requests are rejected!!
|
||||
/// </summary>
|
||||
private string stationNumber;
|
||||
private int transactionCode;
|
||||
|
||||
// some optional values, default false
|
||||
private bool mslLevelCheck;
|
||||
private ConfigCode expirationMaster;
|
||||
private ConfigCode mslMaster;
|
||||
private ConfigCode quantityMaster;
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
|
||||
public SetupCenterExternalControlReceiver(OibClient.OibSetupCenterExternalControlEvents oibSetupCenterExternalControlEvents, IIMSApi imsapi, IMSApiSessionContextStruct newSessionContext,
|
||||
String stationNumber, int transactionCode,
|
||||
ConfigCode quantityMaster, ConfigCode mslMaster, ConfigCode expirationMaster)
|
||||
{
|
||||
_oibSetupCenterExternalControlEvents = oibSetupCenterExternalControlEvents;
|
||||
if (oibSetupCenterExternalControlEvents != null)
|
||||
{
|
||||
oibSetupCenterExternalControlEvents.Ping = Ping;
|
||||
oibSetupCenterExternalControlEvents.GetNewPackagingUnitData = GetNewPackagingUnitData;
|
||||
oibSetupCenterExternalControlEvents.GetPackagingUnitControlStatus = GetPackagingUnitControlStatus;
|
||||
}
|
||||
this.imsapi = imsapi;
|
||||
this.sessionContext = newSessionContext;
|
||||
this.stationNumber = stationNumber;
|
||||
this.transactionCode = transactionCode;
|
||||
this.quantityMaster = quantityMaster;
|
||||
this.mslMaster = mslMaster;
|
||||
this.expirationMaster = expirationMaster;
|
||||
serializer = new ItacXmlSerializer();
|
||||
|
||||
// evaluate some optional parameters from appConfig file
|
||||
if (!String.IsNullOrEmpty(ConfigurationManager.AppSettings["mslLevelCheck"]))
|
||||
{
|
||||
mslLevelCheck = bool.Parse(ConfigurationManager.AppSettings["mslLevelCheck"].ToString());
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "optional parameter 'mslLevelCheck' set '" + mslLevelCheck.ToString() + "'");
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_oibSetupCenterExternalControlEvents != null)
|
||||
_oibSetupCenterExternalControlEvents.Dispose();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Start/Stop
|
||||
|
||||
public void StartReceiver()
|
||||
{
|
||||
_oibSetupCenterExternalControlEvents.Start();
|
||||
}
|
||||
|
||||
public void StopReceiver()
|
||||
{
|
||||
_oibSetupCenterExternalControlEvents.Stop();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region toolFunctions
|
||||
|
||||
// muss noch weiter getestet werden...
|
||||
public void DeepCopy(object sourceObject, object destObject)
|
||||
{
|
||||
Type sourceType = sourceObject.GetType();
|
||||
Type destType = destObject.GetType();
|
||||
MemberInfo[] sourceMbrInfoArray = sourceType.GetMembers();
|
||||
MemberInfo[] destMbrInfoArray = destType.GetMembers();
|
||||
|
||||
foreach (MemberInfo sourceMbrInfo in sourceMbrInfoArray)
|
||||
{
|
||||
if (sourceMbrInfo.MemberType == MemberTypes.Property)
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Error, "" + sourceMbrInfo + " is a " + sourceMbrInfo.MemberType);
|
||||
// alle einfachen TypeNameConverter direkt prüfen (int, String, bool)
|
||||
// komplexe Typen ???
|
||||
|
||||
PropertyInfo sourcePropInfo = sourceType.GetProperty(sourceMbrInfo.Name);
|
||||
|
||||
// gibt es das Property auch im Zielobjekt
|
||||
foreach (MemberInfo destMbrInfo in destMbrInfoArray)
|
||||
{
|
||||
// identischer Name, identischerr Typ
|
||||
if (destMbrInfo.MemberType == sourceMbrInfo.MemberType && destMbrInfo.Name == sourceMbrInfo.Name)
|
||||
{
|
||||
PropertyInfo destPropInfo = destType.GetProperty(destMbrInfo.Name);
|
||||
object sourceValue = sourcePropInfo.GetValue(sourceObject, null);
|
||||
object destValue = destPropInfo.GetValue(destObject, null);
|
||||
if (sourcePropInfo.PropertyType == typeof(String) || sourcePropInfo.PropertyType == typeof(int)
|
||||
|| sourcePropInfo.PropertyType == typeof(Int32) || sourcePropInfo.PropertyType == typeof(Int64)
|
||||
|| sourcePropInfo.PropertyType == typeof(long) || sourcePropInfo.PropertyType == typeof(bool)
|
||||
|| sourcePropInfo.PropertyType == typeof(Boolean))
|
||||
{
|
||||
if (sourceValue != destValue)
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "primitive type copy value");
|
||||
destPropInfo.SetValue(destObject, sourceValue, null);
|
||||
}
|
||||
}
|
||||
else if (!sourceType.IsArray)
|
||||
{
|
||||
// komplexer Typ, kein Array
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, sourceMbrInfo.Name + " is complex type ");
|
||||
if (sourceValue != null)
|
||||
{
|
||||
DeepCopy(sourceValue, destValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, sourceMbrInfo.Name + " is complex type, sourceValue is null");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void applyToPackagingUnit(SmtContainer container, ref PackagingUnit p)
|
||||
{
|
||||
p.BatchId = container.supplierChargeNumber;
|
||||
// p.BatchPackagingUnit=
|
||||
p.BrightnessClass = container.classification; ;
|
||||
// p.Comment="";
|
||||
p.ComponentBarcode = "";
|
||||
p.ComponentName = container.materialBinPartNumber;
|
||||
// p.ConsumptionDate = getDateValue(resultValues[indexMap[""]]);
|
||||
|
||||
// special case: itac 31.12.3000 is unexpired, in ASM 31.12.9999
|
||||
if (container.expirationDate >= new DateTime(2037, 12, 31))
|
||||
{
|
||||
p.ExpiryDate = DateTime.MaxValue.ToUniversalTime();
|
||||
}
|
||||
else
|
||||
{
|
||||
p.ExpiryDate = container.expirationDate; // getDateValue(resultValues[indexMap["EXPIRATION_DATE"]]);
|
||||
}
|
||||
// p.Extra1="";
|
||||
// p.Extra2="";
|
||||
// p.Extra3="";
|
||||
// p.GreyZone=
|
||||
if (p.LastProductionDate <= new DateTime(1901, 01, 01, 00, 00, 00, DateTimeKind.Utc))
|
||||
{
|
||||
p.LastProductionDate = DateTime.MinValue.ToUniversalTime();
|
||||
}
|
||||
// p.ManufactureLocation
|
||||
// p.ManufacturePartNumber
|
||||
p.Manufacturer = container.supplierName;
|
||||
p.ManufacturerDate = container.dateCreated;
|
||||
p.MsdLevel = MslLevel.toCode(container.mslLevel);
|
||||
|
||||
string mslState = container.mslState;
|
||||
if ("C".Equals(mslState))
|
||||
{
|
||||
p.MsdOpenDate = DateTime.MinValue.ToUniversalTime();
|
||||
}
|
||||
else
|
||||
{
|
||||
// take open date from MES
|
||||
p.MsdOpenDate = container.mslOpenDate;
|
||||
// correction of MSD open Date when unopened
|
||||
if (p.MsdOpenDate <= new DateTime(1901, 01, 01, 00, 00, 00, DateTimeKind.Utc))
|
||||
{
|
||||
p.MsdOpenDate = DateTime.MinValue.ToUniversalTime();
|
||||
}
|
||||
}
|
||||
|
||||
// p.OrderingCode = ;
|
||||
p.OriginalQuantity = container.quantity;// Convert.ToInt32(double.Parse(resultValues[indexMap["MATERIAL_BIN_QTY_TOTAL"]]));
|
||||
p.PurchaseOrderNumber = container.huNumber;
|
||||
p.Quantity = container.materialBinQuantityActual; // Convert.ToInt32(Double.Parse(resultValues[indexMap["MATERIAL_BIN_QTY_ACTUAL"]]));
|
||||
// p.RevisionLevel;
|
||||
// p.RoHS
|
||||
// p.Serial
|
||||
// p.ShippingNoteNumber
|
||||
// p.SplicedPackagingUnit
|
||||
p.Supplier = container.supplierName;
|
||||
// p.SupplierData
|
||||
// p.UID;
|
||||
}
|
||||
|
||||
|
||||
public void mapValues(PackagingUnit pu, string[] materialBinUploadKeys, ref string[] result, int index)
|
||||
{
|
||||
foreach (string s in materialBinUploadKeys)
|
||||
{
|
||||
switch (s)
|
||||
{
|
||||
case "ERROR_CODE": result[index++] = "0"; break;
|
||||
case "MATERIAL_BIN_NUMBER": result[index++] = pu.UID; break;
|
||||
default: result[index++] = "0"; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void deepAddUnit(PackagingUnit packUnit, ref Dictionary<string, PackagingUnit> packagingUnitMap)
|
||||
{
|
||||
packagingUnitMap.Add(packUnit.UID, packUnit);
|
||||
if (packUnit.SplicedPackagingUnit != null)
|
||||
{
|
||||
deepAddUnit(packUnit.SplicedPackagingUnit, ref packagingUnitMap);
|
||||
}
|
||||
}
|
||||
#endregion toolFunctions
|
||||
|
||||
#region ISiplaceSetupCenterExternalControl Members
|
||||
|
||||
/// <summary>
|
||||
/// Check for the client if this service is available.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool Ping()
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "SetupCenterExternalControl.Ping");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the packaging unit control status.
|
||||
/// </summary>
|
||||
/// <param name="packagingUnitLocations">The packaging unit locations.</param>
|
||||
/// <returns>List of ExternalControlResults for reading the data</returns>
|
||||
/// ResultState UNKNOWN=0;OK = 1;NOT_OK=2;
|
||||
public ExternalControlResult[] GetNewPackagingUnitData(PackagingUnitLocation[] packagingUnitLocations)
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "SetupCenterExternalControl.GetNewPackagingUnit()\n"
|
||||
+ serializer.serialize(packagingUnitLocations).ToString());
|
||||
|
||||
Imsapi. KeyValue[] matBinfilters = new Imsapi.KeyValue[] { new Imsapi.KeyValue("MATERIAL_BIN_NUMBER", "") };
|
||||
AttributeInfo[] attributes = new AttributeInfo[0];
|
||||
string[] resultValues;
|
||||
|
||||
try
|
||||
{
|
||||
ExternalControlResult[] result = new ExternalControlResult[packagingUnitLocations.Length];
|
||||
for (int i = 0; i < packagingUnitLocations.Length; i++)
|
||||
{
|
||||
result[i] = new ExternalControlResult();
|
||||
result[i].PackagingUnit = packagingUnitLocations[i].PackagingUnit;
|
||||
|
||||
matBinfilters[0].value = packagingUnitLocations[i].PackagingUnit.UID;
|
||||
int imsapiResult = imsapi.mlGetMaterialBinData(sessionContext, stationNumber, matBinfilters, attributes, SmtContainer.MAXIMAL_INFORMATION, out resultValues);
|
||||
// return all relevant PackagingUnit infos known in iTAC.MES.Suite
|
||||
if (imsapiResult < 0 || imsapiResult == 1) // 1 = no data found
|
||||
{
|
||||
result[i].ResultState = 2;
|
||||
result[i].Messages = new List<ExternalControlResultMessage> { new ExternalControlResultMessage() };
|
||||
result[i].Messages[0].Message = "UID " + packagingUnitLocations[i].PackagingUnit.UID + " unknown in iTAC.MES.Suite";
|
||||
}
|
||||
else
|
||||
{
|
||||
// OK, Info gathered
|
||||
result[i].ResultState = 1;
|
||||
result[i].Messages = new List<ExternalControlResultMessage> { };
|
||||
PackagingUnit p = result[i].PackagingUnit;
|
||||
try
|
||||
{
|
||||
SmtContainer knownContainer = new ImsApiMapTool<SmtContainer>().getStruct(typeof(SmtContainer), SmtContainer.MAXIMAL_INFORMATION, resultValues);
|
||||
applyToPackagingUnit(knownContainer, ref p);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
result[i].ResultState = 2;
|
||||
result[i].Messages = new List<ExternalControlResultMessage> { new ExternalControlResultMessage() };
|
||||
result[i].Messages[0].Message = e.Message.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Information, serializer.serialize(result).ToString());
|
||||
return result;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// Fehler, keine weitere info vorhanden, da die Applikation nicht läuft
|
||||
return new ExternalControlResult[0];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the packaging unit control status.
|
||||
/// </summary>
|
||||
/// <param name="packagingUnitLocations">The packaging unit locations.</param>
|
||||
/// <returns>List of ExternalControlResults for reading the data</returns>
|
||||
public ExternalControlResult[] GetPackagingUnitControlStatus(PackagingUnitLocation[] packagingUnitLocations)
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "SetupCenterExternalControl.GetPackagingUnitControlStatus:\n"
|
||||
+ serializer.serialize(packagingUnitLocations).ToString());
|
||||
if (!mslLevelCheck)
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "mslLevel check switched off by confguration");
|
||||
}
|
||||
|
||||
Imsapi. KeyValue[] matBinfilters = new Imsapi.KeyValue[] { new Imsapi.KeyValue("MATERIAL_BIN_NUMBER", "") };
|
||||
AttributeInfo[] attributes = new AttributeInfo[0];
|
||||
|
||||
// flag wether to update any qty or not.
|
||||
LinkedList<MaterialBinBooking> updateQtyList = new LinkedList<MaterialBinBooking>();
|
||||
try
|
||||
{
|
||||
ExternalControlResult[] result = new ExternalControlResult[packagingUnitLocations.Length];
|
||||
for (int resultIndex = 0; resultIndex < packagingUnitLocations.Length; resultIndex++)
|
||||
{
|
||||
result[resultIndex] = new ExternalControlResult();
|
||||
result[resultIndex].PackagingUnit = packagingUnitLocations[resultIndex].PackagingUnit;
|
||||
PackagingUnit packagingUnit = packagingUnitLocations[resultIndex].PackagingUnit;
|
||||
// ResultState UNKNOWN = 0; OK = 1; NOT_OK = 2;
|
||||
result[resultIndex].ResultState = 1;
|
||||
result[resultIndex].Messages = new List<ExternalControlResultMessage> { };
|
||||
|
||||
string[] resultValues;
|
||||
|
||||
matBinfilters[0].value = packagingUnitLocations[resultIndex].PackagingUnit.UID;
|
||||
int imsapiResult = imsapi.mlGetMaterialBinData(sessionContext, stationNumber, matBinfilters, attributes, SmtContainer.MINIMAL_INFORMATION, out resultValues);
|
||||
|
||||
if (imsapiResult < 0 || imsapiResult == 1) // 1 = no data found
|
||||
{
|
||||
// Packaging Units unknown in MES.Suite must be rejected
|
||||
// Error, Packaging Unit not found in mes.suite
|
||||
result[resultIndex].ResultState = 2;
|
||||
ExternalControlResultMessage message = new ExternalControlResultMessage();
|
||||
message.Message = "PackagingUnit '" + packagingUnitLocations[resultIndex].PackagingUnit.UID + "' unknown in iTAC.MES.Suite";
|
||||
result[resultIndex].Messages = new List<ExternalControlResultMessage> { message };
|
||||
}
|
||||
else
|
||||
{
|
||||
// find any differences in quantities and update the values in MES.Suite
|
||||
SmtContainer knownContainer = new ImsApiMapTool<SmtContainer>().getStruct(typeof(SmtContainer), SmtContainer.MINIMAL_INFORMATION, resultValues);
|
||||
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Information, serializer.serialize(knownContainer).ToString());
|
||||
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "quantityMaster=" + quantityMaster);
|
||||
adjustQuantity(quantityMaster, ref knownContainer, ref packagingUnit, ref updateQtyList);
|
||||
|
||||
// any differences in mslLevel?
|
||||
if (mslLevelCheck)
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "mslLevelCheck=true");
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, String.Format("UID: {0} MsdLevel(ASM): {1}, MslLevel(iTAC): {2}", packagingUnit.UID, packagingUnit.MsdLevel, knownContainer.mslLevel));
|
||||
|
||||
if (!knownContainer.mslLevel.ToLower().Equals(MslLevel.toString(packagingUnit.MsdLevel)))
|
||||
{
|
||||
// failure, wrong MslLevel
|
||||
result[resultIndex].ResultState = 2;
|
||||
ExternalControlResultMessage message = new ExternalControlResultMessage();
|
||||
message.Message = String.Format("PackagingUnit {0} has MsdLevel {1} in SetupCenter, but Level {2} in iTAC.MES.Suite",
|
||||
packagingUnit.UID, MslLevel.toString(packagingUnit.MsdLevel), knownContainer.mslLevel);
|
||||
result[resultIndex].Messages = new List<ExternalControlResultMessage> { message };
|
||||
}
|
||||
// continue with next container
|
||||
continue;
|
||||
}
|
||||
|
||||
// any differences in msl state?
|
||||
if (mslMaster == ConfigCode.SIMM)
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "mslMaster=" + mslMaster.ToString());
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, String.Format("UID: {0} MsdOpen(ASM): {1}, MslState(iTAC): {2}", packagingUnit.UID, isMsdOpen(packagingUnit.MsdOpenDate), knownContainer.mslState));
|
||||
|
||||
// iTAC states : C = geschützt / verschweißt(Closed) O = ungeschützt / offen(Open) B = in der Rücktrocknung (Baking)
|
||||
// ASM closed: MsdOpenDate = 2.1.1900
|
||||
Imsapi. KeyValue[] mslEventParams = new Imsapi. KeyValue[] { new Imsapi.KeyValue("BOOK_DATE", getImsApiDateString(packagingUnit.MsdOpenDate)) };
|
||||
Imsapi. KeyValue[] mslStopEventParams = new Imsapi.KeyValue[] { new Imsapi.KeyValue("BOOK_DATE", "-1") };
|
||||
string[] mslObjectKeys = new String[] { "ERROR_CODE", "MATERIAL_BIN_NUMBER" };
|
||||
string[] mslObjectValues = new String[] { "0", packagingUnit.UID };
|
||||
string[] mslResultValues = new String[] { };
|
||||
|
||||
if (knownContainer.mslState.Equals("C") && isMsdOpen(packagingUnit.MsdOpenDate))
|
||||
{
|
||||
// closed in iTAC, open in ASM--> required to open in iTAC!!!
|
||||
int mslStartExpirationCode = imsapi.mslStartObjectExpiration(sessionContext, stationNumber, mslEventParams, mslObjectKeys, mslObjectValues, out mslResultValues);
|
||||
if (mslStartExpirationCode < 0)
|
||||
{
|
||||
result[resultIndex].ResultState = 2;
|
||||
ExternalControlResultMessage message = new ExternalControlResultMessage();
|
||||
message.Message = String.Format("PackagingUnit {0} not opened in iTAC.MES.Suite", packagingUnit.UID);
|
||||
result[resultIndex].Messages = new List<ExternalControlResultMessage> { message };
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (knownContainer.mslState.Equals("O") && !isMsdOpen(packagingUnit.MsdOpenDate) && packagingUnit.MsdOpenDate.Ticks > DateTime.MinValue.Ticks)
|
||||
{
|
||||
// open in iTAC, closed in ASM--> required to close in iTAC!!!
|
||||
int mslStopExpirationCode = imsapi.mslStopObjectExpiration(sessionContext, stationNumber, mslStopEventParams, mslObjectKeys, mslObjectValues, out mslResultValues);
|
||||
if (mslStopExpirationCode < 0)
|
||||
{
|
||||
result[resultIndex].ResultState = 2;
|
||||
ExternalControlResultMessage message = new ExternalControlResultMessage();
|
||||
message.Message = String.Format("PackagingUnit {0} not closed in iTAC.MES.Suite", packagingUnit.UID);
|
||||
result[resultIndex].Messages = new List<ExternalControlResultMessage> { message };
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (mslMaster == ConfigCode.MES)
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Warning, "this mode is currently not supported!");
|
||||
}
|
||||
|
||||
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "expirationMaster=" + expirationMaster.ToString());
|
||||
if (!adjustExpiration(expirationMaster, ref knownContainer, ref packagingUnit, ref imsapi, ref result[resultIndex]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// SiMM-Corrections
|
||||
if (packagingUnit.MsdOpenDate <= new DateTime(1900, 01, 01)) { packagingUnit.MsdOpenDate = DateTime.MinValue.ToUniversalTime(); }
|
||||
if (packagingUnit.ConsumptionDate <= new DateTime(1900, 01, 01)) { packagingUnit.ConsumptionDate = DateTime.MinValue.ToUniversalTime(); }
|
||||
if (packagingUnit.ExpiryDate <= new DateTime(1900, 01, 01)) { packagingUnit.ExpiryDate = DateTime.MinValue.ToUniversalTime(); }
|
||||
if (packagingUnit.LastProductionDate <= new DateTime(1900, 01, 01)) { packagingUnit.LastProductionDate = DateTime.MinValue.ToUniversalTime(); }
|
||||
if (packagingUnit.ManufacturerDate <= new DateTime(1900, 01, 01)) { packagingUnit.ManufacturerDate = DateTime.MinValue.ToUniversalTime(); }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (quantityMaster == ConfigCode.SIMM && updateQtyList.Count > 0)
|
||||
{
|
||||
MaterialBinBooking[] matBinBookingArray = new MaterialBinBooking[updateQtyList.Count];
|
||||
updateQtyList.CopyTo(matBinBookingArray, 0);
|
||||
string[] materialBinBookingUploadValues = new ImsApiMapTool<MaterialBinBooking>().getValueArray(matBinBookingArray, MaterialBinBooking.MAXIMAL_INFORMATION); ;
|
||||
string[] materialBinBookingsResultValues = null;
|
||||
int retUpdateQty = imsapi.mlUploadMaterialBinBooking(sessionContext, stationNumber, MaterialBinBooking.MAXIMAL_INFORMATION, materialBinBookingUploadValues, out materialBinBookingsResultValues);
|
||||
}
|
||||
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Information, serializer.serialize(result).ToString());
|
||||
return result;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// Fehler, keine weitere info vorhanden, da die Applikation nicht läuft
|
||||
return new ExternalControlResult[0];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void adjustQuantity(ConfigCode quantityMaster, ref SmtContainer knownContainer, ref PackagingUnit packagingUnit, ref LinkedList<MaterialBinBooking> updateQtyList)
|
||||
{
|
||||
if (quantityMaster == ConfigCode.SIMM)
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, String.Format("UID: {0} Qty(ASM): {1}, Qty(iTAC): {2}", packagingUnit.UID, packagingUnit.Quantity, knownContainer.materialBinQuantityActual));
|
||||
if (packagingUnit.Quantity != knownContainer.materialBinQuantityActual)
|
||||
{
|
||||
// udpate the MES with the quantity from ASM
|
||||
MaterialBinBooking matBinBooking = new MaterialBinBooking();
|
||||
matBinBooking.materialBinNumber = packagingUnit.UID;
|
||||
matBinBooking.transactionCode = transactionCode.ToString();
|
||||
matBinBooking.materialBinQuantityActual = packagingUnit.Quantity;
|
||||
updateQtyList.AddLast(matBinBooking);
|
||||
}
|
||||
}
|
||||
else if (quantityMaster == ConfigCode.MES)
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, String.Format("UID: {0} Qty(ASM): {1}, Qty(iTAC): {2}", packagingUnit.UID, packagingUnit.Quantity, knownContainer.materialBinQuantityActual));
|
||||
if (packagingUnit.Quantity != knownContainer.materialBinQuantityActual)
|
||||
{
|
||||
packagingUnit.Quantity = knownContainer.materialBinQuantityActual;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public bool adjustExpiration(ConfigCode expirationMaster, ref SmtContainer knownContainer, ref PackagingUnit packagingUnit, ref IIMSApi imsapi, ref ExternalControlResult result)
|
||||
{
|
||||
if (expirationMaster == ConfigCode.SIMM)
|
||||
{
|
||||
if (packagingUnit.ExpiryDate == DateTime.MinValue)
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, String.Format("UID: {0} no expiration set", packagingUnit.UID));
|
||||
return true;
|
||||
}
|
||||
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, String.Format("UID: {0} expiryDate(ASM): {1}, expirationDate(iTAC): {2}", packagingUnit.UID, packagingUnit.ExpiryDate, knownContainer.expirationDate));
|
||||
if (expirationDateDifferent(packagingUnit.ExpiryDate, knownContainer.expirationDate))
|
||||
{
|
||||
// update expirationDate in iTAC
|
||||
Imsapi. KeyValue[] keyValueArray = new Imsapi.KeyValue[1];
|
||||
keyValueArray[0] = new Imsapi.KeyValue("EXPIRATION_DATE_FINAL", getImsApiDateString(packagingUnit.ExpiryDate));
|
||||
int changeBinResult = imsapi.mlChangeMaterialBinData(sessionContext, stationNumber, packagingUnit.UID, keyValueArray);
|
||||
if (changeBinResult < 0)
|
||||
{
|
||||
// reject container
|
||||
result.ResultState = 2;
|
||||
ExternalControlResultMessage message = new ExternalControlResultMessage();
|
||||
message.Message = String.Format("PackagingUnit {0} expiration date final not updated in iTAC.MES.Suite", packagingUnit.UID);
|
||||
result.Messages = new List<ExternalControlResultMessage> { message };
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (expirationMaster == ConfigCode.MES)
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Warning, "this mode is currently not supported!");
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public string getImsApiDateString(DateTime expiryDate)
|
||||
{
|
||||
if (expiryDate.Ticks >= lastItacTimeTicks)
|
||||
{
|
||||
return "32535212399000";
|
||||
}
|
||||
if (expiryDate.Ticks <= firstItacTimeTicks)
|
||||
{
|
||||
return "0";
|
||||
}
|
||||
|
||||
return expiryDate.ToUniversalTime().Subtract(
|
||||
new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)
|
||||
).TotalMilliseconds.ToString();
|
||||
}
|
||||
|
||||
public bool expirationDateDifferent(DateTime expiryDate, DateTime expirationDate)
|
||||
{
|
||||
// both values after 30.12.3000 00:00:00 --> same...
|
||||
if (expiryDate.Day >= 30 && expiryDate.Month >= 12 && expiryDate.Year >= 3000 &&
|
||||
expirationDate.Day >= 30 && expirationDate.Month >= 12 && expirationDate.Year >= 3000) { return false; }
|
||||
return expiryDate.Ticks != expirationDate.Ticks;
|
||||
}
|
||||
|
||||
public bool isMsdOpen(DateTime msdOpenDate)
|
||||
{
|
||||
return (msdOpenDate.Ticks > msdOpenTime);
|
||||
}
|
||||
|
||||
public List<ExternalControlResult> GetPackagingUnitControlStatus(List<PackagingUnitLocation> packagingUnitLocations)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public List<ExternalControlResult> GetNewPackagingUnitData(List<PackagingUnitLocation> packagingUnitLocations)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using com.itac.mes.imsapi;
|
||||
|
||||
namespace com.itac.mes.imsapi.data
|
||||
{
|
||||
public class SmtContainer
|
||||
{
|
||||
|
||||
public static string[] MAXIMAL_INFORMATION = new string[] { "MATERIAL_BIN_NUMBER", "EXPIRATION_DATE", "MATERIAL_BIN_DATE_CODE",
|
||||
"MATERIAL_BIN_PART_NUMBER", "MATERIAL_BIN_STATE", "SUPPLIER_CHARGE_NUMBER", "DATE_CREATED",
|
||||
"PART_COST", "PART_COST_BASE", "STORAGE_DESC", "STORAGE_NUMBER", "RECEIVING_NUMBER", "SUPPLIER_NAME", "SUPPLIER_NUMBER",
|
||||
"CLASSIFICATION", "MSL_STATE", "MSL_LEVEL", "MSL_DRY_END_DATE", "MSL_OPEN_DATE", "HU_NUMBER",
|
||||
"MATERIAL_BIN_QTY_ACTUAL", "MATERIAL_BIN_QTY_TOTAL"};
|
||||
|
||||
public static string[] MINIMAL_INFORMATION = new string[] { "MATERIAL_BIN_NUMBER", "EXPIRATION_DATE", "MATERIAL_BIN_STATE",
|
||||
"MSL_STATE", "MSL_LEVEL", "MSL_DRY_END_DATE", "MSL_OPEN_DATE", "MATERIAL_BIN_QTY_ACTUAL" };
|
||||
|
||||
[ImsApiKey(Key = "MATERIAL_BIN_NUMBER")]
|
||||
public string materialBinNumber { get; set; }
|
||||
[ImsApiKey(Key = "MATERIAL_BIN_QTY_ACTUAL")]
|
||||
public int materialBinQuantityActual = 0;
|
||||
[ImsApiKey(Key = "MATERIAL_BIN_QTY_TOTAL")]
|
||||
public int quantity = 0;
|
||||
[ImsApiKey(Key = "ERROR_CODE")]
|
||||
public int errorCode = 0;
|
||||
[ImsApiKey(Key = "EXPIRATION_DATE")]
|
||||
public DateTime expirationDate;
|
||||
[ImsApiKey(Key = "DATE_CREATED")]
|
||||
public DateTime dateCreated;
|
||||
[ImsApiKey(Key = "MSL_DRY_END_DATE")]
|
||||
public DateTime mslDryEndDate;
|
||||
[ImsApiKey(Key = "MSL_OPEN_DATE")]
|
||||
public DateTime mslOpenDate;
|
||||
[ImsApiKey(Key = "MATERIAL_BIN_DATE_CODE")]
|
||||
public string materialBinDateCode;
|
||||
[ImsApiKey(Key = "MATERIAL_BIN_PART_NUMBER")]
|
||||
public string materialBinPartNumber;
|
||||
[ImsApiKey(Key = "MATERIAL_BIN_STATE")]
|
||||
public string materialBinState;
|
||||
[ImsApiKey(Key = "SUPPLIER_CHARGE_NUMBER")]
|
||||
public string supplierChargeNumber;
|
||||
[ImsApiKey(Key = "PART_COST")]
|
||||
public string partCost;
|
||||
[ImsApiKey(Key = "PART_COST_BASE")]
|
||||
public string partCostBase;
|
||||
[ImsApiKey(Key = "STORAGE_DESC")]
|
||||
public string storageDesc;
|
||||
[ImsApiKey(Key = "STORAGE_NUMBER")]
|
||||
public string storageNumber;
|
||||
[ImsApiKey(Key = "RECEIVING_NUMBER")]
|
||||
public string receivingNumber;
|
||||
[ImsApiKey(Key = "SUPPLIER_NAME")]
|
||||
public string supplierName;
|
||||
[ImsApiKey(Key = "SUPPLIER_NUMBER")]
|
||||
public string supplierNumber;
|
||||
[ImsApiKey(Key = "CLASSIFICATION")]
|
||||
public string classification;
|
||||
[ImsApiKey(Key = "MSL_STATE")]
|
||||
public string mslState;
|
||||
[ImsApiKey(Key = "MSL_LEVEL")]
|
||||
public string mslLevel;
|
||||
[ImsApiKey(Key = "HU_NUMBER")]
|
||||
public string huNumber;
|
||||
|
||||
public int CompareTo(MaterialBinBooking obj)
|
||||
{
|
||||
if (materialBinNumber == null) return -1;
|
||||
if (obj == null) return 1;
|
||||
return materialBinNumber.CompareTo(obj.materialBinNumber);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Itac.Oib
|
||||
{
|
||||
public interface IReceiver
|
||||
{
|
||||
void StartReceiver();
|
||||
|
||||
void StopReceiver();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,456 @@
|
||||
#region Namespace
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.ServiceProcess;
|
||||
using System.Threading;
|
||||
using com.itac.mes.tools;
|
||||
using Itac.Oib;
|
||||
using Asm.As.Oib.Client;
|
||||
using com.itac.mes.imsapi.client.dotnet;
|
||||
using com.itac.mes.imsapi.domain.container;
|
||||
using Imsapi = com.itac.mes.imsapi.domain.container;
|
||||
using System.Security.Principal;
|
||||
using com.itac.mes.simm;
|
||||
using com.itac.mes.imsapi;
|
||||
#endregion
|
||||
|
||||
namespace com.itac.mes.proxy.winservice
|
||||
{
|
||||
|
||||
public class WindowsService : ServiceBase
|
||||
{
|
||||
#region Fields
|
||||
|
||||
/// <summary>
|
||||
/// Der Linienname ergibt sich aus der SetupCenter Konfiguration. Es darf nur eine Linie geben.
|
||||
/// </summary>
|
||||
private OibClient _oibClient;
|
||||
private static List<tools.KeyValue> versionList;
|
||||
|
||||
|
||||
private static IMSApiDotNet imsapi = null;
|
||||
private IMSApiSessionValidationStruct sessValData = new IMSApiSessionValidationStruct();
|
||||
private IMSApiSessionContextStruct newSessionContext = null;
|
||||
|
||||
|
||||
private IIMSApi imsapiproxy = null;
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Static Methods
|
||||
|
||||
private static string GetVersionNr()
|
||||
{
|
||||
var asm = Assembly.GetExecutingAssembly();
|
||||
var asmName = asm.GetName();
|
||||
|
||||
object[] attribs = asm.GetCustomAttributes(typeof(AssemblyProductAttribute), true);
|
||||
string productName = String.Empty;
|
||||
|
||||
if (attribs.Length > 0)
|
||||
{
|
||||
var asmProduct = attribs[0] as AssemblyProductAttribute;
|
||||
productName = asmProduct.Product;
|
||||
}
|
||||
string aVersion = String.Format("{1}.{2}.{3}.{4}",
|
||||
productName, asmName.Version.Major, asmName.Version.Minor, asmName.Version.Build, asmName.Version.Revision);
|
||||
string vers = String.Format("{0} - Version: {1}", productName, aVersion);
|
||||
return (vers);
|
||||
}
|
||||
|
||||
private static string GetFileVersionNr()
|
||||
{
|
||||
var asm = Assembly.GetExecutingAssembly();
|
||||
|
||||
object[] attribs = asm.GetCustomAttributes(typeof(AssemblyProductAttribute), true);
|
||||
string productName = String.Empty;
|
||||
var assembly = Assembly.GetExecutingAssembly();
|
||||
if (attribs.Length > 0)
|
||||
{
|
||||
var asmProduct = attribs[0] as AssemblyProductAttribute;
|
||||
productName = asmProduct.Product;
|
||||
}
|
||||
|
||||
var fvi = FileVersionInfo.GetVersionInfo(assembly.Location);
|
||||
// string version = fvi.ProductVersion;
|
||||
versionList.Add(new tools.KeyValue() { key = productName, value = fvi.ProductVersion });
|
||||
string version = String.Format("FileVersion: {1}", productName, fvi.ProductVersion);
|
||||
|
||||
|
||||
String[] xVersion = fvi.Comments.Split();
|
||||
String[] mesVersion = xVersion[3].Split('=');
|
||||
versionList.Add(new tools.KeyValue() { key = mesVersion[0], value = mesVersion[1] });
|
||||
String[] intfVersion = xVersion[4].Split('=');
|
||||
versionList.Add(new tools.KeyValue() { key = intfVersion[0],value = intfVersion[1] });
|
||||
return (version);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Public Constructor for WindowsService.
|
||||
/// - Put all of your Initialization code here.
|
||||
/// </summary>
|
||||
public WindowsService()
|
||||
{
|
||||
ServiceName = Constants.SERVICE_NAME;
|
||||
EventLog.Log = "EVENT_TYPE";
|
||||
|
||||
// These Flags set whether or not to handle that specific
|
||||
// type of event. Set to true if you need it, false otherwise.
|
||||
CanHandlePowerEvent = true;
|
||||
CanHandleSessionChangeEvent = true;
|
||||
CanPauseAndContinue = true;
|
||||
CanShutdown = true;
|
||||
CanStop = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The Main Thread: This is where your Service is Run.
|
||||
/// </summary>
|
||||
static void Main()
|
||||
{
|
||||
AppDomain.CurrentDomain.UnhandledException += (sender, e) =>
|
||||
{
|
||||
if (e.IsTerminating)
|
||||
{
|
||||
object o = e.ExceptionObject;
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, "### general exception handling ###");
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, o.ToString());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var service = new WindowsService();
|
||||
#if (SERVICE)
|
||||
ServiceBase.Run(service);
|
||||
#else
|
||||
service.OnStart(null);
|
||||
Console.ReadLine();
|
||||
service.OnStop();
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// OnStart(): Put startup code here
|
||||
/// - Start threads, get inital data, etc.
|
||||
/// </summary>
|
||||
/// <param name="args"></param>
|
||||
protected override void OnStart(string[] args)
|
||||
{
|
||||
InitService();
|
||||
base.OnStart(args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// OnStop(): Put your stop code here
|
||||
/// - Stop threads, set final data, etc.
|
||||
/// </summary>
|
||||
protected override void OnStop()
|
||||
{
|
||||
ShutdownService();
|
||||
base.OnStop();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// OnShutdown(): Called when the System is shutting down
|
||||
/// - Put code here when you need special handling
|
||||
/// of code that deals with a system shutdown, such
|
||||
/// as saving special data before shutdown.
|
||||
/// </summary>
|
||||
protected override void OnShutdown()
|
||||
{
|
||||
ShutdownService();
|
||||
base.OnShutdown();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dieser Adapter übernimmt die Steuerung der Subscriptions und der Endpoints
|
||||
/// </summary>
|
||||
private StatisticWorker statisticWorker;
|
||||
private Thread statisticThread;
|
||||
|
||||
private void InitService()
|
||||
{
|
||||
// Ausgabe hilfe für xml-Messages
|
||||
|
||||
var config = new AppSettingsReader();
|
||||
try
|
||||
{
|
||||
#if (SERVICE)
|
||||
TraceListener eventLogTraceListener = new EventLogTraceListener(Constants.SERVICE_NAME);
|
||||
eventLogTraceListener.Filter = new EventTypeFilter(SourceLevels.Information);
|
||||
LogHandler.addListener(eventLogTraceListener);
|
||||
#endif
|
||||
// Der Port an dem der Adapter auf eingehende Verbindungen des iTAC DataInterface lauscht
|
||||
|
||||
Asm.As.Oib.Client.Configuration.OibClientConfiguration oibClientconfiguration = new Asm.As.Oib.Client.Configuration.OibClientConfiguration();
|
||||
// PRE: _oibClient = new OibClient("iTac", "OibAdapter", oibCoreComuputerName, configuredLineFullPath);
|
||||
oibClientconfiguration.ApplicationName = "SIMMApplication";
|
||||
oibClientconfiguration.CompanyName = "iTac";
|
||||
// TODO is not necessary to set
|
||||
|
||||
oibClientconfiguration.EventNotificationProtocol = new Asm.As.Oib.Client.Configuration.EventNotificationProtocol();
|
||||
oibClientconfiguration.OibClientMode = Asm.As.Oib.Client.Configuration.OibClientMode.MaterialManager;
|
||||
|
||||
oibClientconfiguration.TcpPortSharingEnabled = true;
|
||||
// TODO: check this value
|
||||
oibClientconfiguration.UnsubscribeCoreEventsOnShutdown = true;
|
||||
|
||||
|
||||
|
||||
var clusterNodes = (String)config.GetValue("itac.artes.clusterNodes", typeof(String));
|
||||
var stationNumber = (String)config.GetValue("stationNumber", typeof(String));
|
||||
var client = (String)config.GetValue("client", typeof(String));
|
||||
var transactionCode = (int)config.GetValue("transactionCode", typeof(int));
|
||||
|
||||
oibClientconfiguration.FactoryElementPath = (String)config.GetValue("factoryElementPathMes", typeof(String));
|
||||
|
||||
// diese Werte werden alle benötigt...
|
||||
oibClientconfiguration.CoreComputerName = (String)config.GetValue("OIBCoreHostName", typeof(String));
|
||||
oibClientconfiguration.SetupCenterExternalControlCallbackPort = (int)config.GetValue("SetupCenterExternalControlPort", typeof(int));
|
||||
|
||||
// check values for those 3 settings (off, MES, SiMM);
|
||||
|
||||
ConfigCode quantityMaster = ConfigCode.OFF;
|
||||
ConfigCode mslMaster = ConfigCode.OFF;
|
||||
ConfigCode expirationMaster = ConfigCode.OFF;
|
||||
try
|
||||
{
|
||||
quantityMaster = GetCode((String)config.GetValue("QuantityMaster", typeof(String)), "QuantityMaster");
|
||||
mslMaster = GetCode((String)config.GetValue("MSLMaster", typeof(String)), "MSLMaster");
|
||||
expirationMaster = GetCode((String)config.GetValue("ExpirationMaster", typeof(String)), "ExpirationMaster");
|
||||
}
|
||||
catch (ArgumentException ae)
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, getHeadertext("iTAC.SiMM.Application Startup Problem"));
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, ae.Message);
|
||||
return;
|
||||
}
|
||||
|
||||
string sEmptyContainerCheckInterval = (string)config.GetValue("emptyContainerCheckInterval", typeof(string));
|
||||
TimeSpan emptyContainerCheckInterval = new TimeSpan(0);
|
||||
try
|
||||
{
|
||||
emptyContainerCheckInterval = TimeSpan.Parse(sEmptyContainerCheckInterval);
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, getHeadertext("iTAC.SiMM.Application Startup Problem"));
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, "invalid value " + sEmptyContainerCheckInterval + " for configParameter emptyContainerCheckInterval");
|
||||
return;
|
||||
}
|
||||
catch (OverflowException)
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, getHeadertext("iTAC.SiMM.Application Startup Problem"));
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, "invalid value " + sEmptyContainerCheckInterval + " for configParameter emptyContainerCheckInterval");
|
||||
return;
|
||||
}
|
||||
if (emptyContainerCheckInterval.Ticks == 0)
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "checking MES for empty containers switched OFF by configuration value");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (emptyContainerCheckInterval.TotalSeconds < ContainerCheckThread.MIN_INTERVAL_SECONDS)
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, getHeadertext("iTAC.SiMM.Application Startup Problem"));
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "minimum value for checking MES for empty containers is " + ContainerCheckThread.MIN_INTERVAL_SECONDS
|
||||
+ " seconds, but configured is " + emptyContainerCheckInterval.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "checking MES for empty containers " + emptyContainerCheckInterval.ToString());
|
||||
// create and start appropriate thread
|
||||
|
||||
}
|
||||
|
||||
|
||||
// check that the process is started as administrator or end process with message
|
||||
WindowsIdentity identity = WindowsIdentity.GetCurrent();
|
||||
WindowsPrincipal principal = new WindowsPrincipal(identity);
|
||||
if (!principal.IsInRole(WindowsBuiltInRole.Administrator))
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, getHeadertext("iTAC.SiMM.Application Startup Problem"));
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, "");
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, "Insufficient privileges!");
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, "This process needs to be started with administrative privileges.");
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, "Right click on the executable file and select \"Run As Administrator\"");
|
||||
return;
|
||||
}
|
||||
|
||||
versionList = new List<tools.KeyValue>();
|
||||
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Information, getHeadertext("iTAC.SIMM.Application"));
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Information, GetVersionNr() + " / " + GetFileVersionNr());
|
||||
|
||||
|
||||
IMSApiDotNet.setProperty("itac.appid", "iTAC_SIMM_Application");
|
||||
IMSApiDotNet.setProperty("itac.artes.clusternodes", clusterNodes);
|
||||
|
||||
imsapi = IMSApiDotNet.loadLibrary();
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Information, getHeadertext("IMS API"));
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "start Initializing IMS API " + clusterNodes);
|
||||
|
||||
int result = imsapi.imsapiInit();
|
||||
if (result != IMSApiDotNetConstants.RES_OK)
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Error, "IMS API initialization failed " + clusterNodes + ": " + result);
|
||||
return;
|
||||
}
|
||||
|
||||
// read values for 'in' and 'inout' arguments
|
||||
sessValData.stationNumber = stationNumber;
|
||||
sessValData.stationPassword = "";
|
||||
sessValData.user = "";
|
||||
sessValData.password = "";
|
||||
sessValData.client = client;
|
||||
sessValData.registrationType = "S";
|
||||
sessValData.systemIdentifier = "iTAC.SIMM";
|
||||
|
||||
result = imsapi.regLogin(sessValData, out newSessionContext);
|
||||
if (result != IMSApiDotNetConstants.RES_OK)
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Error, "IMS API regLogin failed: " + result);
|
||||
return;
|
||||
}
|
||||
|
||||
ImsApiProxy proxy = new ImsApiProxy(imsapi);
|
||||
imsapiproxy = (IIMSApi)proxy.GetTransparentProxy();
|
||||
|
||||
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "IMS API initialized");
|
||||
|
||||
|
||||
var loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies();
|
||||
foreach (Assembly assembly in loadedAssemblies)
|
||||
{
|
||||
if (assembly.FullName.StartsWith("AsmApi"))
|
||||
{
|
||||
AssemblyProductAttribute adAttr = (AssemblyProductAttribute)Attribute.GetCustomAttribute(assembly, typeof(AssemblyProductAttribute));
|
||||
versionList.Add(new tools.KeyValue() { key = "AsmApi", value = adAttr.Product });
|
||||
Console.WriteLine("AsmApi" + adAttr.Product);
|
||||
}
|
||||
}
|
||||
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Information, getHeadertext("Simm Application Startup"));
|
||||
_oibClient = new OibClient(oibClientconfiguration);
|
||||
|
||||
/// listener auf externalcontrol bauen
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Information, getHeadertext("SetupCenterExternalControl"));
|
||||
var oibSetupCenterExternalControlEvents = _oibClient.GetOibSetupCenterExternalControlEvents();
|
||||
|
||||
var setupCenterNotificationClient = _oibClient.GetSetupCenterNotificationClient();
|
||||
|
||||
SetupCenterExternalControlReceiver externalcontrolReceiver = new SetupCenterExternalControlReceiver(oibSetupCenterExternalControlEvents, imsapiproxy, newSessionContext,
|
||||
stationNumber, transactionCode, quantityMaster, mslMaster, expirationMaster);
|
||||
externalcontrolReceiver.StartReceiver();
|
||||
|
||||
// create and start appropriate thread
|
||||
if (emptyContainerCheckInterval.TotalSeconds >= 10)
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Information, getHeadertext("iTAC.SiMM.Application startup container check thread"));
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "checking MES for empty containers interval: " + emptyContainerCheckInterval.ToString());
|
||||
ContainerCheckThread ctt = new ContainerCheckThread(emptyContainerCheckInterval, imsapiproxy, newSessionContext, setupCenterNotificationClient, stationNumber);
|
||||
ctt.Start();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
HashSet<string> versionKeySet = new HashSet<string>();
|
||||
versionKeySet.Add("ServiceLocator");
|
||||
versionKeySet.Add("SIPLACE.SetupCenter.MaterialControl");
|
||||
/* var serviceLocator = _oibClient.GetSubscriptionManagerClient();
|
||||
var allServices = serviceLocator.GetAllServices();
|
||||
for (int i = 0; i < allServices.Length; i++)
|
||||
{
|
||||
var sd = allServices[i];
|
||||
if (versionKeySet.Contains(sd.ServiceName) && sd.Configuration != null)
|
||||
{
|
||||
versionList.Add(new KeyValue() { key = sd.ServiceName, value = sd.ServiceVersion });
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
String currentPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "current path = " + currentPath);
|
||||
|
||||
var proxyVersions = _oibClient.GetOibProxyVersions();
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Information, getHeadertext("SIMM Proxy Versions"));
|
||||
foreach (var keyValuePair in proxyVersions)
|
||||
{
|
||||
if (!keyValuePair.Key.Equals("AsmApi"))
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Information, string.Format("{0,-50} {1,10}", keyValuePair.Key, keyValuePair.Value));
|
||||
}
|
||||
}
|
||||
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Information, getHeadertext("Statistic Thread"));
|
||||
try
|
||||
{
|
||||
statisticWorker = new StatisticWorker();
|
||||
statisticWorker.setVersionList(versionList);
|
||||
statisticThread = new Thread(statisticWorker.DoWork);
|
||||
statisticThread.Start();
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "Statistic thread started! ");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, "Statistic thread NOT started!", e);
|
||||
}
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Information, getHeadertext("Initialization completed"));
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, "Initialization failed! " + e.Message, e);
|
||||
}
|
||||
}
|
||||
|
||||
private ConfigCode GetCode(string sCodeValue, string sParameterName)
|
||||
{
|
||||
foreach (ConfigCode configCode in Enum.GetValues(typeof(ConfigCode)))
|
||||
{
|
||||
if (configCode.ToString().Equals(sCodeValue.ToUpper()))
|
||||
{
|
||||
return configCode;
|
||||
}
|
||||
}
|
||||
throw new ArgumentException("The value " + sCodeValue + " is invalid for the parameter " + sParameterName);
|
||||
}
|
||||
|
||||
private string getHeadertext(string v)
|
||||
{
|
||||
String separator = "-----------------------------------------------------------------------";
|
||||
if (separator.Length < v.Length)
|
||||
{
|
||||
return separator.Substring(0, 10) + " " + v;
|
||||
}
|
||||
else
|
||||
{
|
||||
return separator.Substring(0, 10) + " " + v + " " + separator.Substring(0, separator.Length - v.Length);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void ShutdownService()
|
||||
{
|
||||
statisticWorker.RequestStop();
|
||||
statisticThread.Join();
|
||||
if (_oibClient != null)
|
||||
_oibClient.Dispose();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Configuration.Install;
|
||||
using System.Diagnostics;
|
||||
using System.ServiceProcess;
|
||||
using com.itac.mes.tools;
|
||||
|
||||
|
||||
namespace com.itac.mes.proxy.winservice
|
||||
{
|
||||
[RunInstaller(true)]
|
||||
public class WindowsServiceInstaller : Installer
|
||||
{
|
||||
/// <summary>
|
||||
/// Public Constructor for WindowsServiceInstaller.
|
||||
/// - Put all of your Initialization code here.
|
||||
/// </summary>
|
||||
public WindowsServiceInstaller()
|
||||
{
|
||||
ServiceProcessInstaller serviceProcessInstaller = new ServiceProcessInstaller();
|
||||
ServiceInstaller serviceInstaller = new ServiceInstaller();
|
||||
|
||||
//# Service Account Information
|
||||
serviceProcessInstaller.Account = ServiceAccount.LocalSystem;
|
||||
serviceProcessInstaller.Username = null;
|
||||
serviceProcessInstaller.Password = null;
|
||||
|
||||
//# Service Information
|
||||
serviceInstaller.DisplayName = "SERVICE_DESC";
|
||||
serviceInstaller.StartType = ServiceStartMode.Automatic;
|
||||
|
||||
//# This must be identical to the WindowsService.ServiceBase name
|
||||
//# set in the constructor of WindowsService.cs
|
||||
serviceInstaller.ServiceName = Constants.SERVICE_NAME;
|
||||
this.Installers.Add(serviceProcessInstaller);
|
||||
this.Installers.Add(serviceInstaller);
|
||||
}
|
||||
|
||||
public override void Install(System.Collections.IDictionary stateSaver)
|
||||
{
|
||||
base.Install(stateSaver);
|
||||
ServiceController controller = new ServiceController(Constants.SERVICE_NAME);
|
||||
try
|
||||
{
|
||||
controller.Start();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (!EventLog.SourceExists(Constants.SERVICE_NAME))
|
||||
{
|
||||
EventLog.CreateEventSource(Constants.SERVICE_NAME, "EVENT_TYPE");
|
||||
}
|
||||
EventLog.WriteEntry(Constants.SERVICE_NAME, "@The service could not be started. Error: " + e.Message, EventLogEntryType.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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
Reference in New Issue
Block a user