static void FindAddins(string strPath, Dictionary<string, GXProtocolAddIn> protocols) { // Iterate through all dlls in this path DirectoryInfo di = new DirectoryInfo(strPath); //If directory not exists. if (!di.Exists) { return; } List<string> foundProtocols = new List<string>(protocols.Keys); //If application domain is already created. if (!string.IsNullOrEmpty(AppDomain.CurrentDomain.RelativeSearchPath)) { GXProxyClass pc = new GXProxyClass(); foreach (FileInfo file in di.GetFiles("*.dll")) { // Load the assembly so we can query for info about it. if (file.Name.StartsWith("Interop.") || file.Name.StartsWith("AxInterop.")) { continue; } pc.ImportProtocolAddIns(strPath, file.FullName, foundProtocols); } foreach (string it in pc.Assemblies) { Assembly asm = Assembly.LoadFile(it); } foreach (string it in pc.Protocols) { Assembly asm = Assembly.LoadFile(it); FindProtocolAddIns(protocols, asm); } } else { // Create an Application Domain: string pathToDll = typeof(GXDeviceList).Assembly.CodeBase; AppDomainSetup domainSetup = new AppDomainSetup { PrivateBinPath = pathToDll }; System.AppDomain td = AppDomain.CreateDomain("FindAddinsDomain", null, domainSetup); GXProxyClass pc = (GXProxyClass)(td.CreateInstanceFromAndUnwrap(pathToDll, typeof(GXProxyClass).FullName)); foreach (FileInfo file in di.GetFiles("*.dll")) { // Load the assembly so we can query for info about it. if (file.Name.StartsWith("Interop.") || file.Name.StartsWith("AxInterop.")) { continue; } pc.ImportProtocolAddIns(strPath, file.FullName, foundProtocols); } List<string> assemblies = pc.Assemblies; List<string> protocols2 = pc.Protocols; // Unload the application domain: System.AppDomain.Unload(td); AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve); foreach (string it in assemblies) { Assembly asm = Assembly.LoadFile(it); } foreach (string it in protocols2) { Assembly asm = Assembly.LoadFile(it); FindProtocolAddIns(protocols, asm); } AppDomain.CurrentDomain.AssemblyResolve -= new ResolveEventHandler(CurrentDomain_AssemblyResolve); } }
/// <summary> /// Add new device profile. /// </summary> /// <param name="request"></param> /// <returns></returns> public GXDeviceProfilesUpdateResponse Post(GXDeviceProfilesUpdateRequest request) { List <GXEventsItem> events = new List <GXEventsItem>(); GXAmiDeviceProfile DeviceProfiles = null; lock (Db) { using (var trans = Db.OpenTransaction(IsolationLevel.ReadCommitted)) { string filename = Path.GetTempFileName(); using (FileStream stream = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None)) { BinaryWriter w = new BinaryWriter(stream); w.Write(request.Data); } string pathToDll = this.GetType().Assembly.CodeBase; // Create an Application Domain: AppDomainSetup domainSetup = new AppDomainSetup { PrivateBinPath = pathToDll }; System.AppDomain td = null; string dir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + Path.DirectorySeparatorChar); //Try to load device template and unload assmbly. try { td = AppDomain.CreateDomain("TestDomain", null, domainSetup); GXProxyClass pc = (GXProxyClass)(td.CreateInstanceFromAndUnwrap(pathToDll, typeof(GXProxyClass).FullName)); if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } byte[] data; string addInType, assemblyName; List <object[]> items = pc.Import(filename, dir, out data, out assemblyName, out addInType); ulong DeviceProfileID = 0; ulong categoryTemplateID = 0; ulong propertyTemplateID = 0; ulong tableTemplateID = 0; int version = 0; foreach (object[] it in items) { if (it[1] is GXAmiDeviceProfile) { DeviceProfiles = it[1] as GXAmiDeviceProfile; events.Add(new GXEventsItem(ActionTargets.DeviceProfile, Actions.Add, DeviceProfiles)); //Find new version number for the template. foreach (GXAmiDeviceProfile dt in Db.Select <GXAmiDeviceProfile>(q => q.Guid == DeviceProfiles.Guid)) { if (dt.ProfileVersion > version) { version = dt.ProfileVersion; } } ++version; DeviceProfiles.ProtocolAddInType = addInType; DeviceProfiles.ProtocolAssembly = assemblyName; DeviceProfiles.ProfileVersion = version; } else if (it[1] is GXAmiCategoryTemplate) { tableTemplateID = 0; (it[1] as GXAmiCategoryTemplate).DeviceID = DeviceProfileID; (it[1] as GXAmiCategoryTemplate).Id += DeviceProfileID << 16; (it[1] as GXAmiCategoryTemplate).TemplateVersion = version; } else if (it[1] is GXAmiDataTableTemplate) { categoryTemplateID = 0; (it[1] as GXAmiDataTableTemplate).DeviceID = DeviceProfileID; (it[1] as GXAmiDataTableTemplate).Id += DeviceProfileID << 16; (it[1] as GXAmiDataTableTemplate).TemplateVersion = version; } else if (it[1] is GXAmiPropertyTemplate) { (it[1] as GXAmiPropertyTemplate).DeviceID = DeviceProfileID; (it[1] as GXAmiPropertyTemplate).TemplateVersion = version; if (categoryTemplateID != 0) { (it[1] as GXAmiPropertyTemplate).ParentID = categoryTemplateID; } else if (tableTemplateID != 0) { (it[1] as GXAmiPropertyTemplate).ParentID = tableTemplateID; } else { throw new ArgumentOutOfRangeException("Parent ID."); } (it[1] as GXAmiPropertyTemplate).Id += DeviceProfileID << 16; } else if (it[1] is GXAmiParameterTemplate) { (it[1] as GXAmiParameterTemplate).DeviceID = DeviceProfileID; (it[1] as GXAmiParameterTemplate).TemplateVersion = version; if (it[0] is GXAmiDeviceProfile) { (it[1] as GXAmiParameterTemplate).ParentID = DeviceProfileID << 16; } else if (it[0] is GXAmiCategoryTemplate) { (it[1] as GXAmiParameterTemplate).ParentID = categoryTemplateID; } else if (it[0] is GXAmiDataTableTemplate) { (it[1] as GXAmiParameterTemplate).ParentID = tableTemplateID; } else if (it[0] is GXAmiPropertyTemplate) { (it[1] as GXAmiParameterTemplate).ParentID = propertyTemplateID; } } Db.Insert(it[1]); if (it[1] is GXAmiDeviceProfile) { #if !SS4 ulong value = (ulong)Db.GetLastInsertId(); #else ulong value = (ulong)Db.LastInsertId(); #endif (it[1] as GXAmiDeviceProfile).Id = value; DeviceProfileID = value; //Update allowed media types. foreach (GXAmiMediaType mt in (it[1] as GXAmiDeviceProfile).AllowedMediaTypes) { mt.DeviceProfileId = DeviceProfileID; Db.Insert(mt); } } else if (it[1] is GXAmiCategoryTemplate) { categoryTemplateID = (it[1] as GXAmiCategoryTemplate).Id; } else if (it[1] is GXAmiDataTableTemplate) { tableTemplateID = (it[1] as GXAmiDataTableTemplate).Id; } else if (it[1] is GXAmiPropertyTemplate) { propertyTemplateID = (it[1] as GXAmiPropertyTemplate).Id; if ((it[1] as GXAmiPropertyTemplate).Values != null && (it[1] as GXAmiPropertyTemplate).Values.Length != 0) { #if !SS4 ulong value = (ulong)Db.GetLastInsertId(); #else ulong value = (ulong)Db.LastInsertId(); #endif foreach (GXAmiValueItem vi in (it[1] as GXAmiPropertyTemplate).Values) { vi.ProfileId = DeviceProfileID; vi.PropertyId = value; Db.Insert(vi); } } } else if (it[1] is GXAmiParameterTemplate) { if ((it[1] as GXAmiParameterTemplate).Values != null && (it[1] as GXAmiParameterTemplate).Values.Length != 0) { #if !SS4 ulong value = (ulong)Db.GetLastInsertId(); #else ulong value = (ulong)Db.LastInsertId(); #endif foreach (GXAmiValueItem vi in (it[1] as GXAmiParameterTemplate).Values) { vi.ProfileId = DeviceProfileID; vi.ParameterId = value; Db.Insert(vi); } } } } //Save device template to data blocks. foreach (GXAmiDeviceProfilesDataBlock it in SplitDataToPackets(DeviceProfileID, filename)) { Db.Insert(it); } foreach (GXAmiDeviceProfilesDataBlock it in SplitDataToPackets(DeviceProfileID, filename)) { Db.Insert(it); } if (request.UserGroups != null) { foreach (long ugId in request.UserGroups) { GXAmiUserGroupDeviceProfile it = new GXAmiUserGroupDeviceProfile(); it.DeviceProfileID = DeviceProfileID; it.UserGroupID = ugId; Db.Insert(it); } } } finally { // Unload the application domain: if (td != null) { System.AppDomain.Unload(td); } if (dir != null) { try { Directory.Delete(dir, true); } catch { //It's OK if this fails. } } } trans.Commit(); } } AppHost host = this.ResolveService <AppHost>(); host.SetEvents(Db, this.Request, 0, events); return(new GXDeviceProfilesUpdateResponse(request.UserGroups, DeviceProfiles)); }