python pywinauto file selection dialog - python-3.x

I am in the process of automating a firmware update for a specific component we use a work a lot. I have the automation of the gui completed (and working) except for this particular screen.
What I need to do, is have the program automatically navigate to the correct folder (standardized across machines) and select the correct file to use for the update.
Here is my code so far:
from pywinauto.application import Application
app = Application(backend='win32').connect(title_re=".*EBDS*", found_index=0)
main_dlg = app.window(title_re=".*EBDS*", found_index=0)
main_dlg.child_window(title="Launch Control Panel", control_type="System.Windows.Forms.Button").click()
sub_dlg = app.window(title_re=".*Bill Acceptor*", found_index=0)
sub_dlg.child_window(title="Open", control_type="System.Windows.Forms.Button").click()
sub_dlg.child_window(title="Download", control_type="System.Windows.Forms.Button").click()
file_dlg = app.window(title_re=".*download*", found_index=0)
It has a couple sub windows that pop up after clicking, thus the main_dlg, sub_dlg, and file_dlg.
I have already told it to select the download button, and it pops up the "select a file to download" window.
What I need to do now is be able to specify the path (where it says This PC), change the file type (currently says Bin files), and select the correct file.
I have done a "print control identifiers" and here is the link to the txt file of that output (it's over 3k lines, so I didn't want to paste it here) Control Identifiers .txt
What I then did was I correctly (manually) went through the steps to get it where it needs to be, and did another "print control identifiers." Again, this is over 3k lines long, so here is a Link to that output.
Assuming that I'm doing this right, the file path location in the gui is:
file_dlg.child_window(title="Select a file to download.", class_name='#32770').child_window(class_name="WorkerW").child_window(class_name="ReBarWindow32").child_window(class_name="Address Band Root").child_window(class_name="msctls_progress32").child_window(class_name="Breadcrumb Parent").child_window(title=".*Address:*", class_name="ToolbarWindow32")
The question is, how do I interact with that object specifically? A .click() or .sendkeys() both error out.
Bonus points if you can figure out how to change the file type.
I'm open to an easier/different way of doing this, however this has to be deployable to a couple hundred machines that don't have the same screen size, ergo I cannot use pyautogui and pixel counts.
Any ideas?

You can enter the full file path to the edit box and click "Open" button. It should look like this:
file_dlg = app.window(title_re=".*Select a file to download*", found_index=0)
file_dlg.FileNameEdit.set_edit_text("full_path_to_file")
file_dlg.child_window(title="&Open", control_type="Button").click()
I assume you have to bypass .click_input() and .type_keys(...) usage as they require active desktop which is hard to maintain on a big pool of machines.

Related

How can I use Base64 image paths in AppleScript?

I have come up with an AppleScript, to monitor my VPN connection from VPN Tracker. So far I got the code working, meaning it shows the correct state as text. I created two PNG files, which I converted into Base64 and would like to use those as the status output, instead of just having text. The reason for the Base64 conversion of the images is, so I can share the script with others, without needing to share the actual images as well and expect the user to put them somewhere on his Mac.
I am however unsure of how to decode those Base64 strings in AppleScript, so it shows the actual image in the end.
This is the code I have so far (with the text output)
set conn_state to "" as string
if application "VPN Tracker 365" is running then
tell application "VPN Tracker 365"
try
if name of groups contains "group_name" then
set conn_state to state of connection of group ("group_name") as string
if conn_state = "On" then
return "VPN active"
else
return "VPN inactive"
end if
end if
on error
return "An error occured"
end try
end tell
end if
I did do some research on the internet but could not find anything that would help me, solve this problem, or I was maybe not using the right search terms.
Any help would be much appreciated. Thanks in advance
"The reason for the Base64 conversion of the images is, so I can share the script with others, without needing to share the actual images as well and expect the user to put them somewhere on his Mac."
Consider taking a different approach. The following solution will enable the image(s) to be bundled within your Applescript and avoid having to Base64 encode/decode them:
Save your AppleScript as an "Application" format via the AppleScript Editor.
Locate your resultant application via the "Finder"
Click on it while pressing the ctrl key.
Via the context menu choose "Show Package Contents".
Copy your .png image(s) to the Contents/Resources folder.
Then in your code access the path to the image as follows:
# Get the pathname to where this script resides in the filesyetem.
set pathToMe to (path to me) as text
# Create the full pathname to the image
set pathToPng to pathToMe & "Contents:Resources:img.png" as alias
# Just a demo to illustrate that the image path can be accessed.
tell application "Preview" to open pathToPng
Note: This example code assumes you've copied an image named img.png to the Contents/Resources folder. It firstly obtains the path to wherever your app is located and assigns the images path to the pathToPng variable
Edit:
Or, as #user3439894 kindly mentioned in the comments, simply use the following code to obtain the path to the image(s) directly:
# Create the full pathname to the image
set pathToPng to path to resource "img.png"
# Just a demo to illustrate that the image path can be accessed.
tell application "Preview" to open pathToPng
Note: This utilizes path to resource to obtain the path of the image, and the aforementioned steps 1-3 are still necessary

