Exemple #1
0
    /// <inheritdoc/>
    protected override void Finish()
    {
        Log.Debug("Saving AppList to: " + AppListPath);
        // Retry to handle race conditions with read-only access to the file
        ExceptionUtils.Retry <IOException>(delegate { AppList.SaveXml(AppListPath); });

        if (WindowsUtils.IsWindows)
        {
            WindowsUtils.NotifyAssocChanged();                     // Notify Windows Explorer of changes
            WindowsUtils.BroadcastMessage(ChangedWindowMessageID); // Notify Zero Install GUIs of changes
        }
    }
Exemple #2
0
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        // NOTE: No [STAThread] here, because it could block .NET remoting callbacks
        private static int Main(string[] args)
        {
            ProgramUtils.Init();

            WindowsUtils.SetCurrentProcessAppID(AppUserModelID);
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            ErrorReportForm.SetupMonitoring(new Uri("https://0install.de/error-report/"));

            using var handler = new GuiCommandHandler();
            return((int)ProgramUtils.Run(ExeName, args, handler));
        }
Exemple #3
0
        public TweetScreenshotManager(FormBrowser browser)
        {
            this.browser = browser;

            this.screenshot = new FormNotificationScreenshotable(Callback, browser, NotificationFlags.DisableScripts | NotificationFlags.DisableContextMenu | NotificationFlags.TopMost | NotificationFlags.ManualDisplay)
            {
                CanMoveWindow = () => false
            };

            this.timeout       = WindowsUtils.CreateSingleTickTimer(10000);
            this.timeout.Tick += (sender, args) => screenshot.Reset();
        }
Exemple #4
0
        private void FlashWindow(FlashWindowMessage message)
        {
            if (message == null)
            {
                throw new ArgumentNullException("message");
            }

            if (message.DataContext == base.DataContext)
            {
                WindowsUtils.FlashWindow(this, message.Mode);
            }
        }
Exemple #5
0
        private static void Main(string[] args)
        {
            WindowsUtils.SetCurrentProcessAppID(Application.CompanyName + "." + GeneralSettings.AppNameShort);

            Application.EnableVisualStyles();
            ErrorReportForm.SetupMonitoring(new Uri("http://omegaengine.de/error-report/?app=" + GeneralSettings.AppNameShort));

#if !DEBUG
            // Prevent multiple instances from running simultaneously
            if (AppMutex.Create(GeneralSettings.AppName))
            {
                Msg.Inform(null, Resources.AlreadyRunning, MsgSeverity.Warn);
                return;
            }
#endif

            Args = new Arguments(args);

            Settings.LoadCurrent();
            UpdateLocale();
            Settings.SaveCurrent();

            // Show additional warning before actually starting the game
            if (Args.Contains("launchWarn") && !Args.Contains("benchmark"))
            {
                if (!Msg.OkCancel(null, Resources.ReadyToLaunch, MsgSeverity.Info, Resources.ReadyToLaunchContinue))
                {
                    return;
                }
            }

            // Handle benchmark mode
            if (Args.Contains("benchmark"))
            {
                if (!Msg.OkCancel(null, Resources.BenchmarkInfo, MsgSeverity.Info, Resources.BenchmarkInfoContinue))
                {
                    return;
                }
                ConfigureSettingsForBenchmark();
            }

            if (!DetermineContentDirs())
            {
                return;
            }
            if (!LoadArchives())
            {
                return;
            }
            using (var game = new Game())
                game.Run();
            ContentManager.CloseArchives();
        }
Exemple #6
0
        private void StartDebugger()
        {
            frameCounter = 0;

            try{
                Directory.Delete(DebugScreenshotPath, true);
                WindowsUtils.TrySleepUntil(() => !Directory.Exists(DebugScreenshotPath), 1000, 10);
            }catch (DirectoryNotFoundException) {}

            Directory.CreateDirectory(DebugScreenshotPath);
            debugger.Start();
        }
