WinAppDriver
WinAppDriver copied to clipboard
Allow to attach the process based on Process ID
Appium option should allow to attach the currently running process based on the Process ID
This is a feature request.
This will attach the currently running process to session without using Root session
var processes = Process.GetProcesses(); bool exi = false; foreach (var process in processes) {
string v = "";
try
{
v = process.MainModule.FileName;
}
catch { }
if (v.ToUpper() == ApplicationPath.ToUpper())
{
WindowHandle = process.MainWindowHandle.ToString("x");
exi = true;
break;
}
}
//////////
AppiumOptions Prop = new AppiumOptions();
Prop.AddAdditionalCapability("appTopLevelWindow", WindowHandle);
Prop.AddAdditionalCapability("deviceName", "WindowsPC");
Prop.AddAdditionalCapability("platformName", "Windows");
Session = new WindowsDriver<WindowsElement>(new Uri(@"http://localhost:4723/"), Prop);
Thanks very much for the answer, I didn't know it was a possibility.
@naeemakram you can use next method https://github.com/microsoft/WinAppDriver/issues/534#issuecomment-562030077
Process.GetProcesses() is working on local machine. how can we get processes in remote machine ? via remote WinAppDriver, I start an application, the application has a separate dialog. from Inspect, it is independent from the main session but has the same pid. my problem is how to get a windows handle for that dialog. windAppDriver.WindowHandles only give me the main windows. thanks and regards
Yes it is not possible to get Window handle from a remote machine. If any one can give suggestion to get WindowsHandle from a remote machine will be very helpful.
Yes it is not possible to ge
Create new console app, the console app supply grpc or http service on server, response processes to clients,
the console app start with the codes blow:
var startInfo = new ProcessStartInfo("C:\\Program Files\\Windows Application Driver\\WinAppDriver.exe");
var winAppDriverProcess = Process.Start(startInfo);
The client can get processes from remote machine.
The ability to minimize the application to the Taskbar is a standard behavior of the vast majority of Windows applications. we have an option to minimize (or close) the program to the system tray (officially known as the Notification Area) that is usually located next to the Taskbar in the bottom-right corner.
process.MainWindowHandle is 0x0000000000000000 Session can not created by process.MainWindowHandle
[DllImport("user32.dll", EntryPoint = "FindWindow", CharSet = CharSet.Unicode)]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", EntryPoint = "FindWindowEx", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string? lpszClass, string? lpszWindow);
public static List<IntPtr> FindAllWindowHandles(IntPtr hParent, string lpszClass, string lpszWindow)
{
var windowHandles = new List<IntPtr>();
IntPtr prevChild = IntPtr.Zero;
while (true)
{
var currChild = FindWindowEx(hParent, prevChild, lpszClass, lpszWindow);
if (currChild == IntPtr.Zero)
break;
windowHandles.Add(currChild);
prevChild = currChild;
}
return windowHandles;
}
// Find one WindowHandle, other WindowHandles are being ignored
var windowHandle = FindWindow("YourClassName", "YourWindowName");
// Find all WindowHandles
var windowHandles = FindAllWindowHandles(IntPtr.Zero, "YourClassName", "YourWindowName");
If nativeWindowHandle is not 0x0000000000000000, you can create Session by windowHandle.
/// <summary>
/// Create WindowsDriver by WindowHandle
/// </summary>
/// <param name="windowHandle">WindowHandle</param>
/// <param name="implicitWait">Gets or sets the implicit wait timeout, which is the amount of time the driver should wait when searching for an element if it is not immediately present.</param>
/// <returns>WindowsDriver</returns>
public static WindowsDriver<WindowsElement>? CreateWindowsDriver(IntPtr windowHandle, double implicitWait = 1500)
{
if (windowHandle.ToInt32() == 0) return null;
var windowHandleHex = windowHandle.ToInt32().ToString("x");
var options = new OpenQA.Selenium.Appium.AppiumOptions();
options.AddAdditionalCapability("deviceName", "WindowsPC");
options.AddAdditionalCapability("appTopLevelWindow", windowHandleHex);
var session = new WindowsDriver<WindowsElement>(WindowsApplicationDriver.RemoteAddress, options);
// Set implicit timeout to 1.5 seconds to ensure element search retries every 500 ms for at most three times
session.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(implicitWait);
return session;
}
I found a workaround, find your desired applications WindowHandle, then directly create session using extracted WindowHandle. Traversing from root is not worthy. I found a lot of people are complaining about how to switch I hope this will help a lot!
import win32gui
def findWindowHandle():
handleList = []
def findit(hwnd,ctx):
if win32gui.GetWindowText(hwnd) == "Microsoft Store": # check the title
handleList.append(hwnd)
win32gui.EnumWindows(findit,None)
return handleList
handle = hex(findWindowHandle()[0])
print(handle)
desired_caps = {}
desired_caps["appTopLevelWindow"] = handle
desired_caps["deviceName"]="WindowsPC"
desired_caps["platformName"]="Windows"
session = webdriver.Remote(command_executor='http://127.0.0.1:4723', desired_capabilities= desired_caps)