public string ExtractGame(Game game, EmulatorProfile profile = null, ExecutorLaunchProgressHandler progressHandler = null) { if (profile == null || profile.EmulatorID != game.ParentEmulator.UID) { profile = game.GetSelectedProfile(); } lock (syncRoot) { if (progressHandler != null) { progressHandler("Loading archive...", 0); } if (!loadArchive(game.CurrentDisc.Path)) { throw new ExtractException("{0} {1}", Translator.Instance.goodmergearchiveerror, game.CurrentDisc.Path); } using (extractor) { List <IArchiveEntry> entries; if (extractor.Entries == null || (entries = extractor.Entries.Where(e => !e.IsDirectory).ToList()).Count < 1) { Logger.LogError("Goodmerge: Archive '{0}' appears to be empty"); throw new ExtractException(Translator.Instance.goodmergeempty); } if (progressHandler != null) { progressHandler("Selecting file...", 0); } IArchiveEntry selectedEntry = selectEntry(entries, game.CurrentDisc.LaunchFile, profile.GetGoodmergeTags()); Logger.LogDebug("Goodmerge: Selected entry {0}", selectedEntry.FilePath); string cacheKey = string.Format("{0}****{1}", game.CurrentDisc.Path, selectedEntry.FilePath); string extractionPath; if (isInCache(cacheKey, out extractionPath)) { Logger.LogDebug("Goodmerge: Using cached file '{0}'", extractionPath); return(extractionPath); } extractionPath = Path.Combine(GoodmergeTempPath, GOODMERGE_FILENAME_PREFIX + game.Filename); string extractedFile = extractFile(extractor, selectedEntry, extractionPath, progressHandler); if (extractedFile != null) { addToCache(cacheKey, extractedFile); } return(extractedFile); } } }
/// <summary> /// Launches the specified game using the specified profile. If the specified profile is null /// the game's configured profile is used. If isConfig is true then any suspend settings are ignored /// and the specified game's playcount and playdate are not updated. /// </summary> /// <param name="game"></param> /// <param name="isConfig">Whether the game is being launched by Configuration. Default false.</param> /// <param name="profile">The profile to use when launching the game.</param> public void LaunchGame(string path, EmulatorProfile profile, ExecutorLaunchProgressHandler launchProgressChanged = null) { if (profile == null) { throw new LaunchException("Profile cannot be null"); } bool isPC = profile.EmulatorID == -1; bool isConfig = Emulators2Settings.Instance.IsConfig; ExecutorItem exeItem = new ExecutorItem(isPC); exeItem.Arguments = profile.Arguments; exeItem.Suspend = !isConfig && profile.SuspendMP == true; if (profile.DelayResume && profile.ResumeDelay > 0) { exeItem.ResumeDelay = profile.ResumeDelay; } if (isPC) { exeItem.Path = path; if (!string.IsNullOrEmpty(profile.LaunchedExe)) { try { exeItem.LaunchedExe = Path.GetFileNameWithoutExtension(profile.LaunchedExe); } catch { exeItem.LaunchedExe = profile.LaunchedExe; } } } else { exeItem.Path = profile.EmulatorPath; exeItem.RomPath = path; exeItem.Mount = profile.MountImages && DaemonTools.IsImageFile(Path.GetExtension(path)); exeItem.ShouldReplaceWildcards = !exeItem.Mount; exeItem.UseQuotes = profile.UseQuotes == true; exeItem.CheckController = profile.CheckController; exeItem.StopEmulationOnKey = profile.StopEmulationOnKey.HasValue ? profile.StopEmulationOnKey.Value : Options.Instance.GetBoolOption("domap"); exeItem.EscapeToExit = profile.EscapeToExit; } exeItem.PreCommand = new LaunchCommand() { Command = profile.PreCommand, WaitForExit = profile.PreCommandWaitForExit, ShowWindow = profile.PreCommandShowWindow }; exeItem.PostCommand = new LaunchCommand() { Command = profile.PostCommand, WaitForExit = profile.PostCommandWaitForExit, ShowWindow = profile.PostCommandShowWindow }; exeItem.Init(); //stop any media playing if (!isConfig && Options.Instance.GetBoolOption("stopmediaplayback") && MediaPortal.Player.g_Player.Playing) { Logger.LogDebug("Stopping playing media..."); MediaPortal.Player.g_Player.Stop(); } lock (launchSync) { launchGame(exeItem, launchProgressChanged); } }
void launchGame(ExecutorItem exeItem, ExecutorLaunchProgressHandler launchProgressChanged) { Dispose(); if (exeItem.Mount) { if (launchProgressChanged != null) { launchProgressChanged("Mounting...", 75); } mountImage(exeItem.RomPath); } else if (launchProgressChanged != null) { launchProgressChanged("Launching...", 75); } List <int> pIds = new List <int>(); initProc(exeItem, new EventHandler((o, e) => { onExit(exeItem, pIds); })); Logger.LogInfo("Launching with arguments '{1} {2}'", exeItem.Path, exeItem.Arguments); if (launchProgressChanged != null) { launchProgressChanged("Launching...", 100); } if (exeItem.CheckController && !ControllerHandler.CheckControllerState()) { Emulators2Settings.Instance.ShowMPDialog(Translator.Instance.nocontrollerconnected); } if (exeItem.Suspend) { suspendMP(true); //suspend MediaPortal rendering } //run pre-command exeItem.PreCommand.Run(); //if we're a launcher get id of all processes currently running with the same name so they can be excluded when looking for launched process if (!string.IsNullOrEmpty(exeItem.LaunchedExe)) { foreach (Process p in Process.GetProcessesByName(exeItem.LaunchedExe)) { pIds.Add(p.Id); } } //start emulator bool result; try { result = proc.Start(); } catch (Exception ex) { result = false; Logger.LogError("Exception starting {0} - {1}", exeItem.Path, ex.Message); } if (!result) { Logger.LogWarn("Failed to start {0}", exeItem.Path); onExit(exeItem, null, false); throw new LaunchException("{0} did not start", exeItem.Path); } //send status changed event if (StatusChanged != null) { StatusChanged(true); } //setup keyboard hook if configured and we're not launching a PC Game (they should have their own way of exiting) if (exeItem.StopEmulationOnKey) { setupKeyboardHook(exeItem.EscapeToExit); } }
string extractFile(IArchive extractor, IArchiveEntry selectedEntry, string extractionPath, ExecutorLaunchProgressHandler progressHandler = null) { if (progressHandler != null) { progressHandler("Creating directory...", 0); } if (!createExtractionDirectory(extractionPath, selectedEntry.FilePath)) { Logger.LogError("Goodmerge: Unable to find alternate extract directory, hard-coded limit has been reached - check '{0}' for any leftover files", GoodmergeTempPath); throw new ExtractException(Translator.Instance.goodmergefileerror); } Logger.LogDebug("Goodmerge: Extracting file '{0}' to directory '{1}'...", selectedEntry.FilePath, extractionPath); if (progressHandler != null) { progressHandler("Extracting...", 0); long totalSize = selectedEntry.Size; extractor.EntryExtractionBegin += (sender, e) => { Logger.LogDebug("EntryExtractionBegin {0}", e.Item.FilePath); }; extractor.FilePartExtractionBegin += (sender, e) => { Logger.LogDebug("FilePartExtractionBegin {0}, compressed: {1}kb, total: {2}kb", e.Name, e.CompressedSize / 1024, e.Size / 1024); }; extractor.CompressedBytesRead += (sender, e) => { Logger.LogDebug("CompressedBytesRead {0}, current: {1}kb, total: {2}kb", e.CurrentFilePartCompressedBytesRead / 1024, e.CompressedBytesRead / 1024); int perc = (int)((e.CurrentFilePartCompressedBytesRead * 100) / totalSize); progressHandler(string.Format("Extracting ({0}%)...", perc), perc); }; extractor.EntryExtractionEnd += (sender, e) => { Logger.LogDebug("Extraction complete {0}", e.Item.FilePath); progressHandler("Extraction complete...", 100); }; } Logger.LogDebug("Extracting {0}, {1}kb", selectedEntry.FilePath, selectedEntry.Size / 1024); string outputFile = Path.Combine(extractionPath, selectedEntry.FilePath); try { selectedEntry.WriteToFile(outputFile); } catch (Exception ex) { Logger.LogError("Goodmerge: Error extracting to directory '{0}' - {1}", extractionPath, ex.Message); throw new ExtractException(Translator.Instance.goodmergeextracterror); } return(outputFile); }