Skip to content

Instantly share code, notes, and snippets.

@roshnet
Last active September 13, 2021 13:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save roshnet/b65c00d06aba7f12ede9b2fb14b645bb to your computer and use it in GitHub Desktop.
Save roshnet/b65c00d06aba7f12ede9b2fb14b645bb to your computer and use it in GitHub Desktop.
Close Chrome tabs in C# (Windows)
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Automation;
using System.Windows.Forms;
namespace NudgeApp {
class ChromeTabBlocker {
[DllImport("user32.dll")]
public static extern int SetForegroundWindow(IntPtr hWnd);
static int getTabCount() {
int numTabs = 0;
Process[] procsChrome = Process.GetProcessesByName("chrome");
foreach (Process proc in procsChrome) {
// the chrome process must have a window
if (proc.MainWindowHandle == IntPtr.Zero)
continue;
// Bring Chrome window to foreground
SetForegroundWindow(proc.MainWindowHandle);
// to find the tabs we first need to locate something reliable - the 'New Tab' button
AutomationElement root = AutomationElement.FromHandle(proc.MainWindowHandle);
Condition condNewTab = new PropertyCondition(AutomationElement.NameProperty, "New Tab");
AutomationElement elmNewTab = root.FindFirst(TreeScope.Descendants, condNewTab);
// get the tabstrip by getting the parent of the 'new tab' button
if (elmNewTab == null) continue;
TreeWalker treewalker = TreeWalker.ControlViewWalker;
AutomationElement elmTabStrip = treewalker.GetParent(elmNewTab);
// Loop through all the tabs and get the names which is the page title
Condition condTabItem = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.TabItem);
foreach (AutomationElement tabitem in elmTabStrip.FindAll(TreeScope.Children, condTabItem)) {
// Tab title can be found by "tabitem.Current.Name"
numTabs += 1;
}
}
return numTabs;
}
static void Main(string[] args) {
Process[] procsChrome = Process.GetProcessesByName("chrome");
// Simply exit if chrome is not open
if (procsChrome.Length <= 0)
return;
// (Un)comment if a dialog box needs to be shown (or not)
MessageBox.Show("Nudge will close blocked apps. Please hang on.", "Distracting apps found", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
foreach (Process proc in procsChrome) {
// The chrome process must have a window
if (proc.MainWindowHandle == IntPtr.Zero)
continue;
// Locate the SearchBar to access tab URL
AutomationElement root = AutomationElement.FromHandle(proc.MainWindowHandle);
// Open a new tab to identify the 'New tab' to allow finding the number of tabs
SetForegroundWindow(proc.MainWindowHandle);
SendKeys.SendWait("^t");
System.Threading.Thread.Sleep(500);
int tabCount = getTabCount();
for (int i = 1; i <= tabCount - 1; i++) {
var SearchBar = root.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.NameProperty, "Address and search bar"));
if (SearchBar != null) {
AutomationPattern[] patterns = SearchBar.GetSupportedPatterns();
if (patterns.Length > 0) {
ValuePattern val = (ValuePattern)SearchBar.GetCurrentPattern(patterns[0]);
if (val.Current.Value.Contains("facebook.com") || val.Current.Value.Contains("youtube.com")) {
SetForegroundWindow(proc.MainWindowHandle);
SendKeys.SendWait("^{F4}");
System.Threading.Thread.Sleep(20);
} else {
SetForegroundWindow(proc.MainWindowHandle);
SendKeys.SendWait("^{PGDN}");
System.Threading.Thread.Sleep(20);
}
}
}
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment