Question
Accenture
US
Last activity: 6 Nov 2018 20:02 EST
How to download an attachment from WebUrl through windows adapter
Hi,
I have a requirement to download an attachment from a Web Url in Windows Automation. (When I click a button in my windows application, it will open an URL in a default browser). But am unable to Interrogate the web download window or Save button. Can you please help. Below is the screenshot
Thanks,
Arun
**Moderation Team has archived post**
This post has been archived for educational purposes. Contents and links will no longer be updated. If you have the same/similar question, please write a new post.
-
Like (0)
-
Share this page Facebook Twitter LinkedIn Email Copying... Copied!
Accepted Solution
Accenture
US
Hi Jeff,
Now am able to save the IE11 attachment with openspan using below code.
Hi Jeff,
Now am able to save the IE11 attachment with openspan using below code.
IntPtr handle = GetWindowHandle(control);
if(handle != IntPtr.Zero)
{
AutomationElementCollection ParentElements = AutomationElement.FromHandle(handle).FindAll(TreeScope.Children, Condition.TrueCondition);
foreach (AutomationElement ParentElement in ParentElements)
{
if(ParentElement.Current.ClassName == "Frame Notification Bar")
{
var childElements = ParentElement.FindAll(TreeScope.Children, Condition.TrueCondition);
foreach (AutomationElement childElement in childElements)
{
if (childElement.Current.Name == "Notification" || childElement.Current.ClassName == "DirectUIHWND")
{
var downloadCtrls = childElement.FindAll(TreeScope.Children, Condition.TrueCondition);
foreach (AutomationElement ctrlButton in downloadCtrls)
{
if (ctrlButton.Current.Name.ToLower() == "save")
{
var invokePattern = ctrlButton.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern;
invokePattern.Invoke();
result = true;
}
}
}
}
}
}
Accenture
US
Hi Team,
Any update on this Thread..?
Thanks,
Arun
Pegasystems Inc.
US
first thing you want to do is to interrogate the download bar. Here is how to do it.
Cigna Health Solutions India Pvt Ltd
IN
Hi,
I am unable to interrogate the download bar in Google Chrome. Can u please help me to check the download status of a file once the downloaded the file i need to rename the same file?
Pegasystems Inc.
IN
Hello!
We've created a new post to drive your query further: unable to interrogate the download bar in Google Chrome
Please continue the discussion over the new post.
Pegasystems Inc.
US
Here is a sample solution that shows how to save the download. This solution uses UIAutomation to click the download option.
https://support.openspan.com/FileManagement/Download/d892702ee0414c458c1e801ccb4707b1
Accenture
US
Hi Jeff,
I tried with the sample you provided. But getting 'Object reference not set to instance of an object" error. Will it be because of IE version? am using IE11. here is the screenshot.
Cognizant Technology Solutions
US
This link is no longer accessible. Could you please provide one which we can download?
Comptech Associates Inc
US
Hi Jeff,
That link is broken. Thomas originally posted it for me and I need it again. Is there some way to post it again? If there is no way to download, could you post the entire script in a txt file?
Ed
Pegasystems Inc.
US
Here is a new implementation for working with the DownloadBar. This solution was written using version 8.0.1080 and uses the latest features of the product at the time. There is a new feature named ClickChildByText which allows you to click options on the DownloadBar by specifying the text on the control.
Pegasystems Inc.
US
Arun,
Have you tried the Save or SaveAs option? This does work with IE 11 on my machine. This exception message is coming out of the Choose script. Try another option (Save or SaveAs) to see if you get the same exception.
if neither of those work, check in interrogation mode to see if the ctlDownloadBar control is created when the download bar is visible.
Accenture
US
Jeff,
I got this error, when I click on Save or SaveAs. And yes ctlDownloadBar is created too
Accepted Solution
Accenture
US
Hi Jeff,
Now am able to save the IE11 attachment with openspan using below code.
Hi Jeff,
Now am able to save the IE11 attachment with openspan using below code.
IntPtr handle = GetWindowHandle(control);
if(handle != IntPtr.Zero)
{
AutomationElementCollection ParentElements = AutomationElement.FromHandle(handle).FindAll(TreeScope.Children, Condition.TrueCondition);
foreach (AutomationElement ParentElement in ParentElements)
{
if(ParentElement.Current.ClassName == "Frame Notification Bar")
{
var childElements = ParentElement.FindAll(TreeScope.Children, Condition.TrueCondition);
foreach (AutomationElement childElement in childElements)
{
if (childElement.Current.Name == "Notification" || childElement.Current.ClassName == "DirectUIHWND")
{
var downloadCtrls = childElement.FindAll(TreeScope.Children, Condition.TrueCondition);
foreach (AutomationElement ctrlButton in downloadCtrls)
{
if (ctrlButton.Current.Name.ToLower() == "save")
{
var invokePattern = ctrlButton.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern;
invokePattern.Invoke();
result = true;
}
}
}
}
}
}
Pegasystems Inc.
US
I have found that the scripts in the attached solution sometimes required me to "hard-code" the option into the script rather than accept it as a parameters. This explains why your new script works with very similar code to the original.
Pegasystems Inc.
US
There are a couple things that are important to recognize about the download bar;
- There is only one download bar control (i.e. a control with a window handle).
- This means that if multiple ones become visible, you cannot tell them apart, so be sure to handle them in order and close one before causing a new one to show.
- Once shown, the control becomes invisible but it will always be matched from then on.
Pegasystems Inc.
US
Here is a script I have used after clicking Save or Save As to detect when the download is complete.
Parameters: OpenSpan.Adapters.Controls.Control control, int timeout
Result type: bool
bool result = false;
DateTime stopTime = DateTime.Now.AddMilliseconds(timeout);
IntPtr handle = GetWindowHandle(control);
if (handle != IntPtr.Zero)
{
System.Windows.Automation.AutomationElement aeDownloadToolBar = System.Windows.Automation.AutomationElement.FromHandle(handle);
if (aeDownloadToolBar != null)
{
System.Windows.Automation.AutomationElement aeButton;
while(DateTime.Now < stopTime)
{
aeButton = aeDownloadToolBar.FindFirst(System.Windows.Automation.TreeScope.Children, new System.Windows.Automation.PropertyCondition(System.Windows.Automation.AutomationElement.NameProperty, "Open folder"));
if (aeButton != null)
{
result = true;
break;
}
else
{ System.Threading.Thread.Sleep(100); }
}
}
}
return result;
Accenture
IN
Hi Jeff,
We've used the solution provided in the link : https://support.openspan.com/FileManagement/Download/d892702ee0414c458c1e801ccb4707b1
and it works very well for our solution in the development environment (VDI and with full admin right access).
But when we deploy the solution onto the production environment ( non-VDI and with no admin rights), this solution or any other solution provided in this article doesn't work at all, even though all the controls match.
I am attaching the snapshots of all the methods in the script , the automation flow and the message that gets displayed when the download doesnt happen. Also, you would notice, that for debugging purpose I have added message boxes in the 'DonwloadSaveAs' method... but none of these messages get displayed since the 'aeDownloadToolBar' is getting returned as 'Null' .
The same happens with the 'ClickButton' method as well.
Need your advice here and please do let me know if you'd need any more information from my end to give you more clarity on this issue.
Thanks
Richa Chopra
Pegasystems Inc.
US
If you can do interrogation on a machine that doesn't work you should be able to fix the matching on the aeDownloadToolbar. That would be the first thing to look at and probably will solve your issue.
The scripts use UIAutomation to find the toolbar. You will need a copy of the Windows SDK to troubleshoot them. Once you have that installed you can use the Inspect Objects program to look at the hierarchy and debug the scripts.
-
MADHURI SUPRIYA PEDAMALLU
Pegasystems Inc.
US
For those who may need a textual layout of the script.
The original script contains four methods, choose, clickbutton, downloadsaveas, and getwindowhandle.
All four methods use the following imports
using:
using System.Windows.Automation;
using OpenSpan.Diagnostics;
name: choose
input parameters: OpenSpan.Adapters.Controls.Control control, int pauseDuration, string choice, out string message
For those who may need a textual layout of the script.
The original script contains four methods, choose, clickbutton, downloadsaveas, and getwindowhandle.
All four methods use the following imports
using:
using System.Windows.Automation;
using OpenSpan.Diagnostics;
name: choose
input parameters: OpenSpan.Adapters.Controls.Control control, int pauseDuration, string choice, out string message
output parameters: bool
Method Body:
Diagnostic.TraceVerbose("Script", string.Format("Choose script running, Choice: {0}", choice));
switch (choice)
{
case "Open":
return ClickButton(control, pauseDuration, "Open", out message);
case "Save":
return ClickButton(control, pauseDuration, "Save", out message);
case "Save As":
return DownloadSaveAs(control, pauseDuration, out message);
case "Show all content":
return ClickButton(control, pauseDuration, "Show all content", out message);
}
message = "invalid option";
Diagnostic.TraceVerbose("Script", string.Format("Choose script complete, Message: {0}, Result: FALSE", message));
return false;
========================================================================================
Name: clickButton
Input Parameter: OpenSpan.Adapters.Controls.Control control, int pauseDuration, string text, out string message
Output Parameter: bool
Method Body:
Diagnostic.TraceVerbose("Script", string.Format("ClickButton script running, Text: {0}", text));
bool result = false;
message = "";
try
{
IntPtr handle = GetWindowHandle(control);
if(handle != IntPtr.Zero)
{
System.Windows.Automation.AutomationElement aeDownloadToolBar = System.Windows.Automation.AutomationElement.FromHandle(handle);
if (aeDownloadToolBar != null)
{
//I'm assuming this is doing something similar to MSAA's PerformDefaultAction. Haven't researched it though.
System.Windows.Automation.AutomationElement aeButton = aeDownloadToolBar.FindFirst(System.Windows.Automation.TreeScope.Children, new System.Windows.Automation.PropertyCondition(System.Windows.Automation.AutomationElement.NameProperty, text));
System.Windows.Automation.InvokePattern ipClickButton1 = (System.Windows.Automation.InvokePattern) aeButton.GetCurrentPattern(System.Windows.Automation.InvokePattern.Pattern);
if(ipClickButton1 != null)
{
System.Threading.Thread.Sleep(pauseDuration);
ipClickButton1.Invoke();
result = true;
}
else
{
message = "null button";
}
}else{
message = "null toolbar";
}
}else
{
message = "Zero Ptr";
}
}
catch(Exception e)
{
OpenSpan.Diagnostics.Diagnostic.PublishException(e,null);
message = e.Message;
}
return result;
================================================================================================
Name: DownloadSaveAs
Input Parameter: OpenSpan.Adapters.Controls.Control control, int pauseDuration, out string message
Output Parameter: bool
Method Body:
Diagnostic.TraceVerbose("Script", "DownloadSaveAs script running");
message = "";
bool result = false;
try
{
IntPtr handle = GetWindowHandle(control);
if(handle != IntPtr.Zero)
{
AutomationElement aeDownloadToolBar = AutomationElement.FromHandle(handle);
AutomationElement rootElement = AutomationElement.RootElement;
if (aeDownloadToolBar != null)
{
AutomationElement splitButton = aeDownloadToolBar.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.NameProperty, ""));
InvokePattern ipClickButton1 = (InvokePattern)splitButton.GetCurrentPattern(InvokePattern.Pattern);
System.Threading.Thread.Sleep(pauseDuration);
ipClickButton1.Invoke();
System.Threading.Thread.Sleep(pauseDuration);
PropertyCondition condition2 = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Menu);
AutomationElement contextMenu = rootElement.FindFirst(TreeScope.Children, condition2);
AutomationElement saveAsButton = contextMenu.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, "Save as"));
InvokePattern ipClickButton2 = (InvokePattern)saveAsButton.GetCurrentPattern(InvokePattern.Pattern);
System.Threading.Thread.Sleep(pauseDuration);
ipClickButton2.Invoke();
result = true;
}
}
}
catch (Exception ex)
{
Diagnostic.PublishException(ex, null);
message = ex.Message;
}
return result;
====================================================================================
Name: GetWindowHandle
Input Parameters: OpenSpan.Adapters.Controls.Control control1
Output Parameters: IntPtr
Method Body:
OpenSpan.Adapters.Windows.Window targetWindow = control1.Target as OpenSpan.Adapters.Windows.Window;
if(targetWindow != null)
{
return targetWindow.Handle;
}
return IntPtr.Zero;
Flextronics Technology Co Ltd
CN
Hi, failed to save files by below step.
AutomationElement saveAsButton = contextMenu.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, "Save as"));
Pegasystems Inc.
US
Here is a new link to the solution referenced above.
KPMG
PT
Hello,
I have been trying to use this solution and I already managed to download the file.
Now, I need to know the file name so I can search for it in the file system and send it by email.
Any idea how I can get the filename?
Thanks
Pegasystems Inc.
US
If you are using the Save function, it will save the files to the users Download folder (at least in every case I have seen).
string downloadFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Downloads");
You'll need to use a little more C# to actually accomplish this. The line above will get you to the user's download folder. From here you can iterate all of the files and grabbing the latest one. There are many ways to do this of varying complexity, so I'll let you select the one that you understand best.
If you have any issues selecting one, let me know and I can take a screenshot of the script in Studio for you.
Genpact
US
All,
Thanks for the detailed solution. It works well for me - however, the "Save" button click does not happen if the machine is locked. Is that a limitation with this approach? Any advise on how I can get that to happen even if the machine is locked?
Thanks
Aravind
Pegasystems Inc.
US
This will not work when the machine is locked. You will need to leave the machine unlocked as the IE Download bar is not actually created by IE while the machine is locked as it knows it doesn't need to create the control because no one is there to use it.
EY
CL
Hello all
How can I apply this solution without adding a windows form? What I want is that inmediatly after the robot clicks the button that triggers the download, it clicks on the save as button, and allow the robot to specify a name and folder where the file will be downloaded.
Thanks
Nicolás
-
Rohit Sud
Pegasystems Inc.
US
You do not need to use a Windows Form. Simply call the automations using your event as the trigger for the automation instead of the click event from the Windows Form.
Genpact
IN
Hi All,
I am using the script in correct answer but while validating the script i am facing an error.
Can anyone help me in this.Please find the error below.
Pegasystems Inc.
US
Make sure you add the following references to your script;
OpenSpan.Automation.dll - Click the "File" button to browse to the installation directory to locate
OpenSpan.dll - Click the "File" button to browse to the installation directory to locate
UIAutomationClient - Click the "GAC" button to locate
UIAutomationTypes - Click the "GAC" button to locate
Genpact
IN
Thank You sasnt, issue resolved.
Primerica
US
Hi All,
I want to download excel from a website. I am using script to download with four method as per thomz code. i am getting popup window, in that i am getting that open,save,close buttons window. In script its giving result false. not able to open,save or save as. Could you please anyone help me in this. Please find the attached screenshot.
Thanks.
Pegasystems Inc.
US
You are likely not matching the download bar. Make sure you interrogate it inside the popup window as that is what gets passed into the script.
Flextronics Technology Co Ltd
CN
But, still can't use 'Save as'..
If you just want to save, the method 'sendkey' is more easier.
Pegasystems Inc.
US
Save As is challenging because it is not an option within the control itself, but rather a desktop menu item. The script required to do that would need to locate the desktop first and then find Save As as a child of that. In my experience, Save will cause the file to go to the user's Downloads folder. Since this is a known location, you could then write a script to grab the latest file from here and move it to wherever it needs to go.
Polisetti
US
Hi Thomas,
Seems this solution is not working in windows 10 with 1087 ver.
Can you suggest if there is issue with windows 10 to execute this script.
Script is validated and build got succeeded, When the bot reaches to download Save as, It simply not executing the script.
Any suggestions would be helpful.
Thanks.