I can close all tab in chrome by use process thus:
Process[] chromeInstances = Process.GetProcessesByName("chrome");
if (chromeInstances.Length > 0)
{
foreach (Process p in chromeInstances)
{
p.Kill(); ;
}
}
But I want close one tab in chrome. It is possible?
According to this post, it is not possible: https://superuser.com/a/306715/68020
You can't close a tab by killing the process. The process represents a renderer that the main browser uses the execute and draw a page, which it then copies to the screen. The "Aw, Snap!" is what the browser displays when the renderer responsible for that tab crashes or is killed. The proper way to close the tab would ideally be via a command-line switch, but there is none that I know of at this time.
Also, as the comment describes,
there isn't a 1:1 relationship between tabs and renderer processes in the first place.
Related
so I want in my Project to only open 1 instance of my Window. So I gave the Window a Title and tried to track every opening with that:
foreach (Window window in Application.Current.Windows)
{
if (window.Title == "QUALI-NET")
{
temp++;
}
}
and then i wanted to call my Function when this if statement is true:
if (temp == 1)
I have build this 2 in an extra Class and have an Switch Case around this. Above the Switch Case I initiliaze this:
QualiWindow WPFQuali = new QualiWindow(Mandant, Data.GetValue<string>("Artikelnummer"));
But The problem when I Open one Window and then open and another Window then it wont open but when I close the first started Window, I cant open the Window ever Again? I just want to allow one Instance of this Window to open. What am Im doing wrong?
I already tried the solutions from here:
How can I make sure only one WPF Window is open at a time?
But none of that is working. Is there a Way to get every opened Window from taskbar or something and just allow one Window with that name XY. to open
If you're keeping a count of the open windows with that title you also need to decrement the count whenever you close the window.
I've been tasked with creating an application launcher that hosts both Winforms and WPF applications and via a slightly different methodology Web applications. The user is presented with a list of applications they can launch and these are "captured" upon launch and are lodged inside a panel on a form by using SetParent to make the panel the parent of the processes MainWindowHandle. This bit appears to work well and the applications when launched are captured and displayed in the given panel.
What Iʼm having a particular issue with is that not all applications that are captured are happy to initially draw themselves in the panel. It seems to be isolated to those applications that are WPF based, but thatʼs not guaranteed.
Effectively what happens is that if a WPF application is launched, it is captured and moved to the panel, and the panel will remain blank until I click the panel at which point the application will happily repaint itself. From this point forward the application seems to be happy enough repainting itself as required without intervention.
Basically Iʼm now at my wits ends and have tried the following User32 native and .NET methods;
Invalidate (on the form, on the panel, on the tab control that hosts both of these)
Update
Refresh
SendMessage with a plethora of parameters, including attempting the, "you shouldnʼt do this" WM_PAINT.
RedrawWindow with the UpdateNow and Invalidate flags.
None of the above makes any visible difference and itʼs only when I physically click the panel or move the window that the contained application will behave and repaint itself.
Has anyone else produced anything similar and has a solution to the redraw/repaint issue? Iʼve scoured the entire Google/Bing/Duck Duck Go spheres trying to hunt down an answer but to no avail.
Hopefully one of you out there has an answer.
The following code represents the bulk of the feature in that it starts a process and captures the handle for the main window of the process and sets itsʼ parent to a panel control on a bog-standard WinForms window. I should probably point out that the bog-standard WinForms window is itself “hosted” inside an application using the (EasyTabs) Library. Which, I believe, is not causing any problems.
Example:
// Try to acquire a the process.
ProcessStartInfo startInfo = new ProcessStartInfo(path);
try
{
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
startInfo.WindowStyle = ProcessWindowStyle.Normal;
Process.StartInfo = startInfo;
Process.EnableRaisingEvents = true;
Process.Exited += TabManagerContainerForm_ProcessExited;
Process.Start();
if (Process != null)
{
// Wait until the process has created a main window or exited.
while (Process.MainWindowHandle == IntPtr.Zero && !Process.HasExited)
{
Thread.Sleep(100);
Process.Refresh();
}
if (!Process.HasExited) // We have acquired a MainWindowHandle
{
// Capture the Process's main window and show it inside the applicationPanel panel control.
SetParent(Process.MainWindowHandle, applicationPanel.Handle);
// Change the captured Process's window to one without the standard chrome. Itʼs provided by our tabbed application.
SetWindowLong(Process.MainWindowHandle, (int)WindowLongFlags.GWL_STYLE, (int)WindowStyles.WS_VISIBLE);
}
else // Process has exited.
{
if (Process.MainWindowHandle == IntPtr.Zero) Log.Information("{0} failed to execute.", Process.ProcessName);
throw new FailedProcessException(string.Format("{0} failed to execute.", path));
}
}
else
{
throw new Exception(string.Format("Invalid path: {0}", path));
}
}
catch (Exception ex) when (!(ex is FailedProcessException)) // Catch everything but FailedProcessExceptions. FPEs are simply passed up the chain.
{
Log.Error(ex.Message);
throw;
}
Summary:
The problem seems to happen when attaching an application to a Panel in a tab that is not the currently visible tab.
Solution:
Add WS_CHILD flag to the call to SetWindowLong:
SetWindowLong(Process.MainWindowHandle, (int)WindowLongFlags.GWL_STYLE, (int)(WindowStyles.WS_VISIBLE | WindowStyles.WS_CHILD));
Details:
I tried reproducing the example in the question (without using EasyTabs). I used a simple Form with a single Panel. With a button press I call a simple WPF app and attach it to the Panel. It works OK, it renders immediately. The only problem I found was the position of the WPF window which was random. I fixed it with calling SetWindowPos (using pinvoke) like this:
SetWindowPos(Process.MainWindowHandle, IntPtr.Zero, 0, 0, 0, 0, SetWindowPosFlags.IgnoreResize);
Than, I tried using a TabControl with two tabs, each containing a Panel and two buttons, each one when pressed, launches a different WPF app to one of the Panels. I found that when a tab (TabPage) is not the visible tab, the problem occurs - the launched application is not visible until the Panel is clicked. I solved this problem by adding WS_CHILD flag to the call to SetWindowLong. I'm not sure why but it works...
My code:
// Capture the Process's main window and show it inside the applicationPanel panel control.
SetParent(Process.MainWindowHandle, applicationPanel.Handle);
// Change the captured Process's window to one without the standard chrome. Itʼs provided by our tabbed application.
SetWindowLong(Process.MainWindowHandle, (int)WindowLongFlags.GWL_STYLE, (int)(WindowStyles.WS_VISIBLE | WindowStyles.WS_CHILD));
// Change the Process's window position to the top-left corner of the panel
SetWindowPos(Process.MainWindowHandle, IntPtr.Zero, 0, 0, 0, 0, SetWindowPosFlags.IgnoreResize);
I have an app that uses TabTip. When i want to close it i do this:
public void CloseTabTip()
{
foreach (Process pkiller in Process.GetProcesses())
{
if (pkiller.ProcessName.ToString() == "TabTip")
{
pkiller.Kill();
return;
}
}
}
And it trows an exception: access denied. Now the strange thing is that it only does that when i close the TabTip manually. And even stranger than that it only does that when i close it manually using the touch screen. Because when i close it using the mouse it works fine.
The function CloseTabTip is called when i click a button. If i click the button after manually closing the TabTip with touch screen it trows exception but if i close it using mouse it does not.
Now, i have pondered that it was because of this, however even if i wait some seconds for the process to close it still trows this exception. I am thinking this is a Windows bug since it only give an error when i close TabTib using the touch screen.
Any ideas on how to "fix" this? I know i can use a try catch statement but that is not the most correct way of doing things.
Running app in WIN10
I have an ActiveX control written in C# which operates a scanner from the browser using WIA. Everything works fine except the WIA CommonDialog pops under the browser window. How can I get it to show up on top of the browser?
wiaDialog = new WIA.CommonDialog();
wiaImage = wiaDialog.ShowAcquireImage(WiaDeviceType.ScannerDeviceType, WiaImageIntent.UnspecifiedIntent, WiaImageBias.MaximizeQuality, wiaFormatJPEG, false, false, false);
[Edit]
Thanks very much to Noseratio for putting me onto the right track. The suggestion to use BringWindowToTop invoked via a timer before popping up the dialog does not quite work. Instead the function to use is SetForegroundWindow. The code is as follows (invoked from a System.Timer.Timer prior to opening the scan dialog):
public static void scanDialogToTop(Object caller, EventArgs theArgs) {
scanner.theTimer.Stop();
foreach (Process p in Process.GetProcesses()) {
if (p.MainWindowTitle.StartsWith("Scan using")) {
SetForegroundWindow(p.MainWindowHandle);
break;
}
}
}
See this article for a more complete discussion.
It does not look like you can specify a parent window for ShowAcquireImage. If the caption of the popup window is static, you could use FindWindow to find the popup's handle. If ShowAcquireImage is a blocking call (doesn't return until the popup window is closed), before calling it you'd need to setup a timer and call FindWindow upon a timer event. I also suspect the WIA popup is created on a different thread (you could check that with Spy++). If that's the case, you could use the following hack to give the WIA popup window focus. Otherwise you just do BringWindowToTop.
I am currently invoking the windows task manager using a click event in WPF. The event simply executes 'Process.Start("taskmgr").
My question is, is there a way to choose which tab inside task manager is selected when the process starts / is displayed? I am looking to have the 'performance' tab selected automatically whenever the click event is raised.
Thanks for the help.
To expand on Philipp Schmid's post, I've whipped up a little demo:
Run it as a console application. You need to add references to UIAutomationClient and UIAutomationTypes.
One possible improvement you (or I, if you desire) can make is to hide the window initially, only showing it after the correct tab has been selected. I'm not sure if that would work, however, as I'm not sure that AutomationElement.FromHandle would be able to find a hidden window.
Edit: At least on my computer (Windows 7, 32 bit, .Net framework 4.0), the following code initially creates a hidden Task Manager and shows it after the correct tab has been selected. I don't explicitly show the window after selecting the performance tab, so probably one of the automation lines does as a side-effect.
using System;
using System.Diagnostics;
using System.Windows.Automation;
namespace ConsoleApplication2 {
class Program {
static void Main(string[] args) {
// Kill existing instances
foreach (Process pOld in Process.GetProcessesByName("taskmgr")) {
pOld.Kill();
}
// Create a new instance
Process p = new Process();
p.StartInfo.FileName = "taskmgr";
p.StartInfo.CreateNoWindow = true;
p.Start();
Console.WriteLine("Waiting for handle...");
while (p.MainWindowHandle == IntPtr.Zero) ;
AutomationElement aeDesktop = AutomationElement.RootElement;
AutomationElement aeForm = AutomationElement.FromHandle(p.MainWindowHandle);
Console.WriteLine("Got handle");
// Get the tabs control
AutomationElement aeTabs = aeForm.FindFirst(TreeScope.Children,
new PropertyCondition(AutomationElement.ControlTypeProperty,
ControlType.Tab));
// Get a collection of tab pages
AutomationElementCollection aeTabItems = aeTabs.FindAll(TreeScope.Descendants, new PropertyCondition(AutomationElement.ControlTypeProperty,
ControlType.TabItem));
// Set focus to the performance tab
AutomationElement aePerformanceTab = aeTabItems[3];
aePerformanceTab.SetFocus();
}
}
}
Why do I destroy previous instances of Task Manager? When an instance is already open, secondary instances will open but immediately close. My code doesn't check for this, so the code that finds the window handle will freeze.
While taskmgr.exe doesn't have any command line arguments to specify the selected tab, you can use Windows UI Automation to 'navigate' to the performance tab.
Unfortunately, taskmgr.exe does not support any command line argument.
When run, it will always activate the tab that was active on last close.
Starting with Windows 10 build 18305, you can now set a preferred tab to have Task Manager open to by default.
To update:
Click on the start menu and in the search box type 'Windows Update'
Chose 'Windows Update Settings'
In the left panel click 'Preview Builds'
Click on the 'Check' now.
Download the new build.
After update, change dword value of StartUpTab in Win registry key:
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\TaskManager
0 – Processes tab
1 – Performance tab
2 – App history tab
3 – Startup tab
4 – Users tab
5 – Details tab
6 – Services tab
Win CMD:
reg add HKCU\Software\Microsoft\Windows\CurrentVersion\TaskManager /v "startup" /t REG_DWORD /d "1"
This (experimental) feature is only available to some Windows Insiders.
No other tabs except "Start-up" are supported for older builds of Win 10:
taskmgr /4 /startup
To reset:
reg delete HKCU\Software\Microsoft\Windows\CurrentVersion\TaskManager /v "Preferences" /f
To confirm modified key:
REG ADD "HKCU\Software\Microsoft\Windows\CurrentVersion\Applets\Regedit" /v "LastKey" /d "HKCU\Software\Microsoft\Windows\CurrentVersion\TaskManager" /f & regedit
Tested in Win 10 CMD