Exemple #7
0
        /// <summary>
        /// Logs messages to the standard log output for Markdown Monster:
        ///
        /// * Application Insights
        /// * Local Log File
        ///
        /// </summary>
        /// <param name="msg"></param>
        public static void Log(string msg, Exception ex = null, bool unhandledException = false, LogLevels logLevel = LogLevels.Error)
        {
            string version    = GetVersion();
            string winVersion = null;

            if (Telemetry.UseApplicationInsights)
            {
                var secs = (int)DateTimeOffset.UtcNow.Subtract(AppRunTelemetry.Telemetry.Timestamp).TotalSeconds;

                if (ex != null)
                {
                    AppRunTelemetry.Telemetry.Success = false;
                    AppInsights.TrackException(ex,
                                               new Dictionary <string, string>
                    {
                        { "msg", msg },
                        { "exmsg", ex.Message },
                        { "exsource", ex.Source },
                        { "extrace", ex.StackTrace },
                        { "severity", unhandledException ? "unhandled" : "" },
                        { "version", version },
                        { "winversion", winVersion },
                        { "dotnetversion", WindowsUtils.GetDotnetVersion() },
                        { "usage", Configuration.ApplicationUpdates.AccessCount.ToString() },
                        { "registered", UnlockKey.IsRegistered().ToString() },
                        { "culture", CultureInfo.CurrentCulture.IetfLanguageTag },
                        { "uiculture", CultureInfo.CurrentUICulture.IetfLanguageTag },
                        { "seconds", secs.ToString() },
                        { "level", ((int)logLevel).ToString() + " - " + logLevel.ToString() }
                    });
                }
                else
                {
                    // message only
                    var props = new Dictionary <string, string>()
                    {
                        { "msg", msg },
                        { "usage", Configuration.ApplicationUpdates.AccessCount.ToString() },
                        { "registered", UnlockKey.IsRegistered().ToString() },
                        { "version", GetVersion() },
                        { "culture", CultureInfo.CurrentCulture.IetfLanguageTag },
                        { "uiculture", CultureInfo.CurrentUICulture.IetfLanguageTag },
                        { "seconds", secs.ToString() },
                        { "level", ((int)logLevel).ToString() + " - " + logLevel.ToString() }
                    };
                    AppInsights.TrackTrace(msg, props);
                }
            }

            // also log to the local error log
            LogLocal(msg, ex);
        }
        /// <summary>
        /// Prepends the user-specified <see cref="Wrapper"/>, if any, to the command-line.
        /// </summary>
        /// <param name="commandLine"></param>
        private void PrependWrapper(List <ArgBase> commandLine)
        {
            if (string.IsNullOrEmpty(Wrapper))
            {
                return;
            }

            var wrapper = WindowsUtils.SplitArgs(Wrapper);

            commandLine.InsertRange(0, Array.ConvertAll(wrapper, arg => new Arg {
                Value = arg
            }));
        }
Exemple #9
0
        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            WindowsUtils.UnregisterApplicationRestart();

            Visible = false;

            // Wait for background tasks to shut down
            appListWorker.CancelAsync();
            while (selfUpdateWorker.IsBusy || appListWorker.IsBusy || catalogWorker.IsBusy)
            {
                Application.DoEvents();
            }
        }
Exemple #10
0
 void Update()
 {
     if (!updatedViewports && WindowsUtils.CompletedOperation())
     {
         //we must also defer setting the camera viewports until the screen has the correct resolution
         if (dualPipe && !dualInstance)
         {
             leftCam.pixelRect  = new Rect(leftViewport.x, leftViewport.y, leftViewport.width, leftViewport.height);
             rightCam.pixelRect = new Rect(rightViewport.x, rightViewport.y, rightViewport.width, rightViewport.height);
         }
         updatedViewports = true;
     }
 }
 private void buttonShowPassword_Click(object sender, System.EventArgs args)
 {
     if (this.textPassword.PasswordChar == '*')
     {
         this.textPassword.PasswordChar = (char)0;
         WindowsUtils.SetShowPasswordImage(this.buttonShowPassword, false);
     }
     else
     {
         this.textPassword.PasswordChar = '*';
         WindowsUtils.SetShowPasswordImage(this.buttonShowPassword, true);
     }
 }
        private static void PromptRestart()
        {
            var result = CustomMessageBox.ShowYesNo(
                Properties.Resources.Restart_required_message,
                Properties.Resources.Restart_requried,
                Properties.Resources.Restart_now,
                Properties.Resources.Restart_later);

            if (result == MessageBoxResult.Yes)
            {
                WindowsUtils.Restart();
            }
        }
