C# White UI Automation: can't find SWT window - c#

I'm using White for UI automation and it was working fine until I met an app that was created in Java. In that case I'm unable to find any windows. If I get all Windows from the desktop then I can see the window's name I'm looking for:
List<White.Core.UIItems.WindowItems.Window> windows = new List<White.Core.UIItems.WindowItems.Window>();
windows = White.Core.Desktop.Instance.Windows();
int a = 0;
for (int i = 0; i < windows.Count; i++)
if (windows[i].Name == "HP Service Manager Client") a = i;
This is working, but if I attach the running process and try to get its windows, then I get nothing, the list will be empty:
windows=app.GetWindows();
This is the code that should find the main window:
var processes = Process.GetProcessesByName("ServiceManager");
White.Core.Application app = White.Core.Application.Attach(processes[0]);
White.Core.UIItems.WindowItems.Window main = app.GetWindow(SearchCriteria.ByText("HP Service Manager Client"), InitializeOption.NoCache);
The error I get: Additional information: Couldn't find window with SearchCriteria Name=HP Service Manager Client in process 7396, after waiting for 5000 ms
I can see the Window in VisualUIAVerify and I know that the name of it is correct.
This is the only app which is not working, IE, Firefox, etc. are all working fine, I can always identify the main window, but this time I can't find any windows at all.
I wonder if someone could explain me why it is doing this and help me to resolve this issue (or find a workaround). Many thanks in advance.

Related

Error on getting device info using DeviceManager

I'm trying to get device info using DeviceManager class in C# and i get the folowing error:
The runtime has encountered a fatal error. The address of the error was at 0x7170f7fc, on thread 0x1448. The error code is 0xc0000005. This error may be a bug in the CLR or in the unsafe or non-verifiable portions of user code. Common sources of this bug include user marshaling errors for COM-interop or PInvoke, which may corrupt the stack.
Here is my code:
// Create a DeviceManager instance
var deviceManager = new DeviceManager();
// Loop through the list of devices and add the name to the listbox
for (int i = 0; i <= deviceManager.DeviceInfos.Count; i++)
{
// Add the device only if it's a scanner
if (deviceManager.DeviceInfos[i].Type != WiaDeviceType.ScannerDeviceType)
{
continue;
}
// Add the Scanner device to the listbox (the entire DeviceInfos object)
listBox1.Items.Add(new Scanner(deviceManager.DeviceInfos[i]));
}
It started happening after i found a solution online to change the WIA service logon
Services -> Windows Image Acquisition (WIA) right click -> Properties -> Log On tab -> select local System Account and Allow service to interact with desktop.
I tried it, didnt work, so I turned back to "This account" with Local Service user.

How to find and list all UWP apps / packages?

My goal is to find and launch a UWP app by name (e.g. Twitter). I'm currently using an elevated desktop extension, following a guide by Stefan Wick.
In my full-trust Win32 console process, I'm currently using the PackageManager to find and list all the UWP apps, and it works on my machine. However, when I send my finalized app package to another user, nothing appears on his screen, even after running elevated.
Here's my current code:
var PkgMgr = new PackageManager();
var currUserPkgs = PkgMgr.FindPackagesForUser(string.Empty);
foreach (Package pkg in currUserPkgs)
{
string pkgName = pkg.DisplayName;
if (pkgName == "")
{
continue;
}
if (pkgName.Contains(appName) || appName.Contains(pkgName) ||
percentSimilarity(appName, pkgName) >= 0.50)
{
// we found it
appPkgName = pkg.Id.FamilyName;
break;
}
}
Why does this not bring up any packages on another user's machine? There's no error message that's called.
Also, is there another solution that can locate all UWP packages? Thank you!

