public HidAttributes GetHidAttributes(SafeFileHandle safeFileHandle) { var isSuccess = HidD_GetAttributes(safeFileHandle, out var hidAttributes); _ = WindowsHelpers.HandleError(isSuccess, $"Could not get Hid Attributes (Call {nameof(HidD_GetAttributes)})", Logger); return(hidAttributes); }
private WindowsUsbInterface GetInterface(SafeFileHandle interfaceHandle) { //TODO: We need to get the read/write size from a different API call... //TODO: Where is the logger/tracer? var isSuccess = WinUsbApiCalls.WinUsb_QueryInterfaceSettings(interfaceHandle, 0, out var interfaceDescriptor); var retVal = new WindowsUsbInterface(interfaceHandle, interfaceDescriptor.bInterfaceNumber, Logger, ReadBufferSizeProtected, WriteBufferSizeProtected); _ = WindowsHelpers.HandleError(isSuccess, "Couldn't query interface", Logger); Logger.LogInformation( "Found Interface Number: {interfaceNumber} Endpoint count: {endpointCount} Class: {class} Subclass: {subClass}", interfaceDescriptor.bInterfaceNumber, interfaceDescriptor.bNumEndpoints, interfaceDescriptor.bInterfaceClass, interfaceDescriptor.bInterfaceSubClass); for (byte i = 0; i < interfaceDescriptor.bNumEndpoints; i++) { isSuccess = WinUsbApiCalls.WinUsb_QueryPipe(interfaceHandle, 0, i, out var pipeInfo); _ = WindowsHelpers.HandleError(isSuccess, "Couldn't query endpoint", Logger); Logger.LogInformation("Found PipeId: {pipeId} PipeType: {pipeType} MaxPacketSize: {maxPacketSize}", pipeInfo.PipeId, pipeInfo.PipeType, pipeInfo.MaximumPacketSize); //TODO: We are dropping the max packet size here... retVal.UsbInterfaceEndpoints.Add(new WindowsUsbInterfaceEndpoint(pipeInfo.PipeId, pipeInfo.PipeType, pipeInfo.MaximumPacketSize)); } return(retVal); }
private void UpdateFileAssociationsButtonState() { if (CurrentOS.IsWindows) { #if WIN32 btnAssociateFiles.Visible = true; btnAssociateFiles.Enabled = true; var fileAssociation = new TangraFileAssociations(); if (fileAssociation.Registered) { btnAssociateFiles.Text = "Re-Associate files with Tangra"; } else { btnAssociateFiles.Text = "Associate files with Tangra"; if (!fileAssociation.CanRegisterWithoutElevation) { btnAssociateFiles.FlatStyle = FlatStyle.System; WindowsHelpers.SendMessage(btnAssociateFiles.Handle, WindowsHelpers.BCM_SETSHIELD, 0, (IntPtr)1); } } if (fileAssociation.CanRegisterWithoutElevation) { btnAssociateFiles.Tag = fileAssociation; } #endif } else { btnAssociateFiles.Visible = false; } }
public object Convert(object value, Type targetType, object parameter, string language) { if (_elementTheme == ElementTheme.Dark) { return((bool)value ? WindowsHelpers.GetSolidColorBrush("#FF5C7AB7") : WindowsHelpers.GetSolidColorBrush("#FF232323")); } return((bool)value ? WindowsHelpers.GetSolidColorBrush("#FFC6D8FB") : WindowsHelpers.GetSolidColorBrush("#FFd4e1ee")); }
private void InitializeSettings() { if (!WindowsHelpers.IsSupportedVirtualDesktopVersion()) { Logger.Instance.LogMessage(TracingLevel.INFO, $"Invalid Virtual Desktop Version"); Connection.SetTitleAsync("Update\nWindows"); return; } FetchAllVirtualDesktops(); }
private void RemoteService_ShutdownRequested(object sender, ShutdownRequestedEventArgs e) { if ((DateTime.Now - _lastShutdownRequest).TotalSeconds < 30) { return; } _exit = true; WindowsHelpers.Shutdown(); Application.Exit(); }
/// <summary> /// Sets the icon image source /// </summary> public void SetIconImageSource() { try { IconImageSource = IconSource == null ? null : WindowsHelpers.GetIconOrThumbnail(IconSource, ShellThumbnailSize.Small).ToImageSource(); IconImageSource?.Freeze(); } catch (Exception ex) { Logger.Warn(ex, "Getting jump list icon image source"); } }
private static ConnectedDeviceDefinition GetDeviceDefinition(SafeFileHandle defaultInterfaceHandle, string deviceId, ILogger logger) { var bufferLength = (uint)Marshal.SizeOf(typeof(USB_DEVICE_DESCRIPTOR)); #pragma warning disable IDE0059 // Unnecessary assignment of a value var isSuccess2 = WinUsbApiCalls.WinUsb_GetDescriptor(defaultInterfaceHandle, WinUsbApiCalls.DEFAULT_DESCRIPTOR_TYPE, 0, WinUsbApiCalls.EnglishLanguageID, out var _UsbDeviceDescriptor, bufferLength, out var lengthTransferred); #pragma warning restore IDE0059 // Unnecessary assignment of a value _ = WindowsHelpers.HandleError(isSuccess2, "Couldn't get device descriptor", logger); string productName = null; string serialNumber = null; string manufacturer = null; if (_UsbDeviceDescriptor.iProduct > 0) { productName = WinUsbApiCalls.GetDescriptor( defaultInterfaceHandle, _UsbDeviceDescriptor.iProduct, "Couldn't get product name", logger); } if (_UsbDeviceDescriptor.iSerialNumber > 0) { serialNumber = WinUsbApiCalls.GetDescriptor( defaultInterfaceHandle, _UsbDeviceDescriptor.iSerialNumber, "Couldn't get serial number", logger); } if (_UsbDeviceDescriptor.iManufacturer > 0) { manufacturer = WinUsbApiCalls.GetDescriptor( defaultInterfaceHandle, _UsbDeviceDescriptor.iManufacturer, "Couldn't get manufacturer", logger); } return(new ConnectedDeviceDefinition( deviceId, DeviceType.Usb, productName: productName, serialNumber: serialNumber, manufacturer: manufacturer, vendorId: _UsbDeviceDescriptor.idVendor, productId: _UsbDeviceDescriptor.idProduct, writeBufferSize: _UsbDeviceDescriptor.bMaxPacketSize0, readBufferSize: _UsbDeviceDescriptor.bMaxPacketSize0 )); }
/// <summary> /// Gets the image source for the specified path /// </summary> /// <param name="path">The path to get the image source for</param> /// <returns>The image source</returns> private static ImageSource GetImageSource(FileSystemPath path) { lock (IconCache) { if (IconCache.ContainsKey(path.FullPath)) { return(IconCache[path.FullPath]); } ImageSource image = WindowsHelpers.GetIconOrThumbnail(path, ShellThumbnailSize.Small).ToImageSource(); image.Freeze(); IconCache.Add(path.FullPath, image); return(image); } }
internal static string GetDescriptor(SafeFileHandle defaultInterfaceHandle, byte index, string errorMessage, ILogger logger) { logger ??= NullLogger.Instance; var buffer = new byte[256]; var isSuccess = WinUsb_GetDescriptor(defaultInterfaceHandle, USB_STRING_DESCRIPTOR_TYPE, index, EnglishLanguageID, buffer, (uint)buffer.Length, out var transfered); if (WindowsHelpers.HandleError(isSuccess, errorMessage, logger, false) != 0) { logger.LogWarning(errorMessage); return(null); } var descriptor = new string(Encoding.Unicode.GetChars(buffer, 2, (int)transfered)); return(descriptor.Substring(0, descriptor.Length - 1)); }
public HidCollectionCapabilities GetHidCapabilities(SafeFileHandle readSafeFileHandle) { var isSuccess = HidD_GetPreparsedData(readSafeFileHandle, out var pointerToPreParsedData); _ = WindowsHelpers.HandleError(isSuccess, "Could not get pre parsed data", Logger); var result = HidP_GetCaps(pointerToPreParsedData, out var hidCollectionCapabilities); if (result != HIDP_STATUS_SUCCESS) { throw new ApiException($"Could not get Hid capabilities. Return code: {result}"); } isSuccess = HidD_FreePreparsedData(ref pointerToPreParsedData); _ = WindowsHelpers.HandleError(isSuccess, "Could not release handle for getting Hid capabilities", Logger); return(hidCollectionCapabilities); }
public void CreateURLShortcut(FileSystemPath shortcutName, FileSystemPath destinationDirectory, string targetURL) { try { // Make sure the file extension is correct or else Windows won't treat it as an URL shortcut shortcutName = shortcutName.ChangeFileExtension(new FileExtension(".url")); // Delete if a shortcut with the same name already exists DeleteFile(destinationDirectory + shortcutName); // Create the shortcut WindowsHelpers.CreateURLShortcut(shortcutName, destinationDirectory, targetURL); } catch (Exception ex) { Logger.Warn(ex, "Creating URL shortcut {0}", destinationDirectory); throw; } }
public async Task OpenRegistryKeyAsync(string registryKeyPath) { if (!RegistryHelpers.KeyExists(registryKeyPath)) { await Message.DisplayMessageAsync(Resources.File_RegKeyNotFound, Resources.File_RegKeyNotFoundHeader, MessageType.Error); return; } try { WindowsHelpers.OpenRegistryPath(registryKeyPath); Logger.Debug("The Registry key path {0} was opened", registryKeyPath); } catch (Exception ex) { Logger.Error(ex, "Opening Registry key path {0}", registryKeyPath); await Message.DisplayExceptionMessageAsync(ex, Resources.File_OpenRegKeyError, Resources.File_OpenRegKeyErrorHeader); } }
/// <summary> /// Opens the specified path in Explorer /// </summary> /// <param name="location">The path</param> public async Task OpenExplorerLocationAsync(FileSystemPath location) { if (!location.Exists) { await Services.MessageUI.DisplayMessageAsync(Resources.File_LocationNotFound, Resources.File_OpenLocationErrorHeader, MessageType.Error); return; } try { WindowsHelpers.OpenExplorerPath(location); RL.Logger?.LogDebugSource($"The explorer location {location} was opened"); } catch (Exception ex) { ex.HandleError("Opening explorer location", location); await Services.MessageUI.DisplayExceptionMessageAsync(ex, Resources.File_OpenLocationError, Resources.File_OpenLocationErrorHeader); } }
/// <summary> /// Opens the specified registry key path in RegEdit /// </summary> /// <param name="registryKeyPath">The key path to open</param> /// <returns>The task</returns> public async Task OpenRegistryKeyAsync(string registryKeyPath) { if (!RegistryHelpers.KeyExists(registryKeyPath)) { await Services.MessageUI.DisplayMessageAsync(Resources.File_RegKeyNotFound, Resources.File_RegKeyNotFoundHeader, MessageType.Error); return; } try { WindowsHelpers.OpenRegistryPath(registryKeyPath); RL.Logger?.LogDebugSource($"The Registry key path {registryKeyPath} was opened"); } catch (Exception ex) { ex.HandleError("Opening Registry key path", registryKeyPath); await Services.MessageUI.DisplayExceptionMessageAsync(ex, Resources.File_OpenRegKeyError, Resources.File_OpenRegKeyErrorHeader); } }
public async Task OpenExplorerLocationAsync(FileSystemPath location) { if (!location.Exists) { await Message.DisplayMessageAsync(Resources.File_LocationNotFound, Resources.File_OpenLocationErrorHeader, MessageType.Error); return; } try { WindowsHelpers.OpenExplorerPath(location); Logger.Debug("The explorer location {0} was opened", location); } catch (Exception ex) { Logger.Error(ex, "Opening explorer location {0}", location); await Message.DisplayExceptionMessageAsync(ex, Resources.File_OpenLocationError, Resources.File_OpenLocationErrorHeader); } }
/// <summary> /// Creates a file shortcut /// </summary> public void CreateFileShortcut(FileSystemPath ShortcutName, FileSystemPath DestinationDirectory, FileSystemPath TargetFile, string arguments = null) { try { // Make sure the file extension is correct or else Windows won't treat it as a shortcut ShortcutName = ShortcutName.ChangeFileExtension(new FileExtension(".lnk")); // Delete if a shortcut with the same name already exists DeleteFile(DestinationDirectory + ShortcutName); // Create the shortcut WindowsHelpers.CreateFileShortcut(ShortcutName, DestinationDirectory, TargetFile, arguments); RL.Logger?.LogInformationSource($"The shortcut {ShortcutName} was created"); } catch (Exception ex) { ex.HandleUnexpected("Creating shortcut", DestinationDirectory); throw; } }
public async override void KeyPressed(KeyPayload payload) { Logger.Instance.LogMessage(TracingLevel.INFO, $"Key Pressed {this.GetType()}"); if (!WindowsHelpers.IsSupportedVirtualDesktopVersion()) { Logger.Instance.LogMessage(TracingLevel.INFO, $"Key Pressed but invalid Virtual Desktop Version"); await Connection.SetTitleAsync("Update\nWindows"); await Connection.ShowAlert(); return; } if (SwitchVirtualDesktop()) { await Connection.ShowOk(); } else { await Connection.ShowAlert(); } }
public void CreateFileShortcut(FileSystemPath ShortcutName, FileSystemPath DestinationDirectory, FileSystemPath TargetFile, string arguments = null) { try { // Make sure the file extension is correct or else Windows won't treat it as a shortcut ShortcutName = ShortcutName.ChangeFileExtension(new FileExtension(".lnk")); // Delete if a shortcut with the same name already exists DeleteFile(DestinationDirectory + ShortcutName); // Create the shortcut WindowsHelpers.CreateFileShortcut(ShortcutName, DestinationDirectory, TargetFile, arguments); Logger.Info("The shortcut {0} was created", ShortcutName); } catch (Exception ex) { Logger.Warn(ex, "Creating shortcut {0}", DestinationDirectory); throw; } }
static AppViewModel() { // Get the current Window version WindowsVersion = WindowsHelpers.GetCurrentWindowsVersion(); }
/// <summary> /// Searches the Win32 program shortcuts for matching game install directories /// </summary> /// <param name="shortcuts">The shortcut paths</param> /// <param name="programShortcutGameFinders">The shortcut game finders</param> /// <param name="programShortcutFinders">The shortcut finders</param> /// <returns>The task</returns> protected virtual async Task SearchWin32ShortcutsAsync(IEnumerable <string> shortcuts, List <GameFinderItemContainer> programShortcutGameFinders, List <FinderItem> programShortcutFinders) { // Enumerate each program foreach (var shortcut in shortcuts) { // Get the file name var file = Path.GetFileNameWithoutExtension(shortcut); // Make sure we got a file if (file == null) { continue; } // Check matches towards other finder items foreach (var finderItem in programShortcutFinders.Where(x => file.IndexOf(x.ShortcutName, StringComparison.CurrentCultureIgnoreCase) > -1).ToArray()) { FileSystemPath targetDir; try { // Attempt to get the shortcut target path targetDir = WindowsHelpers.GetShortCutTarget(shortcut).Parent; } catch (Exception ex) { ex.HandleUnexpected("Getting start menu item shortcut target for game finder", shortcut); continue; } // Add the item var added = AddItem(finderItem, targetDir); // Remove if added if (added) { programShortcutFinders.Remove(finderItem); } } // Handle each game match foreach (var gameMatch in programShortcutGameFinders.Where(x => file.IndexOf(x.FinderItem.ShortcutName, StringComparison.CurrentCultureIgnoreCase) > -1).ToArray()) { FileSystemPath targetDir; try { // Attempt to get the shortcut target path targetDir = WindowsHelpers.GetShortCutTarget(shortcut).Parent; } catch (Exception ex) { ex.HandleUnexpected("Getting start menu item shortcut target for game finder", shortcut); continue; } // Add the game var added = await AddGameAsync(gameMatch, targetDir); // Remove if added if (added) { programShortcutGameFinders.Remove(gameMatch); } } // Break if no more games needed to be found if (!programShortcutGameFinders.Any() && !programShortcutFinders.Any()) { break; } } }
private void Initialize() { using var logScope = Logger.BeginScope("DeviceId: {deviceId} Call: {call}", DeviceId, nameof(Initialize)); try { Close(); int errorCode; if (string.IsNullOrEmpty(DeviceId)) { throw new ValidationException( $"{nameof(ConnectedDeviceDefinition)} must be specified before {nameof(InitializeAsync)} can be called."); } _DeviceHandle = APICalls.CreateFile(DeviceId, FileAccessRights.GenericWrite | FileAccessRights.GenericRead, APICalls.FileShareRead | APICalls.FileShareWrite, IntPtr.Zero, APICalls.OpenExisting, APICalls.FileAttributeNormal | APICalls.FileFlagOverlapped, IntPtr.Zero); if (_DeviceHandle.IsInvalid) { //TODO: is error code useful here? errorCode = Marshal.GetLastWin32Error(); if (errorCode > 0) { throw new ApiException($"Device handle no good. Error code: {errorCode}"); } } Logger.LogInformation(Messages.SuccessMessageGotWriteAndReadHandle); var isSuccess = WinUsbApiCalls.WinUsb_Initialize(_DeviceHandle, out var interfaceHandle); _ = WindowsHelpers.HandleError(isSuccess, Messages.ErrorMessageCouldntIntializeDevice, Logger); #pragma warning disable CA2000 //We need to hold on to this handle var defaultInterfaceHandle = new SafeFileHandle(interfaceHandle, false); #pragma warning restore CA2000 var connectedDeviceDefinition = GetDeviceDefinition(defaultInterfaceHandle, DeviceId, Logger); if (!WriteBufferSizeProtected.HasValue) { if (!connectedDeviceDefinition.WriteBufferSize.HasValue) { throw new ValidationException("Write buffer size not specified"); } WriteBufferSizeProtected = (ushort)connectedDeviceDefinition.WriteBufferSize.Value; } if (!ReadBufferSizeProtected.HasValue) { if (!connectedDeviceDefinition.ReadBufferSize.HasValue) { throw new ValidationException("Read buffer size not specified"); } ReadBufferSizeProtected = (ushort)connectedDeviceDefinition.ReadBufferSize.Value; } //Get the first (default) interface #pragma warning disable CA2000 //Ths should be disposed later var defaultInterface = GetInterface(defaultInterfaceHandle); UsbInterfaces.Add(defaultInterface); byte i = 0; while (true) { isSuccess = WinUsbApiCalls.WinUsb_GetAssociatedInterface(defaultInterfaceHandle, i, out var interfacePointer); if (!isSuccess) { errorCode = Marshal.GetLastWin32Error(); if (errorCode == APICalls.ERROR_NO_MORE_ITEMS) { break; } throw new ApiException( $"Could not enumerate interfaces for device. Error code: {errorCode}"); } var associatedInterface = GetInterface(interfacePointer); //TODO: this is bad design. The handler should be taking care of this UsbInterfaces.Add(associatedInterface); i++; } RegisterDefaultInterfaces(); #pragma warning restore CA2000 } catch (Exception ex) { Logger.LogError(ex, Messages.ErrorMessageCouldntIntializeDevice); throw; } }
public Page_Games_GameViewModel GetDisplayViewModel() { try { if (IsAdded) { var actions = new List <OverflowButtonItemViewModel>(); // Get the manager var manager = Game.GetManager(Game.GetGameType()); // Add launch options if set to do so if (Game.GetLaunchMode() == UserData_GameLaunchMode.AsAdminOption) { actions.Add(new OverflowButtonItemViewModel(Resources.GameDisplay_RunAsAdmin, GenericIconKind.GameDisplay_Admin, new AsyncRelayCommand(async() => await Game.GetManager().LaunchGameAsync(true)))); actions.Add(new OverflowButtonItemViewModel()); } // Get the Game links var links = GetGameFileLinks?.Where(x => x.Path.FileExists).ToArray(); // Add links if there are any if (links?.Any() ?? false) { actions.AddRange(links. Select(x => { // Get the path string path = x.Path; // Create the command var command = new AsyncRelayCommand(async() => (await Services.File.LaunchFileAsync(path, arguments: x.Arguments))?.Dispose()); if (x.Icon != GenericIconKind.None) { return(new OverflowButtonItemViewModel(x.Header, x.Icon, command)); } try { return(new OverflowButtonItemViewModel(x.Header, WindowsHelpers.GetIconOrThumbnail(x.Path, ShellThumbnailSize.Small).ToImageSource(), command)); } catch (Exception ex) { Logger.Error(ex, "Getting file icon for overflow button item"); return(new OverflowButtonItemViewModel(x.Header, x.Icon, command)); } })); actions.Add(new OverflowButtonItemViewModel()); } // Get additional items var additionalItems = manager.GetAdditionalOverflowButtonItems; // Add the items if there are any if (additionalItems.Any()) { actions.AddRange(additionalItems); actions.Add(new OverflowButtonItemViewModel()); } // Add RayMap link if (RayMapURL != null) { actions.Add(new OverflowButtonItemViewModel(Resources.GameDisplay_Raymap, GenericIconKind.GameDisplay_Map, new AsyncRelayCommand(async() => (await Services.File.LaunchFileAsync(RayMapURL))?.Dispose()))); actions.Add(new OverflowButtonItemViewModel()); } // Add open archive if (HasArchives) { actions.Add(new OverflowButtonItemViewModel(Resources.GameDisplay_Archives, GenericIconKind.GameDisplay_Archive, new AsyncRelayCommand(async() => { using IArchiveDataManager archiveDataManager = GetArchiveDataManager; try { // Show the archive explorer await Services.UI.ShowArchiveExplorerAsync(archiveDataManager, GetArchiveFilePaths(Game.GetInstallDir()).Where(x => x.FileExists).ToArray()); } catch (Exception ex) { Logger.Error(ex, "Archive explorer"); await Services.MessageUI.DisplayExceptionMessageAsync(ex, Resources.Archive_CriticalError); } }), UserLevel.Advanced)); } // Add open location actions.Add(new OverflowButtonItemViewModel(Resources.GameDisplay_OpenLocation, GenericIconKind.GameDisplay_Location, new AsyncRelayCommand(async() => { // Get the install directory var instDir = Game.GetInstallDir(); // Select the file in Explorer if it exists if ((instDir + DefaultFileName).FileExists) { instDir += DefaultFileName; } // Open the location await Services.File.OpenExplorerLocationAsync(instDir); Logger.Trace("The Game {0} install location was opened", Game); }), UserLevel.Advanced)); actions.Add(new OverflowButtonItemViewModel(UserLevel.Advanced)); // Add Game options var optionsAction = new OverflowButtonItemViewModel(Resources.GameDisplay_Options, GenericIconKind.GameDisplay_Config, new AsyncRelayCommand(async() => { Logger.Trace("The Game {0} options dialog is opening...", Game); await GameOptionsDialog.ShowAsync(Game); })); actions.Add(optionsAction); return(new Page_Games_GameViewModel( game: Game, displayName: DisplayName, iconSource: IconSource, isDemo: IsDemo, mainAction: new ActionItemViewModel(Resources.GameDisplay_Launch, GenericIconKind.GameDisplay_Play, new AsyncRelayCommand(async() => await Game.GetManager().LaunchGameAsync(false))), secondaryAction: optionsAction, launchActions: actions)); } else { var actions = new List <OverflowButtonItemViewModel>(); OverflowButtonItemViewModel downloadItem = null; if (CanBeDownloaded) { downloadItem = new OverflowButtonItemViewModel(Resources.GameDisplay_CloudInstall, GenericIconKind.GameDisplay_Download, new AsyncRelayCommand(async() => await DownloadGameAsync())); if (CanBeLocated) { actions.Add(downloadItem); actions.Add(new OverflowButtonItemViewModel()); } } // Get the purchase links var links = Game. // Get all available managers GetManagers(). // Get the purchase links SelectMany(x => x.GetGamePurchaseLinks); // Add links actions.AddRange(links. Select(x => { // Get the path string path = x.Path; // Create the command var command = new AsyncRelayCommand(async() => (await Services.File.LaunchFileAsync(path))?.Dispose()); // Return the item return(new OverflowButtonItemViewModel(x.Header, x.Icon, command)); })); // Add disc installer options for specific Games if (CanBeInstalledFromDisc) { // Add separator if there are previous actions if (actions.Any()) { actions.Add(new OverflowButtonItemViewModel()); } // Add disc installer action actions.Add(new OverflowButtonItemViewModel(Resources.GameDisplay_DiscInstall, GenericIconKind.GameDisplay_DiscInstall, new AsyncRelayCommand(async() => { // Show and run the installer await Services.DialogBaseManager.ShowDialogWindowAsync(new GameInstaller_Window(Game)); }))); } // If the last option is a separator, remove it if (actions.LastOrDefault()?.IsSeparator == true) { actions.RemoveAt(actions.Count - 1); } // Create the main action var mainAction = CanBeLocated ? new ActionItemViewModel(Resources.GameDisplay_Locate, GenericIconKind.GameDisplay_Location, new AsyncRelayCommand(async() => await LocateGameAsync())) : downloadItem; // Return the view model return(new Page_Games_GameViewModel(Game, DisplayName, IconSource, IsDemo, mainAction, null, actions)); } } catch (Exception ex) { Logger.Fatal(ex, "Getting game display view model"); throw; } }