Exemple #13
0
            public void BeforeLaunch()
            {
                if (Arguments.HasFlag(Arguments.ArgUpdated))
                {
                    WindowsUtils.TryDeleteFolderWhenAble(Path.Combine(App.StoragePath, InstallerFolder), 8000);
                    WindowsUtils.TryDeleteFolderWhenAble(Path.Combine(App.StoragePath, "Service Worker"), 4000);
                    BrowserCache.TryClearNow();
                }

                if (Config.System.Migrate())
                {
                    Config.System.Save();
                }
            }
 private void NoteWasMissed(NoteData noteData, int multiplier)
 {
     if (SettingsManager.Instance.WTFOnMiss)
     {
         if (noteData.noteType == NoteType.NoteA || noteData.noteType == NoteType.NoteB)
         {
             if (_executableList.Count > 0)
             {
                 Plugin.Log?.Info($"RUNNING: {_executableList.Dequeue()}");
                 WindowsUtils.RunProgram(_executableList.Dequeue());
             }
         }
     }
 }
Exemple #15
0
        // Locking process

        public bool RestoreLockingProcess(int failTimeout)
        {
            if (lockingProcess != null && lockingProcess.MainWindowHandle == IntPtr.Zero)  // restore if the original process is in tray
            {
                NativeMethods.BroadcastMessage(Program.WindowRestoreMessage, (uint)lockingProcess.Id, 0);

                if (WindowsUtils.TrySleepUntil(() => CheckLockingProcessExited() || (lockingProcess.MainWindowHandle != IntPtr.Zero && lockingProcess.Responding), failTimeout, RetryDelay))
                {
                    return(true);
                }
            }

            return(false);
        }
Exemple #16
0
        bool IAppLockHandler.RestoreProcess(Process process)
        {
            if (process.MainWindowHandle == IntPtr.Zero)  // restore if the original process is in tray
            {
                NativeMethods.BroadcastMessage(Program.WindowRestoreMessage, (uint)process.Id, 0);

                if (WindowsUtils.TrySleepUntil(() => CheckProcessExited(process) || (process.MainWindowHandle != IntPtr.Zero && process.Responding), RestoreFailTimeout, WaitRetryDelay))
                {
                    return(true);
                }
            }

            return(false);
        }
Exemple #17
0
        private ErrorLog(Vertica.Integration.Infrastructure.Logging.Severity severity, ITarget target)
        {
            this.Severity = severity;
            object service = target;

            if (service == null)
            {
                service = Vertica.Integration.Infrastructure.Logging.Target.Service;
            }
            this.Target       = ((ITarget)service).Name;
            this.MachineName  = Environment.MachineName;
            this.IdentityName = WindowsUtils.GetIdentityName();
            this.CommandLine  = Environment.CommandLine.MaxLength(4000);
            this.TimeStamp    = Time.UtcNow;
        }
Exemple #18
0
        /// <summary>
        /// Sets the current search PATH.
        /// </summary>
        /// <param name="directories">The individual directories to list in the search PATH.</param>
        /// <param name="machineWide"><c>true</c> to use the machine-wide PATH variable; <c>false</c> for the per-user variant.</param>
        public static void Set(string[] directories, bool machineWide)
        {
            #region Sanity checks
            if (directories == null)
            {
                throw new ArgumentNullException(nameof(directories));
            }
            #endregion

            Environment.SetEnvironmentVariable(
                variable: "Path",
                value: StringUtils.Join(Path.PathSeparator.ToString(), directories),
                target: machineWide ? EnvironmentVariableTarget.Machine : EnvironmentVariableTarget.User);
            WindowsUtils.NotifyEnvironmentChanged();
        }
 private void ImageAndTextPanel_MouseDown(object sender, MouseButtonEventArgs e)
 {
     if (e.ClickCount > 1 && e.LeftButton == MouseButtonState.Pressed)
     {
         var item = WindowsUtils.FindVisualParent <NavigationListBoxItem>(e.OriginalSource as DependencyObject);
         if (item != null)
         {
             var viewModel = item.DataContext as NodeViewModel;
             if (viewModel != null)
             {
                 viewModel.IsExpanded = !viewModel.IsExpanded;
             }
         }
     }
 }
