Esempio n. 1
0
 /// <summary>Validate the current options</summary>
 public override Exception Validate()
 {
     return
         (m_ass.Length == 0 ? new Exception($"Assembly parameter not given") :
          !Path_.FileExists(m_ass) ? new FileNotFoundException($"Assembly file '{m_ass}' not found") :
          null);
 }
Esempio n. 2
0
        public ScriptUI(Model model, string name, string filepath, Guid context_id)
        {
            InitializeComponent();
            DockControl = new DockControl(this, $"Script-{context_id}")
            {
                ShowTitle      = false,
                TabText        = name,
                TabToolTip     = filepath,
                TabCMenu       = TabCMenu(),
                DestroyOnClose = true,
            };
            LastUpdateTime  = TimeSpan.Zero;
            Context         = new Context(model, name, context_id);
            LdrAutoComplete = new View3d.AutoComplete();
            Filepath        = filepath;
            Editor          = m_editor;

            Render              = Command.Create(this, RenderInternal);
            SaveScript          = Command.Create(this, SaveScriptInternal);
            RemoveObjects       = Command.Create(this, RemoveObjectsInternal);
            CloseScript         = Command.Create(this, CloseScriptInternal);
            IndentSelection     = Command.Create(this, IndentSelectionInternal);
            CommentOutSelection = Command.Create(this, CommentOutSelectionInternal);
            UncommentSelection  = Command.Create(this, UncommentSelectionInternal);

            // If the temporary script exists, load it
            if (Path_.FileExists(Filepath))
            {
                LoadFile();
            }

            DataContext = this;
        }
        /// <summary>
        /// Initialization of the package; this method is called right after the package is sited, so this is the place
        /// where you can put all the initialization code that rely on services provided by VisualStudio.
        /// </summary>
        /// <param name="cancellationToken">A cancellation token to monitor for initialization cancellation, which can occur when VS is shutting down.</param>
        /// <param name="progress">A provider for progress updates.</param>
        /// <returns>A task representing the async work of package initialization, or an already completed task if there is none. Do not return null from this method.</returns>
        protected override void Initialize()
        {
            var root = Path_.Directory(Assembly.GetExecutingAssembly().Location);

            AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
            Assembly?CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
            {
                var path = Path_.CombinePath(root, new AssemblyName(args.Name).Name + ".dll");

                if (!Path_.FileExists(path))
                {
                    return(null);
                }
                return(Assembly.LoadFrom(path));
            }

            // When initialized asynchronously, the current thread may be a background thread at this point.
            // Do any initialization that requires the UI thread after switching to the UI thread.
            //await this.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
            base.Initialize();

            // Add our command handlers for menu
            if (GetService <IMenuCommandService>() is OleMenuCommandService mcs)
            {
                mcs.AddCommand(new AlignMenuCommand(this));
                mcs.AddCommand(new UnalignMenuCommand(this));
            }
        }
Esempio n. 4
0
        /// <summary>Load the keys data for the given username and password</summary>
        private EResult GetKeys(out XElement keys)
        {
            keys = null;

            // Get the key file name. This is an encrypted XML file
            if (!Path_.FileExists(KeysFilepath))
            {
                return(EResult.NotFound);
            }

            // Read the file contents into memory and decrypt it
            try
            {
                // This code throw a CryptographicException when the 'User' has an incorrect password.
                // This is not an error, it's just that CrytographicException are not disabled by default
                // in the debugger exception settings.
                var keys_xml = string.Empty;
                using (var fs = new FileStream(KeysFilepath, FileMode.Open, FileAccess.Read, FileShare.Read))
                    using (var cs = new CryptoStream(fs, Decryptor, CryptoStreamMode.Read))
                        using (var sr = new StreamReader(cs))
                            keys_xml = sr.ReadToEnd();

                keys = XElement.Parse(keys_xml, LoadOptions.None);
                return(EResult.Success);
            }
            catch
            {
                // If the xml is not valid, assume bad password
                return(EResult.BadPassword);
            }
        }
Esempio n. 5
0
        /// <summary>Upload a local file to the host. The remote file will be named 'remote_filename' on the host</summary>
        public void Upload(string local_filepath, string remote_filename, ResumeBehaviour resume = ResumeBehaviour.DontResume)
        {
            Trace(string.Format("Uploading: {0} to {1}/{2}/{3}", local_filepath, Settings.RemoteHost, Settings.RemotePath, remote_filename));
            Reply reply;

            // Check the local filepath exists first
            if (!Path_.FileExists(local_filepath))
            {
                throw new FileNotFoundException("Upload failed", local_filepath);
            }

            // Upload the file
            using (var input = new FileStream(local_filepath, FileMode.Open, FileAccess.Read))
            {
                if (resume != ResumeBehaviour.DontResume)
                {
                    // Some servers may not support resumed uploading.
                    long offset = RemoteFileSize(remote_filename);
                    if (SendCommand("REST " + offset).Code == Status.PendingFurtherInfo)
                    {
                        Trace("Resuming file upload from offset " + offset);
                        input.Seek(offset, SeekOrigin.Begin);
                    }
                    else if (resume == ResumeBehaviour.Resume)
                    {
                        // The caller specifically wanted resuming but it's
                        // not supported, throw so they can choose what to do.
                        Trace("Resuming not supported. Aborting.");
                        throw new NotSupportedException("Resumed upload not supported by server");
                    }
                    else
                    {
                        Trace("Resuming not supported. Restarting.");
                        input.Seek(0, SeekOrigin.Begin);
                    }
                }

                // Store the file
                reply = SendCommand("STOR " + remote_filename);
                if (reply.Code != Status.DataConnectionAlreadyOpen && reply.Code != Status.DataConnectionOpenning)
                {
                    throw new IOException(reply.Message);
                }

                // Write the file to the data channel
                using (BinaryWriter w = new BinaryWriter(ConnectDataStream()))
                    input.CopyTo(w.BaseStream);
            }

            // Confirm done
            reply = ReadReply();
            if (reply.Code != Status.DataConnectionClosing && reply.Code != Status.RequestedActionOkay)
            {
                throw new IOException(reply.Message);
            }
        }