MAC OS X difference between "open APP.app" and "APP.app/content/MacOs/APP" shell scripts

Somehow I get a problem, if I call an application twice or several times but only one instance should be running (which is desired).
First some (probably necessary) background information:
working on MAC OS X El Capitan (10.11.6)
I've got an Application made by node.js, electron and build by "npm build -m" (let's call it APP.app)
I installed the application App.app into program-folder by opening the built dmg-file and move it into the program-folder
Then I start the application App.app by click on the App.app-icon in program-folder
The application starts with a visible Window and also has an hidden background process running
If I close the visible Window, the App.app-Icon remains in the dock (which is okay, since the background-process is still running)
Now (and this is the difference to the windows build and running in windows), if I click again on the App.app-Icon in the program-folder, I only get a focus on the already running application INSTEAD of opening the window and close the old application (I can see te focus switch/activation by the switching menu name beside the apple-logo on top of the screen; it becomes "App")
the closing of the previous running instance is defined in electron code in the init-method as follows:
var shouldQuit = app.makeSingleInstance(function (commandLine, workingDirectory) {
console.info('starting new instance');
initInternal(commandLine);
// Someone tried to run a second instance, we should focus our window.
var windows = options.closeWindowsOnRestart ? Browser.getAllWindows() : appWindows.slice();
windows.forEach(function (val, index) {
val.close();
});
readyCallback();
});
So, I did some homework and could figure out following:
my App.app-icon-click should look something like open /Applications/App.app
with this, I get the same problem as descriped above if I call it again (it only focusses the already opened window)
Now comes the funny part. If I open the application by calling directly /Applications/App.app/content/MacOS/App.app the old application-instance is closed and new App.app-application is started
I read through open-manual and could figure out, that if I use the -n-flag, the application starts succesful a new instance, too. (open /Applications/App.app -n)
I was wondering WHY? Do you have any clues? What is the difference between open and directly call of the application?
I suggest that the info.pklist in App.app-package is making the open-call different to the direct call of App.app.
BTW:
Unfortunately I already tried to add try-catch-blocks to debug the problem, but open does not give an output to terminal, it just opens the call whereas the direct call does not throw an error and everything works fine.
Anyway, I believe it's more a MAC OS X problem than an App.app-problem.
Hopefully there's somebody with same problems and a solution for me
Don't hesitate to ask for more details, if needed.
Short Version:
open starts the application with the LaunchService (and possible
added launch-parameters in info.plist)
whereas direct call of the
application just starts the application iself without any other
launch-options
*Long Version *
I read through the open manual (man open; Source: https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man1/open.1.html) and could figure out, that "the default application as determined via LaunchServices is used to open the specified files" if you click on an item.
So I read through the LaunchService-documentation and could figure out following:
"Opening Items by File-System Reference [...] default way:
If the designated item is an application: [...]
If the application is already running, it is activated (brought to the front of the screen) and sent an 'rapp' (“reopen
application”) Apple event."
(Source: https://developer.apple.com/library/content/documentation/Carbon/Conceptual/LaunchServicesConcepts/LSCTasks/LSCTasks.html#//apple_ref/doc/uid/TP30000999-CH203-TP9)
This reflects exactly my watching that if I click on the icon the second time, the app is just focussed/activated.
Thus I need the possibility to tell the application to open a new instance (oapp-event) instead of activating the already opened application (rapp-event)
Further reading lead me to following informations:
"Launch Options When opening an application (whether by itself or to
open one or more documents or URLs), you can specify various launch
options to control the manner in which it is launched or activated.
These can include: [...] Whether to launch a new instance of the
application, even if another instance is already running"
(Source: https://developer.apple.com/library/content/documentation/Carbon/Conceptual/LaunchServicesConcepts/LSCConcepts/LSCConcepts.html#//apple_ref/doc/uid/TP30000999-CH202-BABBJHID)
Thus I only need to add the "launch option" to define, that a new instance should be created instead of activating the existing one. But there's not written what the launch-option for it is and how they will be applied to the application (I suggest it belongs into info.plist-file).
So at least this is the answer to my original question, so I posted it here.
open - starts the application with the Launch-Service (and the defined option-parameters in info.plist)
whereas direct call of the application just starts the application iself without any other launch-options

xlsread、xlswrite not work in matlab

matlab (2015b) in my new notebook ThinkPad function xlsread/ xlswrite not work
for every exist excel file, xlsread not load the data
xlswrite also not work in every path
error use xlsread (line251)
catch exception
if isempty(exception.identifier)
exception = MException('MATLAB:xlsreadold:FormatError','%s', exception.message);
end
throw(exception);
the method import data also not work for excel file。
I found this answer in
https://cn.mathworks.com/matlabcentral/answers/282688-why-my-excel-file-can-not-be-read-by-matlab hope it can help you:
Who has problem to read excel file, can follow this order.
1- open the excel> file, >option, >add in, manage then select COM ADD IN, and clear everything (unchecked). everything should be cleared (unchecked).
2- restart the PC, and open the matlab.
3- perform xlsread command.
NOTE: for those people who use foxit pdf reader, it is potential to face this problem, so follow mentioned order.
NOTE: sometimes by using the matlab, configuration of excel is changed in unknown way, therefore there is no way to open the usual excel file in windows by double click.
So, open excel from desktop icon, file> option,> advanced,> general and then make clear (unchecked) "the ignore applications that use dynamic data exchange (DDE)". (same information for NOTE 2: https://support.microsoft.com/en-us/kb/3001579) these are some error for excel worker with matlab and related command.

Gifs on Sailfish-os

I came here with a little problem, i can't use any local .gif in my code.
I work on Linux with QtCreator and the Sailfish VM to make a Sailfish-os application.
I tried first this example, without any success.
Rectangle {
width: animation.width
height: animation.height
AnimatedImage { id: animation; source: "../images/animatedimageitem.gif"}
}
The execution return :
QML AnimatedImage: Error Reading Animated Image File file:///bla/bla/.....
Same problem with other permissions on the gif and with an other gif.
After some researches I found this page where someone indicate to download a plugin, but Qt declare (I wish i could put a link but i'm new -_-', see comments) that gifs are already support by default.
The plugin was finally unobtainable and I found this Sailfish/bin/plugins/imageformats/libqgif.so in my directories.
So what can i do to show a gif on this damn thing ?
The error you are seeing is probably related to filepaths. Gifs are supported, AFAIK.
Instead of coding the path that way, consider the usage of a resource file to improve portability and platform independence.
Create a new resource file (File -> New File or project -> Qt -> Qt Resource File)
The property editor opens, click Add in the bottom then Add prefix and set a prefix such as / (or whatever you like!)
Click again to select Add files and insert your image
Right-click the newly added image entry and copy resource path to Clipboard
Build -> Run qmake (fundamental to ensure correct compilation)
The path you copied in the clipboard should be of the form:
://PATH_TO_IMAGE.gif
Now, given your QML code, I can guess the image folder is inside source code at the same level as the QML folder. Hence, if you added the .gif file from that folder you would have the following path in the clipboard:
://images/name.gif
This can be prepended with the prefix to obtain the final path. If your prefix is set to /, as we did above, the final string to be set in the source property of your AnimatedImage would be:
"qrc:///images/name.gif"
Obviously, a different prefix or a different path would result in a different final path.
Well..... I just put it on my phone (Jolla) and the gif works well. So this is the VM who doesn't seems to like gifs ...
Thanks for help though,
Psycho.

Reproducing the blocked exe "unblock" option in file properties in windows 2003

When I download my program from my website to my windows 2003 machine, it has a block on it and you have to right click on the exe, then properties, then select the button "Unblock".
I would like to add detection in my installer for when the file is blocked and hence doesn't have enough permissions.
But I can't eaisly reproduce getting my exe in this state where it needs to be unblocked.
How can I get the unblock to appear on my exe so I can test this functionality?
This is done using NTFS File Streams. There is a stream named "Zone.Identifier" added to downloaded files. When IE7 downloads certain types of file that stream contains:
[ZoneTransfer]
ZoneId=3
The simplest way to set it is to create a text file with those contents in it, and use more to add it to the alternate stream.
Zone.Identifier.txt:
[ZoneTransfer]
ZoneId=3
Command:
more Zone.Identifier.txt > file.exe:Zone.Identifier
Then, the way for you to check it would be to try to open the Zone.Identifier stream and look for ZoneId=3, or simply assume that if the stream exists at all that your user will receive that warning.
It's also important to note that this has nothing to do with permissions. Administrators see the same warning; it's to do entirely with the source and type of file. The entire stream goes away when users uncheck the "Always ask before opening this file" box and then click Run.
There is a supported API for this, documented on MSDN. Search on MSDN for "Persistent Zone Identifier Object". Basically you CoCreateInstance with CLSID_PersistentZoneIdentifier and request an IPersistFile interface. You then call IPersistFile::Load with the name of the file in question. Next, QI for an IZoneIdentifier interface and use IZoneIdentifier::GetId to obtain the zone of the file. If there was no "mark of the web", you should get URLZONE_LOCAL_MACHINE. The ZoneId of 3 mentioned in the other reply is URLZONE_INTERNET. (The enumeration is called URLZONE and is also documented on MSDN, or see sdk\inc\urlmon.h.) You can remove or change the "mark of the web" by calling IZoneIdentifier::Remove or IZoneIdentifier::SetId and then call IPersistFile::Save. There are more details about all of this on MSDN. Good luck!
Thanks for this it helped me a lot.
You can make the process even easier if you create a batch file with the contents.
echo [ZoneTransfer] > Zone.Identifier
echo ZoneId=3 >> Zone.Identifier
more Zone.Identifier > %1:Zone.Identifier
This will generate the Zone.Identifier for you and mark the file accordingly.
To run it just supply the file name e.g. if the file is called mark.bat
mark.bat myfile.txt

Resources