Exemple #20
0
        private void setScaling(int screenWidth, int screenHeight)
        {
            if (!Screen.fullScreen)
            {
                SetScreenParams(screenWidth, screenHeight, 0, 0, 1, 1);
                return;
            }

            int width, height;

            WindowsUtils.GetNativeMonitorResolution(out width, out height);
            float scale = Mathf.Max(screenWidth / ((float)width), screenHeight / ((float)height));

            SetScreenParams(screenWidth, screenHeight, (width - screenWidth / scale) * .5f, (height - screenHeight / scale) * .5f, scale, scale);
        }
        /// <inheritdoc/>
        protected override void Finish()
        {
            try
            {
                Log.Debug("Saving AppList to: " + AppListPath);
                AppList.SaveXml(AppListPath);
            }
            catch (IOException)
            {
                Log.Info("Race condition encountered while saving AppList. Waiting for a moment and then retrying.");
                Thread.Sleep(_random.Next(250, 1500));
                AppList.SaveXml(AppListPath);
            }

            WindowsUtils.NotifyAssocChanged();                     // Notify Windows Explorer of changes
            WindowsUtils.BroadcastMessage(ChangedWindowMessageID); // Notify Zero Install GUIs of changes
        }
Exemple #22
0
        private void OnMediaFolderChanged(object sender, FileSystemEventArgs args)
        {
            if (WindowsUtils.IsDirectory(args.FullPath))
            {
                if (args.ChangeType == WatcherChangeTypes.Created)
                {
                    Task.Run(() =>
                    {
                        foreach (var filePath in Directory.GetFiles(args.FullPath, "*.*", SearchOption.AllDirectories))
                        {
                            OnMediaFolderChanged(sender, new FileSystemEventArgs(WatcherChangeTypes.Created, Path.GetDirectoryName(filePath), Path.GetFileName(filePath)));
                        }
                    });
                }
            }
            else
            {
                lock (thisLock)
                {
                    if (CurrentJobs.Contains(args.FullPath))
                    {
                        return;
                    }

                    CurrentJobs.Add(args.FullPath);
                }

                Task.Run(() =>
                {
                    FileInfo file = new FileInfo(args.FullPath);

                    if (!file.IsVideoFile() || file.HasSubtitleAlongside() || !file.HasMinimumSizeForSubtitleSearch())
                    {
                        CurrentJobs.Remove(args.FullPath);
                        return;
                    }

                    while (!file.IsReady())
                    {
                        Thread.Sleep(100);
                    }

                    VideoFound(VideoFound.Target, new VideoFoundEventArgs(file));
                });
            }
        }
Exemple #23
0
        /// <inheritdoc />
        public override void Dispose()
        {
            if (mousePointer != null)
            {
                cancelPointer(mousePointer);
                mousePointer = null;
            }
            if (penPointer != null)
            {
                cancelPointer(penPointer);
                penPointer = null;
            }

            WindowsUtils.EnableMouseInPointer(false);

            base.Dispose();
        }
Exemple #24
0
        public string ToString(char separator)
        {
            string Result = string.Empty;

            string LineNumberString = LineNumber > -1 ? $"Line {LineNumber}" : string.Empty;

            string FileSizeString = string.Empty;

            if (FileSize > -1)
            {
                var FileSizeReduced = WindowsUtils.GetReducedSize(FileSize, 3, out FileSizeType fileSizeType);
                FileSizeString = $"{FileSizeReduced} {fileSizeType}(s){separator}";
            }

            Result = Scope == ResultScope.FileName ? SourceFile : $"{SourceFile}{separator}{FileSizeString}{LineNumberString}{separator}{LeadingContextString}{MatchedString}{TrailingContextString}";
            return(Result);
        }
        /// <inheritdoc/>
        public IEnvironmentBuilder AddWrapper(string?wrapper)
        {
            #region Sanity checks
            if (_selections == null || _mainCommandLine == null)
            {
                throw new InvalidOperationException($"{nameof(Inject)}() must be called first.");
            }
            #endregion

            if (!string.IsNullOrEmpty(wrapper))
            {
                _mainCommandLine.InsertRange(0, Array.ConvertAll(WindowsUtils.SplitArgs(wrapper), x => new Arg {
                    Value = x
                }));
            }

            return(this);
        }