Esempio n. 6
0
        /// <summary>Run the command</summary>
        public override int Run()
        {
            // If a file is given, load the data from it
            if (m_filepath.HasValue())
            {
                if (!Path_.FileExists(m_filepath))
                {
                    throw new Exception($"File '{m_filepath}' doesn't exist");
                }

                m_data = File.ReadAllText(m_filepath);
            }

            // If no data is available, error
            if (!m_data.HasValue())
            {
                throw new Exception("No data to generate key from");
            }

            // No private key?
            if (!m_pk.HasValue() || !Path_.FileExists(m_pk))
            {
                throw new Exception($"Private key '{m_pk}' doesn't exist");
            }

            var priv = File.ReadAllText(m_pk);
            var code = ActivationCode.Generate(m_data, priv);
            var key  = Convert.ToBase64String(code);

            // Save to the system clipboard
            if (m_outclip)
            {
                Clipboard.SetText(key);
            }

            // Save to a file
            if (m_outfile.HasValue())
            {
                key.ToFile(m_outfile);
            }

            // Write to StdOut
            Console.WriteLine(key);
            return(0);
        }
Esempio n. 7
0
            /// <summary>Notify observers about the changed items</summary>
            public bool NotifyChanged()
            {
                // Scan the directory and notify about created, deleted, or changed files
                var current_files = Path_.EnumFileSystem(Path, SearchOption.TopDirectoryOnly, exclude: FileAttributes.Hidden | FileAttributes.Directory)
                                    .Select(x => x.FullName).ToList();
                var existing = current_files
                               .ToHashSet(x => x.ToLowerInvariant());

                foreach (var path in current_files)
                {
                    // If there is an existing watcher for the file, simply check for changed
                    if (m_files.TryGetValue(path.ToLowerInvariant(), out var file))
                    {
                        // File unchanged
                        if (!file.HasChanged)
                        {
                            continue;
                        }

                        // File changed, but change not handled
                        if (!file.NotifyChanged())
                        {
                            continue;
                        }

                        // File no longer exists, remove from 'm_files'
                        if (!Path_.FileExists(file.Path))
                        {
                            m_files.Remove(file.Path.ToLowerInvariant());
                        }

                        continue;
                    }

                    // If this is a new file, notify then add
                    file = new WatchedFile(path, m_onchange, Id, m_ctx);
                    if (file.NotifyChanged())
                    {
                        m_files[path.ToLowerInvariant()] = file;
                    }
                }

                return(true);
            }
Esempio n. 8
0
        /// <summary>Load a pattern set from file</summary>
        public static PatternSet Load(string filepath)
        {
            if (!Path_.FileExists(filepath))
            {
                throw new Exception($"Pattern set file '{filepath}' does not exist");
            }

            var root = XDocument.Load(filepath).Root;

            if (root == null)
            {
                throw new Exception("Pattern set has no root xml node");
            }

            return(new PatternSet(root)
            {
                Name = Path_.FileTitle(filepath)
            });
        }
Esempio n. 9
0
        // Notes:
        //  - This is the main logic object for the ED Trade Advisor.
        //  - Generally speaking, it does the following:
        //      - Maintain the database of systems, stations, commodities, price data, etc
        //      - Monitor for changes in the player's location (using the ED journal files)
        //      - Finds the best (ish) trades around the current player location

        public Advisor(Action <Action> run_on_main_thread)
        {
            Settings.Instance.SettingChange += HandleSettingChange;
            m_marshal_to_main_thread         = run_on_main_thread;
            RebuildStaticData   = !Path_.FileExists(EliteDataProvider.Filepath);
            Shutdown            = new CancellationTokenSource();
            TradeRoutes         = new List <TradeRoute>();
            m_find_trade_routes = new AutoResetEvent(false);
            Web            = new Web(Shutdown.Token);
            Src            = new EliteDataProvider(Web, Shutdown.Token);
            JournalMonitor = new EDJournalMonitor(Shutdown.Token);

            RunOnMainThread(new Action(() =>
            {
                Settings.Instance.NotifySettingChanged(nameof(Settings.UseCurrentLocation));
                Settings.Instance.NotifySettingChanged(nameof(Settings.ReadCargoCapacityFromLoadout));
                Settings.Instance.NotifySettingChanged(nameof(Settings.ReadMaxJumpRangeFromLoadout));
            }));
        }
Esempio n. 10
0
        /// <summary>Sets and saves the ADB file path</summary>
        private void SetAdbPath(string path)
        {
            // Reject invalid paths
            if (!Path_.FileExists(path))
            {
                return;
            }

            // If hint text is shown, clear it first
            if (m_edit_adb_fullpath.ForeColor == Color.LightGray)
            {
                m_edit_adb_fullpath.ForeColor = Color.Black;
                m_edit_adb_fullpath.Text      = string.Empty;
            }

            // Only set when different
            if (m_edit_adb_fullpath.Text != path)
            {
                m_edit_adb_fullpath.Text = path;
                PopulateUsingAdb();
            }
        }
Esempio n. 11
0
        /// <summary>Load settings from AppData</summary>
        public override void LoadSettingsFromStorage()
        {
            // Note: the 'LoadSettingsFromXml' and 'SaveSettingsToXml' methods are
            // only used when the user Exports or Imports their settings.
            // To/From storage are used for normal saving.
            try
            {
                var filepath = SettingsFilepath;
                if (!Path_.FileExists(filepath))
                {
                    return;
                }

                // Load the settings XML file
                var root = XDocument.Load(filepath).Root;
                var grps = root.Elements(nameof(Groups), nameof(AlignGroup)).Select(x => x.As <AlignGroup>());
                Groups.Assign(grps);

                // Load other settings
                AlignStyle = root.Element(nameof(AlignStyle)).As <EAlignCharacters>(EAlignCharacters.Spaces);
            }
            catch { }             // Don't allow anything to throw from here, otherwise VS locks up... :-/
        }
Esempio n. 12
0
        public Licence(string lic_file)
            : this()
        {
            if (!Path_.FileExists(lic_file))
            {
                throw new FileNotFoundException($"Licence file '{lic_file}' not found");
            }

            // Load the licence file
            var root = XDocument.Load(lic_file, LoadOptions.None).Root;

            if (root == null)
            {
                throw new InvalidDataException("licence file invalid");
            }

            LicenceHolder  = root.Element(nameof(LicenceHolder)).As(LicenceHolder);
            EmailAddress   = root.Element(nameof(EmailAddress)).As(EmailAddress);
            Company        = root.Element(nameof(Company)).As(Company);
            VersionMask    = root.Element(nameof(VersionMask)).As(VersionMask);
            ActivationCode = root.Element(nameof(ActivationCode)).As(ActivationCode);
            Changed        = false;
        }