How to get Selenium to operate two browser windows using only one driver selenium (using c# and chromedriver)?

I am attempting to control two browser windows via selenium using c# and a single chromedriver. The reason being that I need to share session details accross browser windows.
The code that I have tried and failed with is below;
var options = new ChromeOptions();
options.AddArguments("chrome.switches", "--disable-extensions --disable-extensions-file-access-check --disable-extensions-http-throttling --disable-infobars --enable-automation ");
options.AddUserProfilePreference("credentials_enable_service", false);
options.AddUserProfilePreference("profile.password_manager_enabled", false);
options.PageLoadStrategy = PageLoadStrategy.Default;
ChromeDriverService service = ChromeDriverService.CreateDefaultService();
service.HideCommandPromptWindow = true;
var Driver = new ChromeDriver(service, options);
//THIS WILL OPEN A NEW WINDOW. BUT BECAUSE IT IS A NEW DRIVER DOES NOT WORK FOR SHARING SESSION DETAILS.
//var TestDriver = new ChromeDriver(service, options);
//TestDriver.Manage().Window.Maximize();
//THIS JUST OPENS UP A NEW TAB. NOT A NEW WINDOW (IT WOULD SEEM MOST DOCUMENTATION SUGGESTS THAT IT SHOULD)
IJavaScriptExecutor jscript = Driver as IJavaScriptExecutor;
jscript.ExecuteScript("window.open();", "google.com.au");
//TRY USING THE SEND KEYS TECHNIQUE. NOTHING HAPPENS
var test = Driver.FindElement(By.TagName("html"));
test.SendKeys(Keys.Control + "n");
test.SendKeys(Keys.Control + "t");
//TRY AGAIN USING THE SEND KEYS TECHNIQUE USING A DIFFERENT TAG. NOTHING HAPPENS
var blah = Driver.FindElements(By.TagName("body"));
blah[0].SendKeys(Keys.Control + "t");
//TRY USING ACTIONS. NOTHING HAPPENS
Actions action = new Actions(Driver);
action.SendKeys(OpenQA.Selenium.Keys.Control + "n");
action.Build().Perform();
I may resort to AutoIt to open a browser if I have to, but one more dependency is not what I need. Documentation everywhere around the web seems to suggest than all the options I tried above should work...I suspect it may be a chromedriver issue of some kind.
Any ideas on how to achieve my goal would be greatly appreciated
UPDATE.
Arnons answer below lead me to the solution. If you are in a similar situation the best thing to do is just open up the browser console (from developers tools) and experiment with javascript until you get what you want. Then just execute that. In the end executing the following code has worked for me.
IJavaScriptExecutor jscript = Driver as IJavaScriptExecutor;
jscript.ExecuteScript("window.open('https://www.bing.com.au','_blank','toolbar = 0, location = 0, menubar = 0')");
The other alternative was to use Autoit, which I also got working, much easier than I did figuring out the javascript. But one less dependency is best :)
UPDATE2.
Further complications arise with trying to control the window as an independent browser window. I believe any new window created from a parent window, has the same process id (at least my testing has indicated so), and for all intense and purpose is treated as a tab in the selinium driver. I therefore conclude that certain things are just not possible (for example relocating the child browser window on the screen).
Your first attempt using ExecuteJavaScript was very close, but In order for it to open a new window instead of new tab, you should add the following arguments: `"_blank", "toolbar=0,location=0,menubar=0" to it.
See this question for more details.
I should have read the question better, here is my solution. Ended up using this for selecting windows that popped up after clicking a button but should work with swapping between windows.
//---- Setup Handles ----
//Create a Handle to come back to window 1
string currentHandle = driver.CurrentWindowHandle;
//Creates a target handle for window 2
string popupWindowHandle = wait.Until<string>((d) =>
{
string foundHandle = null;
// Subtract out the list of known handles. In the case of a single
// popup, the newHandles list will only have one value.
List<string> newHandles = driver.WindowHandles.Except(originalHandles).ToList();
if (newHandles.Count > 0)
{
foundHandle = newHandles[0];
}
return foundHandle;
});
//Now you can use these next 2 lines to continuously swap
//Swaps to window 2
driver.SwitchTo().Window(popupWindowHandle);
// Do stuff here in second window
//Swap back to window 1
driver.SwitchTo().Window(currentHandle);
// Do stuff here in first window
You need to explicitly tell Selenium which tab you wish to interact with, which in this case would be;
driver.SwitchTo().Window(driver.WindowHandles.Last());

UWP MapControl Cannot add a MapIcon when building an app package that targets an older OS

I am trying to add a MapIcon to my Bing maps control. When I am running the application in my debugging environment on visual studio I don't have any issues. However once I build my app package and run it, adding a map Icon crashes the application and throws this an exception that reads:
"Unable to cast object of type Windows.UI.Xaml.Controls.Maps.MapIcon to type Windows.UI.Xaml.Controls.Maps.IMapElement4"
Here is the simple code that instantiates the MapIcon. It is important to know that I do not have any issues adding these map Icons in debug mode. The problem only exists once the app package has been built and run. I was able to pinpoint the exception using a try/catch to display the exception while the released app is running. If anyone can help me to get rid of this exception, or have any advice for a work around, it would be much appreciated
MapIcon messageicon2_2 = new MapIcon
{
Location = message_position,
NormalizedAnchorPoint = new Point(0.5, 1.0),
ZIndex = 0,
Title = "msg " + count + "(2.2)",
IsEnabled = true,
CollisionBehaviorDesired = MapElementCollisionBehavior.RemainVisible
};
MyWaypoints.Add(messageicon2_2);
messageLayer.MapElements = MyWaypoints;
[EDIT To Clarify]: I know that this bug is coming specifically from the instantiation of the Mapicon. This code works perfectly fine when it is released and run on a Windows 10 17134 machine.... The machine that I need it to run is Windows 10 16299. This machine can not be updated to a newer version of windows. I am in need of a way to display these map icons on this older release of windows.
The exception points to the IsEnabled property which was added to MapElement for Windows OS Version 1803 (17134). See MapElement.IsEnabled Property.
I know the exception is not the most helpful, but maybe there was some other warning about it that got missed?
For errors like this, you can either remove all uses of the missing API and/or make sure to write version adaptive code that can run on the lowest OS version, while also taking advantage of the selected features that are available only on certain OS versions.
Specifically you can do something like:
var messageicon2_2= new MapIcon
{
Location = message_position,
NormalizedAnchorPoint = new Point(0.5, 1.0),
ZIndex = 0,
Title = "msg " + count + "(2.2)",
CollisionBehaviorDesired = MapElementCollisionBehavior.RemainVisible
};
if (ApiInformation.IsPropertyPresent("Windows.UI.Xaml.Controls.Maps.MapElement", "IsEnabled"))
{
messageicon2_2.IsEnabled = true;
}
MyWaypoints.Add(messageicon2_2);
messageLayer.MapElements = MyWaypoints;

Showing a Windows 10 toast notification

I'm developing a program in C# (Visual Studio 2015) and I want to show a toast message to the user at a certain situation. I downloaded this code from the MSDN and it runs fine:
// Get a toast XML template
XmlDocument toastXml = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastImageAndText04);
// Fill in the text elements
XmlNodeList stringElements = toastXml.GetElementsByTagName("text");
for (int i = 0; i < stringElements.Length; i++)
{
stringElements[i].AppendChild(toastXml.CreateTextNode("Line " + i));
}
// Specify the absolute path to an image
String imagePath = "file:///" + Path.GetFullPath("toastImageAndText.png");
XmlNodeList imageElements = toastXml.GetElementsByTagName("image");
imageElements[0].Attributes.GetNamedItem("src").NodeValue = imagePath;
// Create the toast and attach event listeners
ToastNotification toast = new ToastNotification(toastXml);
toast.Activated += ToastActivated;
toast.Dismissed += ToastDismissed;
toast.Failed += ToastFailed;
// Show the toast. Be sure to specify the AppUserModelId on your application's shortcut!
ToastNotificationManager.CreateToastNotifier(APP_ID).Show(toast);
After testing this code I wanted to implement it into my application. So I changed it up a little bit and tried to run it. The error messages:
The type "IReadOnlyList<>" is defined in a not referenced assembly. Add a reference to System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
(translated)
Same goes for IEnumerable<> and IReadOnlyList<>
The error come from these two lines:
for (int i = 0; i < stringElements.Length; i++)
{
stringElements[i].AppendChild(toastXml.CreateTextNode("Line " + i));
I also tried adding the reference to System.Runtime. I downloaded it with NuGet (https://www.nuget.org/packages/System.Runtime/4.0.0/).
After that the errors were gone, but now literaly every word in my code is cringled red with error like "System.Object is not defined" and so on (but it still runs when I start it!).
The only possible solution I can think of is that System.Runtime is already installed somewhere on my computer, and that 4.0.0 is the wrong version for my program. But I can't find it anywhere.
PS: It's a desktop-application, not a Windows-Store application.
I think it is the same problem as in this question
You must add a reference to
C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\Facades\System.Runtime.dll
PS : If you have a Windows 10 only desktop app, you might want to use the new toast system, the code sample on MSDN uses the Windows 8 one. it works on W10 but does not have all the new features (Microsoft released an official NuGet package).
Edit : Since I can't comment, I will post the answer here :
The exception is because you need to provide an applicationId in CreateToastNotifier()
ToastNotificationManager.CreateToastNotifier("MyApplicationId").Show(toast);
It is the name that will be used in the action center to group your toasts (so in general, you put the name of your app). In Windows 8.1 it was needed to register your application Id (I think this was in the sample from the MSDN) but now you can just put the name of your app.
And the GetXml() is only for WinRT. In desktop you need to do like you did with the GetContent().

Categories

Resources