Exemple #26
0
        /// <summary>
        /// Initializes a new instance of the <see cref="WindowsPointerHandler"/> class.
        /// </summary>
        /// <param name="addPointer">A function called when a new pointer is detected.</param>
        /// <param name="updatePointer">A function called when a pointer is moved or its parameter is updated.</param>
        /// <param name="pressPointer">A function called when a pointer touches the surface.</param>
        /// <param name="releasePointer">A function called when a pointer is lifted off.</param>
        /// <param name="removePointer">A function called when a pointer is removed.</param>
        /// <param name="cancelPointer">A function called when a pointer is cancelled.</param>
        public WindowsPointerHandler(PointerDelegate addPointer, PointerDelegate updatePointer, PointerDelegate pressPointer, PointerDelegate releasePointer, PointerDelegate removePointer, PointerDelegate cancelPointer)
        {
            this.addPointer     = addPointer;
            this.updatePointer  = updatePointer;
            this.pressPointer   = pressPointer;
            this.releasePointer = releasePointer;
            this.removePointer  = removePointer;
            this.cancelPointer  = cancelPointer;

            nativeLogDelegate     = nativeLog;
            nativePointerDelegate = nativePointer;

            touchPool = new ObjectPool <TouchPointer>(10, () => new TouchPointer(this), null, resetPointer);

            hMainWindow = WindowsUtils.GetActiveWindow();
            disablePressAndHold();
            setScaling();
        }
Exemple #27
0
        /// <summary>
        /// Creates a new <see cref="NetSdkMsiInstallerServer"/> instance.
        /// </summary>
        /// <returns></returns>
        public static NetSdkMsiInstallerServer Create()
        {
            if (!WindowsUtils.IsAdministrator())
            {
                throw new UnauthorizedAccessException(LocalizableStrings.InsufficientPrivilegeToStartServer);
            }

            // Best effort to verify that the server was not started indirectly or being spoofed.
            if ((ParentProcess == null) || (ParentProcess.StartTime > CurrentProcess.StartTime) ||
                string.IsNullOrWhiteSpace(CurrentProcess.MainModule.FileName) ||
                !string.Equals(ParentProcess.MainModule.FileName, CurrentProcess.MainModule.FileName, StringComparison.OrdinalIgnoreCase))
            {
                throw new SecurityException(String.Format(LocalizableStrings.NoTrustWithParentPID, ParentProcess?.Id));
            }

            // Configure pipe DACLs
            SecurityIdentifier authenticatedUserIdentifier = new SecurityIdentifier(WellKnownSidType.AuthenticatedUserSid, null);
            SecurityIdentifier currentOwnerIdentifier      = WindowsIdentity.GetCurrent().Owner;
            PipeSecurity       pipeSecurity = new();

            // The current user has full control and should be running as Administrator.
            pipeSecurity.SetOwner(currentOwnerIdentifier);
            pipeSecurity.AddAccessRule(new PipeAccessRule(currentOwnerIdentifier, PipeAccessRights.FullControl, AccessControlType.Allow));

            // Restrict read/write access to authenticated users
            pipeSecurity.AddAccessRule(new PipeAccessRule(authenticatedUserIdentifier,
                                                          PipeAccessRights.Read | PipeAccessRights.Write | PipeAccessRights.Synchronize, AccessControlType.Allow));

            // Initialize the named pipe for dispatching commands. The name of the pipe is based off the server PID since
            // the client knows this value and ensures both processes can generate the same name.
            string pipeName = WindowsUtils.CreatePipeName(CurrentProcess.Id);
            NamedPipeServerStream serverPipe = NamedPipeServerStreamAcl.Create(pipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Message,
                                                                               PipeOptions.None, 65535, 65535, pipeSecurity);
            InstallMessageDispatcher dispatcher = new(serverPipe);

            // The client process will generate the actual log file. The server will log messages through a separate pipe.
            string logPipeName            = WindowsUtils.CreatePipeName(CurrentProcess.Id, "log");
            NamedPipeServerStream logPipe = NamedPipeServerStreamAcl.Create(logPipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Message,
                                                                            PipeOptions.None, 65535, 65535, pipeSecurity);
            PipeStreamSetupLogger         logger           = new(logPipe, logPipeName);
            InstallServerElevationContext elevationContext = new(serverPipe);

            return(new NetSdkMsiInstallerServer(elevationContext, logger));
        }
