how to get count of number of opened windows in WPF - c#

I have a requirement that, if one window is opened then user can not allow to open other window, for that I have tried following code.
if(System.Windows.Application.Current.Windows.Count == 0)
{
//My code
}
I am checking for currently opened window count, if it is greater then 1 then user can not open other window and that I will mention inside if statement,
but when I run this code it gives me the error
"Object reference not set to an instance of an object."
Any Solution

You would be probably getting this error because, even for the first windows to be loaded, you would be applying this check. For this you can apply null check in your code.
and for list of loaded windows, you can get it using Application,
var loadedWindows = Application.Current.Windows.Cast<Window>()
.Where(win => win.IsLoaded);

If you want to know how many windows are opened from your application instance, you can do this
l_WindowCount = 0;
foreach(var Window in App.Current.Windows)
{
l_WindowCount += 1
}
if(l_WindowCount > 1)
{
//do what you want to do here
}

Related

Can't restart UWP application via CoreApplication.RequestRestartAsync

I'm trying to restart the application, but I get NotInForeground error every time.
I tried to close every other application and loop the restart attempt to make sure it is in foreground like this
var loopRestart = true;
while (loopRestart)
{
var failureReason = await CoreApplication.RequestRestartAsync("-fastInit -level 1");
loopRestart = failureReason == AppRestartFailureReason.NotInForeground;
}
With or without parameters (from one of the examples found on the internet) it just won't let me do it. When I do CoreApplication.GetCurrentView() is says that the window is ActivatedInForeground quickwatch. At this point I'm lost. Version is 2004

Close IE specific window with C# using Kill is not working

I am trying to close the most recent window/tab of IE but when I call the Kill method the window relaunches without the content of the page.
This is the code that I use to get the most recent IE process:
var a = System.Diagnostics.Process.GetProcessesByName("iexplore");
DateTime earliestStart = DateTime.Today.Subtract(new TimeSpan(1,0,0,0));
System.Diagnostics.Process youngestProccess = a.FirstOrDefault();
foreach(var b in a){
if (b.StartTime > earliestStart)
{
earliestStart = b.StartTime;
youngestProccess = b;
}
}
youngestProccess.Kill();
The code is working in the way that the most recent window "stop" working but the window is not beeing closed
Any idea?
Hi I just discover how to solve the problem.
The message is being thrown because my IE has the option "Enable automatic crash recovery" checked in the Internet Options Advanced tab.
So if you face this you have 2 options: un-check that option forever (which might work for your case) or like in my case you can change the selection via registry keys and when you finish your testing return the value to be on.
So to do this you need to add this to your code before opening IE.
Registry.SetValue("HKEY_CURRENT_USER\\Software\\Microsoft\\Internet Explorer\\Recovery", "AutoRecover", 2);
To turn back on the option you must do the same but with a 0
Registry.SetValue("HKEY_CURRENT_USER\\Software\\Microsoft\\Internet Explorer\\Recovery", "AutoRecover", 0);

How to open broswer's tab on remote machine

Scenario: I have configured Grid 2 and multiple tests are now running in parallel. When test starts there is opened browser window (only one tab opened) and some controls filled inside it. After that I open another tab (in the same browser window), switch to it and fill some controls inside it.
Before filling data inside second tab there needs to be done following steps:
1. Open new tab by calling SendKeys(Keys.Ctrl + 't')
2. Before switching to second tab wait for that second tab's handle to be added to driver instance.
3. If handle added to driver instance then switch to it, else 4.
4. Repeat operation 2. and 3. until timeout reached.
Problem:
When debugging I noticed that when opening a new tab, it's handle was not added to driver.WindowHandles. That means, if not checking if handle added and trying to switch to it, the exception will be thrown. In my case it would switch to incorrect tab as I'm calling driver.SwitchTo().Window(handles[handles.Count() -1]);. So I created method that waits for handle to be added. The problem is that, when running in multiple workers, it always times out. I have changed the timeout but nothing changes. The newly opened tab's handle is not added to WindowHandles. If I'm not running in parallel, then it works as expected.
// previousTabCount- browser's tab count before opening new one
public void WaitForTabToOpenAndSwtich(int previousTabCount)
{
int currentTabCount = driver.WindowHandles.Count();
int count = 0;
while(currentTabCount == previousTabCount)
{
// after 20 seconds throw exception
if(count > 20)
throw new Exception("The newly opened tab's handle was not added.");
// update current tab count
currentTabCount = driver.WindowHandles.Count();
count++;
Thread.Sleep(1000);
}
var handles = driver.WindowHandles;
driver.SwitchTo().Window(handles[handles.Count() -1]);
}
I found the solution. The problem was that when using SendKeys(Keys.Ctrl + 't') to open new tab on remote machine it did not work I'm not sure why. Fortunately I found an alternative approach. Instead of using that send keys command I used:
// script that opens a new tab
driver.ExecuteScript("var w = window.open(); w.document.open();");
After running this script the new tab was opened but I could not change its url by using driver.Navigate().GoToUrl("..."); and exception was thrown:
The HTTP request to the remote WebDriver server for URL 'http:
//example.com' timed out after 60 seconds
So I modified that script a bit by adding a page load at the end like this:
// script that opens new tab and reloads it
driver.ExecuteScript("var w = window.open(); w.document.open(); w.location.reload();");
This worked for me. Maybe someone will find this useful.

