bool Invoke <T>(AADCommand command, ISerializable parameters, [NotNullWhen(true)] out T?result) where T : class, ISerializable { result = null; if (!IsConnected) { return(false); } var r = InvokeOne(command, parameters, out var result2); Debug2.Assert(r != ExecutionResult.UnknownCommand); // internal error, we should fix it switch (r) { case ExecutionResult.IOError: case ExecutionResult.Disconnect: Disconnect(); return(false); case ExecutionResult.Success: result = result2 as T; return(result is not null); default: return(false); } }
/// <summary> /// Connects to a waiting server within the specified time-out period. /// </summary> /// <param name="timeout">The number of milliseconds to wait for the client to connect before the connection times out.</param> /// <returns></returns> bool WaitForConnection(int timeout) { // TODO: timeout Debug2.Assert(!IsConnected); var stream = (NamedPipeServerStream)base.stream; stream.WaitForConnection(); return(IsConnected); }
/// <summary> /// Get the image bytes asynchronously. Must be called from the main thread, /// as the <see cref="DataPath"/> is accessed and Realm can only be used from the main /// thread. If you need to access the data from another thread, call /// <see cref="PrepareImageLoad"/> on the main thread and then call /// <see cref="PreparedImageLoad.GetDataAsync"/> on it. /// </summary> /// <returns></returns> public virtual async Task <byte[]> GetDataAsync() { var dataPath = DataPath; // DO NOT INLINE! See method documentation. Debug2.Assert(dataPath != null, $"dataPath is null for media with REST ID {IdForRestApi}"); return(await MediaCache.GetBytesAsync( IdForRestApi, async() => await fileManager.ReadFromDiskAsync(dataPath) )); }
/// <summary> /// Execute one command and return execution result /// </summary> /// <returns></returns> /// <remarks>See invoker: <seealso cref="AADClient.InvokeOne(AADCommand, ISerializable, out ISerializable?)"/></remarks> ExecutionResult ExecuteOne() { try { ReadCommand(out var command); if (command == AADCommand.Disconnect) { return(ExecutionResult.Disconnect); } if (!CommandHandlerManager.Handlers.TryGetValue(command, out var handler)) { Debug2.Assert(false); return(ExecutionResult.UnknownCommand); } // phase 1: get the handler corresponding to the command if (Activator.CreateInstance(handler.ParametersType, true) is not ISerializable parameters) { throw new InvalidOperationException("Can't create parameters object"); } // phase 2: create parameters instance Read(parameters); // phase 3: read parameters from stream bool b; ISerializable?result; try { b = handler.Execute(parameters, out result); } catch (Exception ex) { WriteCommand(AADCommand.UnhandledException); Write(new AADServerInvocationException(ex.ToFullString())); return(ExecutionResult.UnhandledException); } if (!b) { WriteCommand(AADCommand.Failure); return(ExecutionResult.Failure); } // phase 4: execute command with parameters WriteCommand(AADCommand.Success); Write(result !); // phase 5: write result to stream return(ExecutionResult.Success); } catch (Exception ex) { Debug2.Assert(ex is IOException); // regard all unhandable exceptions as IO error return(ExecutionResult.IOError); } }
void InitializeMenus() { guidToMenu = new Dictionary <Guid, List <MenuMD> >(); foreach (var item in mefMenus) { string ownerGuidString = item.Metadata.OwnerGuid ?? MenuConstants.APP_MENU_GUID; bool b = Guid.TryParse(ownerGuidString, out var ownerGuid); Debug.Assert(b, $"Menu: Couldn't parse OwnerGuid property: '{ownerGuidString}'"); if (!b) { continue; } var guidString = item.Metadata.Guid; b = Guid.TryParse(guidString, out var guid); Debug.Assert(b, $"Menu: Couldn't parse Guid property: '{guidString}'"); if (!b) { continue; } var header = item.Metadata.Header; b = !string.IsNullOrEmpty(header); Debug2.Assert(b, "Menu: Header is null or empty"); if (!b) { continue; } if (!guidToMenu.TryGetValue(ownerGuid, out var list)) { guidToMenu.Add(ownerGuid, list = new List <MenuMD>()); } list.Add(new MenuMD(item)); } foreach (var list in guidToMenu.Values) { var hash = new HashSet <Guid>(); var origList = new List <MenuMD>(list); list.Clear(); foreach (var menu in origList) { var guid = new Guid(menu.Metadata.Guid !); if (hash.Contains(guid)) { continue; } hash.Add(guid); list.Add(menu); } list.Sort((a, b) => a.Metadata.Order.CompareTo(b.Metadata.Order)); } }
private void AddContentToPage(Page dbPage, PageDto pageDto, FetchedMediaData fetchedMedia) { if (pageDto != null && dbPage != null) { PageConverter.Convert(pageDto, dbPage); switch (dbPage) { case ImagePage imagePage: var image = fetchedMedia.Images.SingleOrDefault(x => x.IdForRestApi == pageDto.Image); imagePage.Image = image ?? BackupData.BackupImage; break; case TextPage textPage: break; case TimeSliderPage timeSliderPage: var fetchedImages = fetchedMedia.Images; if (fetchedImages.Count > 0) { Debug2.Assert(timeSliderPage.SliderImages.Count == pageDto.Images.Count); for (var i = 0; i < timeSliderPage.SliderImages.Count; i++) { var imageId = pageDto.Images[i].Image; var dbImage = fetchedImages.FirstOrDefault(img => img.IdForRestApi == imageId); timeSliderPage.SliderImages[i].Image = dbImage; } } else { timeSliderPage.SliderImages.Add(new TimeSliderPageImage { Page = timeSliderPage, Image = BackupData.BackupImage }); } break; } var audio = fetchedMedia.Audios.SingleOrDefault(x => x.IdForRestApi == pageDto.Audio); if (audio != null) { dbPage.Audio = audio; } } }
/// <summary> /// Invoke one specified command with parameters /// </summary> /// <param name="command"></param> /// <param name="parameters"></param> /// <param name="result"></param> /// <returns></returns> /// <remarks>See executor: <seealso cref="AADServer.ExecuteOne"/></remarks> ExecutionResult InvokeOne(AADCommand command, ISerializable parameters, out ISerializable?result) { result = null; try { if (!CommandHandlerManager.Handlers.TryGetValue(command, out var handler)) { Debug2.Assert(false); return(ExecutionResult.UnknownCommand); } // phase 1: get the handler corresponding to the command WriteCommand(command); Write(parameters); // phase 2: write parameters to stream ReadCommand(out var resultCommand); if (resultCommand == AADCommand.UnhandledException) { var exception = new AADServerInvocationException(); Read(exception); throw exception; } if (resultCommand != AADCommand.Success) { return(ExecutionResult.Failure); } // phase 3: read execution result result = Activator.CreateInstance(handler.ResultType, true) as ISerializable; if (result is null) { throw new InvalidOperationException("Can't create result object"); } // phase 4: create result instance Read(result); // phase 5: read result from stream return(ExecutionResult.Success); } catch (AADServerInvocationException) { throw; } catch (Exception ex) { Debug2.Assert(ex is IOException); // regard all unhandable exceptions as IO error return(ExecutionResult.IOError); } }
static bool CheckEquivalent(TypeDef td) { Debug2.Assert(td != null); for (int i = 0; td != null && i < 1000; i++) { if (i != 0) { var info = GetInfo(td); if (info == null) { return(false); } } bool f; if (td.IsInterface) { f = td.IsImport || td.CustomAttributes.IsDefined("System.Runtime.InteropServices.ComEventInterfaceAttribute"); } else { f = td.IsValueType || td.IsDelegate; } if (!f) { return(false); } if (td.GenericParameters.Count > 0) { return(false); } var declType = td.DeclaringType; if (declType == null) { return(td.IsPublic); } if (!td.IsNestedPublic) { return(false); } td = declType; } return(false); }
/// <summary> /// Execute loop until disconnect /// </summary> /// <returns><see langword="true"/> if disconnected by command, <see langword="false"/> if client disconnects without sending command</returns> /// <remarks>Guarantee no exception thrown</remarks> bool Execute() { while (true) { var r = ExecuteOne(); Debug2.Assert(r != ExecutionResult.UnknownCommand); // internal error, we should fix it switch (r) { case ExecutionResult.IOError: case ExecutionResult.Disconnect: Disconnect(); return(r == ExecutionResult.Disconnect); } } }
public IEnumerable <ModuleInfo> EnumerateModules() { foreach (var client in AADExtensions.EnumerateAADClients(processId)) { var runtime = client.Runtime; foreach (var module in client.EnumerateModules()) { var peInfo = client.GetPEInfo(module); if (peInfo.IsInvalid) { // may be ngen image and corresponding IL image not loaded TODO: get native image, not IL image yield return(new DotNetModuleInfo(module.AssemblyName, unchecked ((nuint)(-1)), 0, "NGEN", module.DomainName, $"v{runtime.FileVersion}")); continue; } var layout = peInfo.LoadedLayout; Debug2.Assert(!layout.IsInvalid); yield return(new DotNetModuleInfo(module.AssemblyName, (nuint)layout.ImageBase, layout.ImageSize, peInfo.FilePath, module.DomainName, $"v{runtime.FileVersion}")); } } }
/// <summary> /// Create <see cref="AADServer"/>s in other application domains and get corresponding <see cref="AADClient"/>s /// </summary> /// <param name="clients"></param> /// <returns></returns> public bool EnableMultiDomain(out AADClient[] clients) { if (mainClient is not null) { Debug2.Assert(false, "do NOT call EnableMultiDomain in sub AADClient"); clients = Array2.Empty <AADClient>(); return(false); } if (multiDomainClients is not null) { foreach (var client in multiDomainClients) { Debug2.Assert(client.IsConnected); } clients = multiDomainClients; return(true); } clients = Array2.Empty <AADClient>(); if (!Invoke <Handlers.EnableMultiDomainHandler.PipeNames>(AADCommand.EnableMultiDomain, EmptySerializable.Instance, out var pipeNames)) { return(false); } clients = new AADClient[pipeNames.Values.Length]; for (int i = 0; i < clients.Length; i++) { var client = Create(pipeNames.Values[i], this); if (client is null) { return(false); } clients[i] = client; } multiDomainClients = clients; return(true); }
public static async Task Init() { // We do NOT use DbManager.InTransaction() here because that would attach BackupImage & BackupImageTag // to the transaction and these properties are still null at this point. var dataAccess = IoCManager.Resolve <IDataAccess>(); var fileManager = IoCManager.Resolve <IMediaFileManager>(); var dataLoader = IoCManager.Resolve <IDataLoader>(); backupImage = dataAccess.GetItems <Image>().SingleOrDefault(x => x.IdForRestApi == BackupImageIdForRestApi); backupImageTag = dataAccess.GetItems <Image>().SingleOrDefault(x => x.IdForRestApi == BackupImageTagIdForRestApi); string backupImagePath; if (backupImage == null) { backupImageData = dataLoader.LoadByteData("noImage.png"); backupImagePath = await fileManager.WriteMediaToDiskAsync(backupImageData, BackupImageIdForRestApi, BackupTimestamp); } else { backupImagePath = null; } string backupImageTagPath; if (backupImageTag == null) { var backupImageDataTag = dataLoader.LoadByteData("noImageTag.jpg"); backupImageTagPath = await fileManager.WriteMediaToDiskAsync(backupImageDataTag, BackupImageTagIdForRestApi, BackupTimestamp); } else { backupImageTagPath = null; } dataAccess.InTransaction(Enumerable.Empty <object>(), transaction => { var transactionDataAccess = transaction.DataAccess; if (backupImage == null) { backupImageData = dataLoader.LoadByteData("noImage.png"); Debug2.Assert(backupImagePath != null); transactionDataAccess.AddItem(backupImage = new Image { Title = "No Image", Description = "Hier fehlt das Bild", IdForRestApi = BackupImageIdForRestApi, DataPath = backupImagePath }); } if (backupImageTag == null) { Debug2.Assert(backupImageTagPath != null); transactionDataAccess.AddItem(backupImageTag = new Image { Title = "No Tag Image", Description = "Hier fehlt das Tag-Bild", IdForRestApi = BackupImageTagIdForRestApi, DataPath = backupImageTagPath }); } mockAudioData = dataLoader.LoadByteData("mockaudio.mp3"); return(0); }); IsInitializedSema.Release(); }
/// <summary> /// Read <see cref="ISerializable"/> instance which has simple internal layout /// </summary> /// <param name="destination"></param> /// <param name="obj"></param> /// <returns></returns> /// <remarks>Should only called by <see cref="ISerializable.Deserialize(Stream)(Stream)"/> to quick deserialize itself</remarks> public static bool Read(Stream source, ISerializable obj) { var fields = obj.GetType().GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance); foreach (var field in fields) { object?value; var fieldType = field.FieldType; switch (Type.GetTypeCode(fieldType)) { case TypeCode.Boolean: if (!Serializer.ReadBoolean(source, out bool b)) { return(false); } value = b; goto next; case TypeCode.Byte: if (!Serializer.ReadByte(source, out byte u1)) { return(false); } value = u1; goto next; case TypeCode.Int32: if (!Serializer.ReadInt32(source, out int i4)) { return(false); } value = i4; goto next; case TypeCode.UInt32: if (!Serializer.ReadUInt32(source, out uint u4)) { return(false); } value = u4; goto next; case TypeCode.Int64: if (!Serializer.ReadInt64(source, out long i8)) { return(false); } value = i8; goto next; case TypeCode.UInt64: if (!Serializer.ReadUInt64(source, out ulong u8)) { return(false); } value = u8; goto next; case TypeCode.String: if (!Serializer.ReadString(source, out var s)) { return(false); } value = s; goto next; } if (fieldType == typeof(byte[])) { if (!Serializer.ReadBytes(source, out var bin)) { return(false); } value = bin; goto next; } if (fieldType == typeof(int[])) { if (!Serializer.ReadInt32Array(source, out var i4s)) { return(false); } value = i4s; goto next; } if (fieldType == typeof(uint[])) { if (!Serializer.ReadUInt32Array(source, out var u4s)) { return(false); } value = u4s; goto next; } if (fieldType == typeof(long[])) { if (!Serializer.ReadInt64Array(source, out var i8s)) { return(false); } value = i8s; goto next; } if (fieldType == typeof(ulong[])) { if (!Serializer.ReadUInt64Array(source, out var u8s)) { return(false); } value = u8s; goto next; } if (fieldType == typeof(string[])) { if (!Serializer.ReadStringArray(source, out var ss)) { return(false); } value = ss; goto next; } if (typeof(ISerializable).IsAssignableFrom(fieldType)) { var o = (ISerializable)Activator.CreateInstance(fieldType, true); if (!Read(source, o)) { return(false); } value = o; goto next; } Debug2.Assert(false); return(false); next: field.SetValue(obj, value); } return(true); }
/// <summary> /// Write <see cref="ISerializable"/> instance which has simple internal layout /// </summary> /// <param name="destination"></param> /// <param name="obj"></param> /// <returns></returns> /// <remarks>Should only called by <see cref="ISerializable.Serialize(Stream)"/> to quick serialize itself</remarks> public static bool Write(Stream destination, ISerializable obj) { var fields = obj.GetType().GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance); foreach (var field in fields) { var value = field.GetValue(obj); switch (Type.GetTypeCode(field.FieldType)) { case TypeCode.Boolean: if (!Serializer.WriteBoolean(destination, (bool)value)) { return(false); } continue; case TypeCode.Byte: if (!Serializer.WriteByte(destination, (byte)value)) { return(false); } continue; case TypeCode.Int32: if (!Serializer.WriteInt32(destination, (int)value)) { return(false); } continue; case TypeCode.UInt32: if (!Serializer.WriteUInt32(destination, (uint)value)) { return(false); } continue; case TypeCode.Int64: if (!Serializer.WriteInt64(destination, (long)value)) { return(false); } continue; case TypeCode.UInt64: if (!Serializer.WriteUInt64(destination, (ulong)value)) { return(false); } continue; case TypeCode.String: if (!Serializer.WriteString(destination, (string)value)) { return(false); } continue; } if (value is int[] i4s) { if (!Serializer.WriteInt32Array(destination, i4s)) { return(false); } continue; } if (value is uint[] u4s) { if (!Serializer.WriteUInt32Array(destination, u4s)) { return(false); } continue; } if (value is long[] i8s) { if (!Serializer.WriteInt64Array(destination, i8s)) { return(false); } continue; } if (value is ulong[] u8s) { if (!Serializer.WriteUInt64Array(destination, u8s)) { return(false); } continue; } if (value is string[] ss) { if (!Serializer.WriteStringArray(destination, ss)) { return(false); } continue; } if (value is byte[] bin) { if (!Serializer.WriteBytes(destination, bin)) { return(false); } continue; } if (value is ISerializable o) { if (!Write(destination, o)) { return(false); } continue; } Debug2.Assert(false); return(false); } return(true); }