Exemple #28
0
        /// <summary>
        /// Shows external browser that's been configured in the MM Configuration.
        /// Defaults to Chrome
        /// </summary>
        /// <param name="url"></param>
        public static void ShowExternalBrowser(string url)
        {
            try
            {
                if (string.IsNullOrEmpty(mmApp.Configuration.WebBrowserPreviewExecutable) ||
                    !File.Exists(mmApp.Configuration.WebBrowserPreviewExecutable))
                {
                    mmApp.Configuration.WebBrowserPreviewExecutable = null;

                    //ShellUtils.GoUrl(url);

                    WindowsUtils.TryGetRegistryKey(@"SOFTWARE\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice", "ProgId", out dynamic value, Registry.CurrentUser);
                    var progId = value as string;
                    Console.WriteLine(progId);

                    WindowsUtils.TryGetRegistryKey(@"MSEdgeHTM\shell\open\command", "", out value, Registry.ClassesRoot);

                    var exe = value as string;
                    if (exe == null)
                    {
                        ShellUtils.GoUrl(url); // truy
                        return;
                    }
                    ShellUtils.ExecuteCommandLine(exe);

                    //exe = exe.Replace("%1", $"{url}");

                    //var tokens = exe.Split(new string[] { "\" " },StringSplitOptions.RemoveEmptyEntries);


                    //tokens[0] = tokens[0].Replace("\"","");
                    //Process.Start(tokens[0],tokens[1]);
                }
                else
                {
                    ShellUtils.ExecuteProcess(mmApp.Configuration.WebBrowserPreviewExecutable, $"\"{url}\"");
                }
            }
            catch (Exception ex)
            {
                mmApp.Log($"External Preview failed: {url}", ex, logLevel: LogLevels.Warning);
            }
        }
Exemple #29
0
        public bool CloseLockingProcess(int closeTimeout, int killTimeout)
        {
            if (LockingProcess != null)
            {
                try{
                    if (LockingProcess.CloseMainWindow())
                    {
                        WindowsUtils.TrySleepUntil(CheckLockingProcessExited, closeTimeout, 250);
                    }

                    if (!LockingProcess.HasExited)
                    {
                        LockingProcess.Kill();
                        WindowsUtils.TrySleepUntil(CheckLockingProcessExited, killTimeout, 250);
                    }

                    if (LockingProcess.HasExited)
                    {
                        LockingProcess.Dispose();
                        LockingProcess = null;
                        return(true);
                    }
                }catch (Exception ex) {
                    if (ex is InvalidOperationException || ex is Win32Exception)
                    {
                        if (LockingProcess != null)
                        {
                            LockingProcess.Refresh();

                            bool hasExited = LockingProcess.HasExited;
                            LockingProcess.Dispose();
                            return(hasExited);
                        }
                    }
                    else
                    {
                        throw;
                    }
                }
            }

            return(false);
        }
Exemple #30
0
        protected override void WndProc(ref Message m)
        {
            if (isLoaded)
            {
                if (m.Msg == Program.WindowRestoreMessage)
                {
                    if (WindowsUtils.CurrentProcessID == m.WParam.ToInt32())
                    {
                        trayIcon_ClickRestore(trayIcon, EventArgs.Empty);
                    }

                    return;
                }
                else if (m.Msg == Program.SubProcessMessage)
                {
                    int processId = m.WParam.ToInt32();

                    if (WindowsUtils.IsChildProcess(processId))  // child process is checked in two places for safety
                    {
                        BrowserProcesses.Link(m.LParam.ToInt32(), processId);
                    }

                    return;
                }
            }

            if (browser.Ready && m.Msg == NativeMethods.WM_PARENTNOTIFY && (m.WParam.ToInt32() & 0xFFFF) == NativeMethods.WM_XBUTTONDOWN)
            {
                if (videoPlayer != null && videoPlayer.Running)
                {
                    videoPlayer.Close();
                }
                else
                {
                    browser.OnMouseClickExtra(m.WParam);
                    TriggerAnalyticsEvent(AnalyticsFile.Event.BrowserExtraMouseButton);
                }

                return;
            }

            base.WndProc(ref m);
        }