Esempio n. 13
0
        public void Execute(object _)
        {
            // Prompt for a log file
            var fd = new OpenFileDialog
            {
                Title           = "Open a Log File",
                Filter          = Constants.LogFileFilter,
                Multiselect     = false,
                CheckFileExists = true,
            };

            if (fd.ShowDialog(m_ui) != true)
            {
                return;
            }
            var filepath = fd.FileName;

            try
            {
                // Validate
                if (!Path_.FileExists(filepath))
                {
                    throw new FileNotFoundException($"File '{filepath}' does not exist");
                }

                // Add the file to the recent files
                m_ui.AddToRecentFiles(filepath);

                // Create a log data source from the log file
                m_main.LogDataSource = new SingleFileSource(filepath, m_settings);
            }
            catch (Exception ex)
            {
                m_report.ErrorPopup($"Failed to open file {filepath} due to an error.", ex);
                m_main.LogDataSource = null;
            }
        }
Esempio n. 14
0
        public Licence(string lic_file) : this()
        {
            try
            {
                if (Path_.FileExists(lic_file))
                {
                    // Load the licence file
                    var root = XDocument.Load(lic_file, LoadOptions.None).Root;
                    if (root == null)
                    {
                        throw new InvalidDataException("licence file invalid");
                    }

                    LicenceHolder  = root.Element(XmlTag.LicenceHolder).As(LicenceHolder);
                    EmailAddress   = root.Element(XmlTag.EmailAddr).As(EmailAddress);
                    Company        = root.Element(XmlTag.Company).As(Company);
                    VersionMask    = root.Element(XmlTag.VersionMask).As(VersionMask);
                    ActivationCode = root.Element(XmlTag.ActivationCode).As(ActivationCode);
                }
            }
            catch (FileNotFoundException) { Log.Write(ELogLevel.Info, "Licence file not found"); }
            catch (Exception ex) { Log.Write(ELogLevel.Error, ex, "Licence file invalid"); }
            Changed = false;
        }