How to open "Microsoft Edge" from c# and wait for it to be closed?

I'm building a Windows Form application and I want to open "Microsoft Edge" through my app with a specific URL and wait until the user closes the Edge Window.
I tried it with this code:
using (Process p = Process.Start("microsoft-edge:www.mysite.com"))
{
p.WaitForExit();
}
When I execute this code, Edge is launching with the correct URL ... but got a null object reference. The "p" object that I'm getting from Process.Start is null.
I think it's related to the reuse of Windows application.
Does anyone have a workaround/have an idea how I can wait for the user to close Edge?
Finally I did managed to do so:
When you launch Edge (at least) two process get created:
MicrosoftEdge and MicrosoftEdgeCP.
MicrosoftEdgeCP - foreach tab. So we can "wait" on this new tab process that was just created.
//Edge process is "recycled", therefore no new process is returned.
Process.Start("microsoft-edge:www.mysite.com");
//We need to find the most recent MicrosoftEdgeCP process that is active
Process[] edgeProcessList = Process.GetProcessesByName("MicrosoftEdgeCP");
Process newestEdgeProcess = null;
foreach (Process theprocess in edgeProcessList)
{
if (newestEdgeProcess == null || theprocess.StartTime > newestEdgeProcess.StartTime)
{
newestEdgeProcess = theprocess;
}
}
newestEdgeProcess.WaitForExit();
From an older solution - use a WebBrowser control to load the HTML. Once you get the data back, use an ObjectForScripting to call a c# method to notify when done.
See http://www.codeproject.com/Tips/130267/Call-a-C-Method-From-JavaScript-Hosted-in-a-WebBrowser

I don't want to use Thread.Sleep with SHDocVw.ShellWindows

I have a program where I have to get a SHDocVw.InternetExplorer instance from a running IE8 process. To get the instance the example code below runs. For some reason it won't work without the Thread.Sleep.
The Browser.HWND throws InvalidCastException for all instances in the m_IEFoundBrowsers if the Thread.Sleep is removed. When using the Thread.Sleep it works for the IE8 windows.
Does anyone know how to do this in a way not using Thread.Sleep? (I don't like to use the sleep function, usually it just pushes the problems into the future...)
Example code:
InternetExplorer m_IEBrowser = null;
ShellWindows m_IEFoundBrowsers = new ShellWindowsClass();
Thread.Sleep(10);
foreach (InternetExplorer Browser in m_IEFoundBrowsers)
{
try
{
if (Browser.HWND == (int)m_Proc.MainWindowHandle)
{
m_IEBrowser = Browser;
break;
}
}
catch(InvalidCastException ice)
{
//Do nothing. Browser.HWND could not execute for this item.
}
}
I came across the following link which seems to back up Hans's comment: http://weblogs.asp.net/joberg/archive/2005/05/03/405283.aspx
The article states:
The Internet Controls Library contains
the “ShellWindowsClass” which is
basically a collection of all the
shell windows (e.g.: IE) spawned
across the desktop. That component
provides an event handler called
“Windows Registered” that we are going
to hook up to. Once the process has
been launched, we will wait until the
corresponding window is registered
then we are going to connect our
Internet Explorer control to the shell
window found. To determine if the
window is found, we iterate through
the registered windows and we try to
find a handle that matches the handle
of the process we previously launched.
We will use the “ManualResetEvent”
synchronization primitive to wait a
certain amount of time for the window
to be registered.
I expect you'd be able to map these ideas across to your problem relatively easily.
The article posted by David solved the problem. The first time the code runs in my program it works as described in the article. But if I exit the program, leave the opened IE8 open, open my program again then the the windows_WindowRegistered method got problems with InvalidCastExceptions. Handling these exceptions as shown below made it work as needed.
EXAMPLE CODE:
private void windows_WindowRegistered(int lCookie)
{
if (process == null)
return; // This wasn't our window for sure
for (int i = 0; i < windows.Count; i++)
{
try
{
InternetExplorerLibrary.InternetExplorer ShellWindow = windows.Item(i) as InternetExplorerLibrary.InternetExplorer;
if (ShellWindow != null)
{
IntPtr tmpHWND = (IntPtr)ShellWindow.HWND;
if (tmpHWND == process.MainWindowHandle)
{
IE = ShellWindow;
waitForRegister.Set(); // Signal the constructor that it is safe to go on now.
return;
}
}
}
catch (InvalidCastException ice)
{
//Do nothing. Browser.HWND could not execute for this item.
}
}
}

Categories

Resources