Esempio n. 15
0
		/// <summary>Handle unhandled exceptions</summary>
		private static void HandleTheUnhandled(Exception ex)
		{
			var res = MsgBox.Show(null,
				$"{Application.ProductName} has shutdown with the following error.\r\n"+
				$"Error: {ex.GetType().Name}\r\n"+
				$"\r\n"+
				$"Deleting the applications settings file, '{StartupOptions?.SettingsPath ?? Path_.FileName(Settings.Default.Filepath)}', might prevent this problem.\r\n"+
				$"\r\n"+
				$"Generating a report and sending it to {Util.GetAssemblyAttribute<AssemblyCompanyAttribute>().Company} will aid in the resolution of this issue. "+
				$"The generated report is a plain text file that you can review before sending.\r\n"+
				$"\r\n"+
				$"Would you like to generate the report?\r\n"+
				$"\r\n"+
				$"Alternatively, please contact {Constants.SupportEmail} with information about this error so that it can be fixed.\r\n"+
				$"\r\n"+
				$"Apologies for any inconvenience caused.\r\n",
				"Unexpected Termination", MessageBoxButtons.YesNo, MessageBoxIcon.Error);
			if (res == DialogResult.Yes)
			{
				var dg = new SaveFileDialog{Title = "Save Crash Report", FileName = Application.ProductName+"CrashReport", Filter = Util.FileDialogFilter("Crash Report Files","*.txt", "All files","*.*"), DefaultExt = "txt", CheckPathExists = true};
				if (dg.ShowDialog() == DialogResult.OK)
				{
					var settings = "Settings filepath unknown";
					if (StartupOptions != null && Path_.FileExists(StartupOptions.SettingsPath))
						settings = File.ReadAllText(StartupOptions.SettingsPath);

					var sb = new StringBuilder()
						.Append(Application.ProductName).Append(" - Crash Report - ").Append(DateTime.UtcNow).AppendLine()
						.AppendLine("---------------------------------------------------------------")
						.AppendLine("[Unhandled Exception Type]")
						.AppendLine(ex.MessageFull())
						.AppendLine()
						.AppendLine("[Settings File Contents]")
						.AppendLine(settings)
						.AppendLine()
						.AppendLine("[General]")
						.AppendLine($"Application Version: {Util.AssemblyVersion()}")
						.AppendLine(Environment.OSVersion.VersionString)
						.AppendLine(StartupOptions?.Dump() ?? string.Empty)
						.AppendLine()
						.AppendLine("[Additional Comments]")
						.AppendLine("Any additional information about what you were doing when this crash occurred would be extremely helpful and appreciated");
					File.WriteAllText(dg.FileName, sb.ToString());

					try
					{
						if (MsgBox.Show(null, "Preview the report before sending?", "Review Report", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
						Process.Start(dg.FileName);
					} catch {}

					try
					{
						// Try to create an email with the attachment ready to go
						var email = new MailMessage();
						email.From = new MailAddress(Constants.SupportEmail);
						email.To.Add(Constants.SupportEmail);
						email.Subject = $"{Util.AppProductName} crash report";
						email.Priority = MailPriority.Normal;
						email.IsBodyHtml = false;
						email.Body =
							$"To {Util.AppCompany},\r\n" +
							$"\r\n" +
							$"Attached is a crash report generated on {DateTime.Now}.\r\n" +
							$"A brief description of how the application was being used at the time follows:\r\n" +
							$"\r\n\r\n\r\n\r\n" +
							$"Regards,\r\n" +
							$"A Helpful User";
						email.Attachments.Add(new Attachment(dg.FileName));

						// Try to send it
						var smtp = new SmtpClient();
						smtp.Send(email);
					}
					catch {}
				}
			}
			Environment.ExitCode = 1;
		}
Esempio n. 16
0
        /// <summary>Starts a worker thread to read bytes from a memory mapped file</summary>
        public static ManualResetEventSlim BeginRead(string filepath, WaitHandle stop, Action <ArraySegment <byte> > data_cb, int block_size = 1024)
        {
            // Use:
            //  var stop = new ManualResetEventSlim(false);
            //  var done = FileContent.BeginRead(filepath, stop, s => UseBytes(s));
            //  ...
            //  stop.Set();
            //  done.WaitOne();

            var done = new ManualResetEventSlim(false);

            ThreadPool.QueueUserWorkItem(async _ =>
            {
                var sr  = (Stream?)null;
                var mmf = (MemoryMappedFile?)null;
                try
                {
                    var buffer = new byte[block_size];
                    for (; ; Thread.Yield())
                    {
                        // Create the memory mapped file after the monitored file is created
                        if (sr == null)
                        {
                            try
                            {
                                // Cancelled already?
                                if (stop.WaitOne(0))
                                {
                                    break;
                                }

                                // Wait for the file to appear.
                                // 'MemoryMappedFile.CreateFromFile' fails for null or zero-length files
                                if (!Path_.FileExists(filepath) || Path_.FileLength(filepath) == 0)
                                {
                                    Thread.Sleep(100);
                                    continue;
                                }

                                // Once the file exists, create a memory mapped file from it
                                mmf = mmf ?? MemoryMappedFile.CreateFromFile(filepath, FileMode.Open, Path_.SanitiseFileName($"FileContent-{filepath}"), 0, MemoryMappedFileAccess.Read);
                                sr  = mmf.CreateViewStream();
                            }
                            catch (UnauthorizedAccessException)
                            {
                                Thread.Sleep(100);
                                continue;
                            }
                        }

                        // Read blocks of data from the file
                        var read = await sr.ReadAsync(buffer, 0, buffer.Length);
                        if (read != 0)
                        {
                            data_cb(new ArraySegment <byte>(buffer, 0, read));
                            continue;
                        }

                        // Only test for exit if no data was read
                        if (stop.WaitOne(0))
                        {
                            break;
                        }

                        // If no data was read from the file, wait a bit longer
                        Thread.Sleep(10);
                    }
                }
                finally
                {
                    sr?.Dispose();
                    mmf?.Dispose();
                    done.Set();
                }
            });
            return(done);
        }
Esempio n. 17
0
        /// <summary>Load and parse the startup options</summary>
        public StartupOptions(string[] args)
        {
            var exe_dir = Util.ResolveAppPath();

            if (!Directory.Exists(exe_dir))
            {
                throw new ArgumentException("Cannot determine the current executable directory");
            }

            // Check the command line options
            for (int i = 0, iend = args.Length; i != iend; ++i)
            {
                var arg = args[i].ToLowerInvariant();

                // No option character implies the file to load
                if (arg[0] != '-' && arg[0] != '/')
                {
                    if (FileToLoad != null)
                    {
                        throw new ArgumentException("Command line should specify a single file path only. If the file path contains white space, remember to use quotes. e.g. RyLogViewer \"my file.txt\"");
                    }
                    FileToLoad = arg;
                    continue;
                }

                // Helper for comparing option strings
                bool IsOption(string opt) => string.CompareOrdinal(arg, 0, opt, 0, opt.Length) == 0;

                // (order these by longest option first)
                if (IsOption(CmdLineOption.RDelim))
                {
                    RowDelim = arg.Substring(CmdLineOption.RDelim.Length);
                }
                else if (IsOption(CmdLineOption.CDelim))
                {
                    ColDelim = arg.Substring(CmdLineOption.CDelim.Length);
                }
                else if (IsOption(CmdLineOption.NoGUI))
                {
                    NoGUI = true;
                }
                else if (IsOption(CmdLineOption.Silent))
                {
                    Silent = true;
                }
                else if (IsOption(CmdLineOption.PatternSet))
                {
                    PatternSetFilepath = arg.Substring(CmdLineOption.PatternSet.Length);
                }
                else if (IsOption(CmdLineOption.SettingsPath))
                {
                    SettingsPath = arg.Substring(CmdLineOption.SettingsPath.Length);
                }
                else if (IsOption(CmdLineOption.LogFilePath))
                {
                    LogFilePath = arg.Substring(CmdLineOption.LogFilePath.Length);
                }
                else if (IsOption(CmdLineOption.Export))
                {
                    ExportPath = arg.Substring(CmdLineOption.Export.Length);
                }
                else if (IsOption(CmdLineOption.Portable))
                {
                    PortableMode = true;
                }
                else if (IsOption(CmdLineOption.ShowHelp))
                {
                    ShowHelp = true;
                }
                else if (IsOption(CmdLineOption.ShowHelp2))
                {
                    ShowHelp = true;
                }
                else
                {
                    throw new ArgumentException("Unknown command line option '" + arg + "'.");
                }
            }

            // Determine whether to run the app in portable mode
            PortableMode |= Path_.FileExists(Path.Combine(exe_dir, "portable"));

            // Set the UserDataDir based on whether we're running in portable mode or not
            UserDataDir = Path.GetFullPath(PortableMode ? exe_dir : Util.ResolveUserDocumentsPath(Application.CompanyName, Application.ProductName));

            // If we're in portable mode, check that we have write access to the local directory
            if (PortableMode)
            {
                if (!Path_.DirExists(UserDataDir) || (new DirectoryInfo(UserDataDir).Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
                {
                    throw new IOException("Unable to run in portable mode as the directory ('" + UserDataDir + "') is readonly.");
                }
            }
            // If not in portable mode, check the UserDataDir directory exists (or can be created)
            else
            {
                if (!Path_.DirExists(UserDataDir))
                {
                    Directory.CreateDirectory(UserDataDir);
                }
            }

            // If the export option is given, a 'FileToLoad' must also be given
            if (ExportPath != null && FileToLoad == null)
            {
                throw new ArgumentException("A file to export must be given if the '-e' option is used");
            }

            // If a settings path has not been given, use the defaults
            if (SettingsPath == null)
            {
                SettingsPath = Path.Combine(UserDataDir, "settings.xml");
            }

            // Set the licence file path
            LicenceFilepath = PortableMode
                                ? Path.Combine(exe_dir, "licence.xml")
                                : Path.Combine(UserDataDir, "licence.xml");

            // If no licence file exists, create the free one
            if (!Path_.FileExists(LicenceFilepath))
            {
                new Licence().WriteLicenceFile(LicenceFilepath);
            }
        }
Esempio n. 18
0
        /// <summary>Checks for the existence of a file without blocking the UI</summary>
        public static bool FileExists(Form parent, string filepath)
        {
            // Check that the file exists, this can take ages if 'filepath' is a network file
            bool file_exists = false;
            var  dlg         = new ProgressForm("Open File", "Opening file...", null, ProgressBarStyle.Marquee, (s, a, cb) => file_exists = Path_.FileExists(filepath));

            using (dlg) dlg.ShowDialog(parent, 500);
            return(file_exists);
        }
Esempio n. 19
0
        /// <summary>Starts a worker thread to read lines from the file</summary>
        public static ManualResetEventSlim BeginReadLines(string filepath, WaitHandle stop, Action <string> lines_cb, Encoding?encoding = null)
        {
            // Use:
            //  var stop = new ManualResetEventSlim(false);
            //  var done = FileContent.BeginReadLines(filepath, stop, s => UseLine(s));
            //  ...
            //  stop.Set();
            //  done.WaitOne();

            var done = new ManualResetEventSlim(false);

            ThreadPool.QueueUserWorkItem(async _ =>
            {
                var sr  = (StreamReader?)null;
                var mmf = (MemoryMappedFile?)null;
                try
                {
                    for (; ; Thread.Yield())
                    {
                        // Create the memory mapped file after the monitored file is created
                        if (sr == null)
                        {
                            // Cancelled already?
                            if (stop.WaitOne(0))
                            {
                                break;
                            }

                            // Wait for the file to appear.
                            // 'MemoryMappedFile.CreateFromFile' fails for null or zero-length files
                            if (!Path_.FileExists(filepath) || Path_.FileLength(filepath) == 0)
                            {
                                Thread.Sleep(100);
                                continue;
                            }

                            // Once the file exists, create a memory mapped file from it
                            mmf = mmf ?? MemoryMappedFile.CreateFromFile(filepath, FileMode.Open, Path_.SanitiseFileName($"FileContent-{filepath}"), 0, MemoryMappedFileAccess.Read);
                            sr  = new StreamReader(mmf.CreateViewStream(), encoding ?? Encoding.UTF8);
                        }

                        // Read lines from the file
                        var line = await sr.ReadLineAsync();
                        if (line != null)
                        {
                            lines_cb(line.Trim('\0'));
                            continue;
                        }

                        // Only test for exit if no data was read
                        if (stop.WaitOne(0))
                        {
                            break;
                        }

                        // If no data was read from the file, wait a bit longer
                        Thread.Sleep(10);
                    }
                }
                finally
                {
                    sr?.Dispose();
                    mmf?.Dispose();
                    done.Set();
                }
            });
            return(done);
        }
Esempio n. 20
0
        /// <summary>Browse to the licence file</summary>
        private void LocateLicenceFile()
        {
            // Prompt for the user to find the licence file
            var filepath = (string)null;

            using (var dlg = new OpenFileDialog {
                Title = "Locate Licence File", Filter = "RyLogViewer Licence File|licence.xml"
            })
            {
                if (dlg.ShowDialog(this) != DialogResult.OK)
                {
                    return;
                }
                filepath = dlg.FileName;
            }

            try
            {
                // Check the licence
                var lic = new Licence(filepath);
                if (lic.Valid)
                {
                    // If there is an existing licence file, confirm overwrite
                    if (Path_.FileExists(m_main.StartupOptions.LicenceFilepath))
                    {
                        // Read the existing licence
                        var existing_lic = (Licence)null;
                        try { existing_lic = new Licence(m_main.StartupOptions.LicenceFilepath); } catch { }
                        if (existing_lic != null && existing_lic.Valid)
                        {
                            // Prompt if about to override an existing valid licence
                            var res = MsgBox.Show(this,
                                                  $"An existing valid licence already exists:\r\n" +
                                                  $"Licence Holder: {existing_lic.LicenceHolder}\r\n" +
                                                  $"Email Address: {existing_lic.EmailAddress}\r\n" +
                                                  "\r\n" +
                                                  "Do you want to replace this licence?",
                                                  Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                            if (res != DialogResult.Yes)
                            {
                                return;
                            }
                        }

                        // Write the licence to the expected location
                        lic.WriteLicenceFile(m_main.StartupOptions.LicenceFilepath);
                        UpdateUI();

                        // Say thank you
                        MsgBox.Show(this,
                                    "Thank you for activating " + Application.ProductName + ".\r\n" +
                                    "Your support is greatly appreciated."
                                    , "Activation Successful"
                                    , MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                    return;
                }

                // Valid licence but not for this version
                if (lic.NotForThisVersion)
                {
                    MsgBox.Show(this,
                                "This licence is for an older version of " + Application.ProductName + ".\r\n" +
                                "\r\n" +
                                "Please consider purchasing a new licence for this version.\r\n" +
                                "If you believe this to be an error, please contact '" + Constants.SupportEmail + "' for support."
                                , "Licence Out of Date"
                                , MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }

                // Do nothing with free licences
                if (lic.IsFreeLicence)
                {
                    MsgBox.Show(this,
                                "This licence is the free edition licence.\r\n" +
                                "\r\n" +
                                "Please consider purchasing a licence for this version.\r\n" +
                                "If you believe this to be an error, please contact '" + Constants.SupportEmail + "' for support."
                                , "Free Edition Licence"
                                , MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }

                // Licence is invalid
                MsgBox.Show(this,
                            "This licence file is invalid.\r\n" +
                            "\r\n" +
                            "If you believe this to be an error, please contact '" + Constants.SupportEmail + "' for support."
                            , "Activation Failed"
                            , MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            catch (Exception ex)
            {
                MsgBox.Show(this, $"Failed to locate and import a valid licence file\r\n{ex.Message}", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
Esempio n. 21
0
        /// <summary>
        /// Delete a directory and all contained files/subdirectories.
        /// Returns true if successful and not interrupted</summary>
        public static bool DelTree(string root, EDelTreeOpts opts, Func <string, EAbortIgnoreRetry> prompt, int timeout_ms = 1000)
        {
            prompt = prompt ?? (_ => EAbortIgnoreRetry.Abort);
            for (;;)
            {
                try
                {
                    // Generate a list of all contained files
                    var files = Directory.GetFiles(root, "*", SearchOption.AllDirectories);
                    if (files.Length != 0)
                    {
                        if (!opts.HasFlag(EDelTreeOpts.FilesOnly) && !opts.HasFlag(EDelTreeOpts.EvenIfNotEmpty))
                        {
                            throw new IOException($"Cannot delete {root}, directory still contains {files.Length} files");
                        }

                        // Check for processes holding locks on the files
                        for (;;)
                        {
                            // Find the lock holding processes/services
                            var lockers = FileLockHolders(files);
                            if (!lockers.Any())
                            {
                                break;
                            }

                            // Prompt the user, Abort, Retry or Ignore
                            var r = prompt(
                                $"The following processes hold locks on files within {root}:\r\n" +
                                $"\t{string.Join("\r\n\t", lockers.Select(x => x.ProcessName))}");
                            if (r == EAbortIgnoreRetry.Abort)
                            {
                                return(false);
                            }
                            if (r == EAbortIgnoreRetry.Ignore)
                            {
                                break;
                            }
                        }

                        // Delete the contained files
                        if (opts.HasFlag(EDelTreeOpts.FilesOnly) || opts.HasFlag(EDelTreeOpts.EvenIfNotEmpty))
                        {
                            foreach (var file in files)
                            {
                                if (Path_.FileExists(file))
                                {
                                    File.Delete(file);
                                }
                            }
                        }
                    }

                    // Try to delete the root directory. This can fail because the file system
                    // doesn't necessarily update as soon as the files are deleted. Try to delete,
                    // if that fails, wait a bit, then try again. If that fails, defer to the user.
                    const int Attempts = 3;
                    for (int retries = Attempts; retries-- != 0;)
                    {
                        try
                        {
                            if (opts.HasFlag(EDelTreeOpts.DeleteRoot))
                            {
                                Directory.Delete(root, true);
                            }
                            else
                            {
                                // Delete the contained directories
                                var dirs = System.IO.Directory.GetDirectories(root, "*", SearchOption.TopDirectoryOnly);
                                foreach (var dir in dirs)
                                {
                                    if (Path_.DirExists(dir))
                                    {
                                        Directory.Delete(dir, true);
                                    }
                                }
                            }
                            return(true);
                        }
                        catch (IOException)
                        {
                            if (retries == 0)
                            {
                                throw;
                            }
                            Thread.Sleep(Math.Max(100, timeout_ms / Attempts));
                        }
                    }
                }
                catch (Exception ex)
                {
                    var r = prompt(
                        $"Failed to delete directory '{root}'\r\n" +
                        $"{ex.Message}\r\n");
                    if (r == EAbortIgnoreRetry.Abort)
                    {
                        return(false);
                    }
                    if (r == EAbortIgnoreRetry.Ignore)
                    {
                        return(true);
                    }
                }
            }
        }
Esempio n. 22
0
        /// <summary>
        /// Smart copy from 'src' to 'dst'. Loosely like XCopy.
        /// 'src' can be a single file, a comma separated list of files, or a directory<para/>
        /// 'dst' can be a
        /// if 'src' is a directory, </summary>
        public static void Copy(string src, string dst, bool overwrite = false, bool only_if_modified = false, bool ignore_non_existing = false, Action <string>?feedback = null, bool show_unchanged = false)
        {
            var src_is_dir = Path_.IsDirectory(src);
            var dst_is_dir = Path_.IsDirectory(dst) || dst.EndsWith("/") || dst.EndsWith("\\") || src_is_dir;

            // Find the names of the source files to copy
            var files = new List <string>();

            if (src_is_dir)
            {
                files = Path_.EnumFileSystem(src, SearchOption.AllDirectories).Select(x => x.FullName).ToList();
            }
            else if (Path_.FileExists(src))
            {
                files = new List <string>()
                {
                    src
                }
            }
            ;
            else if (src.Contains('*') || src.Contains('?'))
            {
                files = Path_.EnumFileSystem(src, SearchOption.AllDirectories, new Pattern(EPattern.Wildcard, src).RegexString).Select(x => x.FullName).ToList();
            }
            else if (!ignore_non_existing)
            {
                throw new FileNotFoundException($"'{src}' does not exist");
            }

            // If the 'src' represents multiple files, 'dst' must be a directory
            if (src_is_dir || files.Count > 1)
            {
                // if 'dst' doesn't exist, assume it's a directory
                if (!Path_.DirExists(dst))
                {
                    dst_is_dir = true;
                }

                // or if it does exist, check that it is actually a directory
                else if (!dst_is_dir)
                {
                    throw new FileNotFoundException($"'{dst}' is not a valid directory");
                }
            }

            // Ensure that 'dstdir' exists. (Canonicalise fixes the case where 'dst' is a drive, e.g. 'C:\')
            var dstdir = Path_.Canonicalise((dst_is_dir ? dst : Path_.Directory(dst)).TrimEnd('/', '\\'));

            if (!Path_.DirExists(dstdir))
            {
                Directory.CreateDirectory(dstdir);
            }

            // Copy the file(s) to 'dst'
            foreach (var srcfile in files)
            {
                // If 'dst' is a directory, use the same filename from 'srcfile'
                var dstfile = string.Empty;
                if (dst_is_dir)
                {
                    var spath = src_is_dir ? Path_.RelativePath(src, srcfile) : Path_.FileName(srcfile);
                    dstfile = Path_.CombinePath(dstdir, spath);
                }
                else
                {
                    dstfile = dst;
                }

                // If 'srcfile' is a directory, ensure the directory exists at the destination
                if (Path_.IsDirectory(srcfile))
                {
                    if (!dst_is_dir)
                    {
                        throw new Exception($"ERROR: {dst} is not a directory");
                    }

                    // Create the directory at the destination
                    if (!Path_.DirExists(dstfile))
                    {
                        System.IO.Directory.CreateDirectory(dstfile);
                    }
                    if (feedback != null)
                    {
                        feedback(srcfile + " --> " + dstfile);
                    }
                }
                else
                {
                    // Copy if modified or always based on the flag
                    if (only_if_modified && !Path_.DiffContent(srcfile, dstfile))
                    {
                        if (feedback != null && show_unchanged)
                        {
                            feedback(srcfile + " --> unchanged");
                        }
                        continue;
                    }

                    // Ensure the directory path exists
                    var d = Path_.Directory(dstfile);
                    var f = Path_.FileName(dstfile);
                    if (!Path_.DirExists(d))
                    {
                        System.IO.Directory.CreateDirectory(d);
                    }
                    if (feedback != null)
                    {
                        feedback(srcfile + " --> " + dstfile);
                    }
                    File.Copy(srcfile, dstfile, overwrite);
                }
            }
        }
Esempio n. 23
0
        /// <summary>Pull 'filename' from EDDB. Returns true if the file was downloaded, and the output filepath</summary>
        public async Task <DownloadFileResult> DownloadFile(string file_url, string output_dir, TimeSpan?maximum_age = null)
        {
            var filename    = Path_.FileName(file_url);
            var output_path = Path_.CombinePath(Path_.CreateDirs(output_dir), filename);

            using (StatusStack.NewStatusMessage($"Downloading '{filename}'..."))
            {
                try
                {
                    HttpRequestMessage  req;
                    HttpResponseMessage resp;

                    // Request the head information about the target file
                    Log.Write(ELogLevel.Info, $"Checking size and timestamp of '{filename}'");
                    req  = new HttpRequestMessage(HttpMethod.Head, file_url);
                    resp = await Client.SendAsync(req, Shutdown);

                    if (!resp.IsSuccessStatusCode)
                    {
                        Log.Write(ELogLevel.Error, $"Downloading information for '{filename}' failed: {resp.StatusCode} {resp.ReasonPhrase}");
                        throw new HttpRequestException($"{resp.ReasonPhrase} ({resp.StatusCode})");
                    }

                    // Only download if the server version is newer.
                    if (maximum_age != null && Path_.FileExists(output_path))
                    {
                        var time_diff = new FileInfo(output_path).LastWriteTime - resp.Content.Headers.LastModified;
                        if (time_diff > -maximum_age.Value)
                        {
                            Log.Write(ELogLevel.Info, $"Local copy of '{filename}' is less than {Settings.Instance.DataAge.ToPrettyString(trailing_zeros:false)} older than the latest version");
                            return(new DownloadFileResult(file_url, output_path, false));
                        }
                    }

                    // Get the download size (remember it might be compressed)
                    var length = resp.Content.Headers.ContentLength;

                    // The server version is newer, download the whole file
                    Log.Write(ELogLevel.Info, $"Downloading '{filename}' ({length} bytes)");
                    using (Scope.Create(() => Downloading = true, () => Downloading = false))
                    {
                        // Make the web request
                        req  = new HttpRequestMessage(HttpMethod.Get, file_url);
                        resp = await Client.SendAsync(req, Shutdown);

                        if (!resp.IsSuccessStatusCode)
                        {
                            Log.Write(ELogLevel.Error, $"Downloading '{filename}' failed: {resp.StatusCode} {resp.ReasonPhrase}");
                            throw new HttpRequestException($"{resp.ReasonPhrase} ({resp.StatusCode})");
                        }

                        // Read the response content into a file
                        using (var file = new FileStream(output_path, FileMode.Create, FileAccess.Write, FileShare.Read))
                        {
                            // Decompress if the content is compressed
                            if (resp.Content.Headers.ContentEncoding.Any(x => x == "gzip"))
                            {
                                using (var content = await resp.Content.ReadAsStreamAsync())
                                    using (var gzip = new GZipStream(content, CompressionMode.Decompress))
                                        await gzip.CopyToAsync(file);
                            }
                            else
                            {
                                await resp.Content.CopyToAsync(file);
                            }

                            Log.Write(ELogLevel.Info, $"Download complete '{filename}'");
                            return(new DownloadFileResult(file_url, output_path, true));
                        }
                    }
                }
                catch
                {
                    Log.Write(ELogLevel.Error, $"Data file '{filename}' was not available from {file_url}.");
                    return(new DownloadFileResult(file_url, output_path, false));
                }
            }
        }
Esempio n. 24
0
        // Notes:
        //  - Parsed command line options

        public StartupOptions(string[] args)
        {
            FilesToLoad  = new List <string>();
            SettingsPath = null !;

            var exe_dir = Util.ResolveAppPath();

            if (!Path_.DirExists(exe_dir))
            {
                throw new ArgumentException("Cannot determine the current executable directory");
            }

            // Check the command line options
            for (int i = 0, iend = args.Length; i != iend; ++i)
            {
                var arg = args[i].ToLowerInvariant();

                // No option character implies the file to load
                if (arg[0] != '-' && arg[0] != '/')
                {
                    FilesToLoad.Add(arg);
                    continue;
                }

                // Helper for comparing option strings
                bool IsOption(string opt) => string.CompareOrdinal(arg, 0, opt, 0, opt.Length) == 0;

                // (order these by longest option first)
                if (IsOption(CmdLine.SettingsPath))
                {
                    SettingsPath = arg.Substring(CmdLine.SettingsPath.Length);
                }
                else if (IsOption(CmdLine.Portable))
                {
                    PortableMode = true;
                }
                else if (IsOption(CmdLine.ShowHelp))
                {
                    ShowHelp = true;
                }
                else if (IsOption(CmdLine.ShowHelp2))
                {
                    ShowHelp = true;
                }
                else
                {
                    throw new ArgumentException($"Unknown command line option '{arg}'.");
                }
            }

            // Determine whether to run the app in portable mode
            PortableMode |= Path_.FileExists(Path_.CombinePath(exe_dir, "portable"));

            // Set the UserDataDir based on whether we're running in portable mode or not
            UserDataDir = Path.GetFullPath(PortableMode ? Path_.CombinePath(exe_dir, "UserData") : Util.ResolveUserDocumentsPath("Rylogic", "LDraw"));
            Path_.CreateDirs(UserDataDir);

            // Check that we have write access to the user data directory
            if (!Path_.DirExists(UserDataDir) || (new DirectoryInfo(UserDataDir).Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
            {
                throw new IOException($"The user data directory ('{UserDataDir}') is readonly.");
            }

            // If a settings path has not been given, use the defaults
            SettingsPath ??= Path_.CombinePath(UserDataDir, "settings2.xml");
        }
Esempio n. 25
0
        /// <summary>Performs an export from the command line</summary>
        public static void ExportToFile(StartupOptions startup_options)
        {
            string tmp_settings_path = Path.Combine(Path.GetTempPath(), "rylog_settings_" + Guid.NewGuid() + ".xml");

            try
            {
                // Copy the settings to a tmp file so that we don't trash the normal settings
                if (Path_.FileExists(startup_options.SettingsPath))
                {
                    File.Copy(startup_options.SettingsPath, tmp_settings_path);
                }
                else
                {
                    new Settings().Save(tmp_settings_path);
                }
                startup_options.SettingsPath = tmp_settings_path;

                // Load an instance of the app and the options.
                var m = new Main(startup_options);

                // Override settings passed on the command line
                if (startup_options.RowDelim != null)
                {
                    m.Settings.RowDelimiter = startup_options.RowDelim;
                }
                if (startup_options.ColDelim != null)
                {
                    m.Settings.ColDelimiter = startup_options.ColDelim;
                }
                if (startup_options.PatternSetFilepath != null)
                {
                    // Specifying a pattern set implies the filters and transforms should be enabled
                    m.Settings.Patterns          = PatternSet.Load(startup_options.PatternSetFilepath);
                    m.Settings.FiltersEnabled    = true;
                    m.Settings.TransformsEnabled = true;
                }

                // Do the export
                using (var outp = new StreamWriter(new FileStream(startup_options.ExportPath, FileMode.Create, FileAccess.Write, FileShare.Read)))
                {
                    try
                    {
                        var d = new BLIData(m, new SingleFile(startup_options.FileToLoad));
                        using (d.file)
                        {
                            var rng           = new[] { new RangeI(0, long.MaxValue) };
                            var row_delimiter = Misc.Robitise(m.Settings.RowDelimiter);
                            var col_delimiter = Misc.Robitise(m.Settings.ColDelimiter);

                            if (startup_options.NoGUI)
                            {
                                using (var done = new ManualResetEvent(false))
                                {
                                    ThreadPool.QueueUserWorkItem(x =>
                                    {
                                        d.progress = (c, l) => true;
                                        DoExport(d, rng, row_delimiter, col_delimiter, outp);
                                        done.Set();
                                    });

                                    done.WaitOne();
                                    if (!startup_options.Silent)
                                    {
                                        Console.WriteLine("Export completed successfully.");
                                    }
                                }
                            }
                            else
                            {
                                if (m.DoExportWithProgress(d, rng, row_delimiter, col_delimiter, outp))
                                {
                                    if (!startup_options.Silent)
                                    {
                                        Console.WriteLine("Export completed successfully.");
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Environment.ExitCode = 1;
                        if (!startup_options.Silent)
                        {
                            Console.WriteLine($"Export failed.\r\n{ex.Message}");
                        }
                    }
                }
            }
            finally
            {
                if (Path_.FileExists(tmp_settings_path))
                {
                    File.Delete(tmp_settings_path);
                }
            }
        }
Esempio n. 26
0
        /// <summary>Search for the full path of adb.exe</summary>
        private void AutoDetectAdbPath()
        {
            // If the full path is saved in the settings, use that (if it's valid)
            if (Path_.FileExists(m_settings.AdbFullPath))
            {
                SetAdbPath(m_settings.AdbFullPath);
                return;
            }

            // Quick check the most likely spot
            var likely_path = Path.Combine(Environment.GetEnvironmentVariable("ANDROID_HOME") ?? string.Empty, @"platform-tools\adb.exe");

            if (Path_.FileExists(likely_path))
            {
                SetAdbPath(likely_path);
                return;
            }

            // Not found? longer search...
            const string msg =
                "Searching for the Android Debugging Bridge application...\r\n" +
                "\r\n" +
                "Trying Path: {0}...\r\n" +
                "\r\n" +
                "Click cancel to locate it manually.";

            var adb_path     = string.Empty;
            var search_paths = new[]
            {
                Environment.GetEnvironmentVariable("ANDROID_HOME"),
                Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86) + @"\Android\android-sdk\platform-tools",
                Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) + @"\Android\android-sdk\platform-tools",
                @"D:\Program Files (x86)\Android\android-sdk\platform-tools",
                @"D:\Program Files\Android\android-sdk\platform-tools",
                @"E:\Program Files (x86)\Android\android-sdk\platform-tools",
                @"E:\Program Files\Android\android-sdk\platform-tools",
                Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
                Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData),
                Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86),
                Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles),
                @"C:\"
            };

            var res = DialogResult.Cancel;

            try
            {
                // Search for 'adb.exe'
                var find_adb = new ProgressForm("Locating 'adb.exe'...", string.Format(msg, string.Empty), Icon, ProgressBarStyle.Marquee, (s, a, cb) =>
                {
                    foreach (var path in search_paths)
                    {
                        if (s.CancelPending || adb_path.HasValue())
                        {
                            break;
                        }

                        if (path == null || !Directory.Exists(path))
                        {
                            continue;
                        }

                        cb(new ProgressForm.UserState {
                            Description = string.Format(msg, path), ForceLayout = false
                        });
                        Func <string, bool> progress = dir =>
                        {
                            cb(ProgressForm.UserState.Empty);
                            return(!s.CancelPending);
                        };

                        foreach (var fi in Path_.EnumFileSystem(path, SearchOption.AllDirectories, regex_filter:@"adb\.exe", progress:progress))
                        {
                            // Found one!
                            adb_path = fi.FullName;
                            return;
                        }
                    }
                })
                {
                    StartPosition = FormStartPosition.CenterParent,
                    ClientSize    = new Size(640, 280),
                };
                using (find_adb)
                    res = find_adb.ShowDialog(this);
            }
            catch (OperationCanceledException) {}
            catch (Exception ex) { Misc.ShowMessage(this, "An error occurred while searching for 'adb.exe'", "Locating 'adb.exe' failed", MessageBoxIcon.Error, ex); }
            if (res != DialogResult.OK)
            {
                return;
            }

            SetAdbPath(adb_path);
        }