I am getting both the currently active window title and exe filepath with the code below
hwnd = win32gui.GetForegroundWindow()
_, pid = win32process.GetWindowThreadProcessId(hwnd)
if hwnd != 0 or pid != 0:
try:
hndl = win32api.OpenProcess(win32con.PROCESS_QUERY_INFORMATION | win32con.PROCESS_VM_READ, 0, pid)
self.newExe = win32process.GetModuleFileNameEx(hndl, 0)
self.newWindowTitle = win32gui.GetWindowText(hwnd)
except:
self.newExe = ''
self.newWindowTitle = ''
the issue is that although it often is, the window title is not always the application name (the name the users understand as the main part of an application) and this is what I need. for example from calc.exe get Calculator withiout relying on the window title.
the purpose is to create a script that will log in an xml comparative use of any software on a computer
Is this possible?
Most Windows applications store information such as this inside their resource tables. There are API calls that can be used to extract this.
The following extracts the file description from a given application:
import win32api
def getFileDescription(windows_exe):
try:
language, codepage = win32api.GetFileVersionInfo(windows_exe, '\\VarFileInfo\\Translation')[0]
stringFileInfo = u'\\StringFileInfo\\%04X%04X\\%s' % (language, codepage, "FileDescription")
description = win32api.GetFileVersionInfo(windows_exe, stringFileInfo)
except:
description = "unknown"
return description
print(getFileDescription(r"C:\Program Files\Internet Explorer\iexplore.exe"))
The output is:
Internet Explorer
You could therefore pass the result of your call to win32process.GetModuleFileNameEx() to this function.
Related
We have a python program that is designed to open an Excel template document, run refreshall() twice (data and pivots), then saveas() a new filename in an output directory.
When I log in to the server and run the program, everything works as required - both refreshall() steps update and the new file is saved with the updated data. This is the case not matter how the Visible flag is set (True or False).
When we set it as a step in an MS SQL job, the output file is created, but the updates are not done. I've been all over Stack Overflow and the internet in general, and have found no answers to solve this.
Using the combrowse.py script to look at the COM objects, we can see that excel is in the "Running Objects" list when run logged in, but it is NOT in the list when it is running via the MS SQL job (reduced to a single step in the job).
I looked at stdout to see if that might be an issue. My theory is that there is no console in which to operate when run via the job, and so Excel does not start (and the refreshall() cannot run). I found that the stdout when run locally is a UTF-8 encoding and when run via the job is a cp1252 encoding. I couldn't get anything more useful than that.
Code snippet:
from AE import logging, encrypt
import os, sys, shutil, datetime, gc
import time
import win32com.client
script_name = 'PerSta'
log_id = logging.Start_script(script_name)
try:
logging.Log_script_message(id = log_id, message = 'Opening excel')
ExcelConn = win32com.client.DispatchEx("Excel.Application")
logging.Log_script_message(id = log_id, message = 'ExcelConn is:')
logging.Log_script_message(id = log_id, message = repr(ExcelConn))
logging.Log_script_message(id = log_id, message = 'Opening {}'.format(script_name))
PS = ExcelConn.Workbooks.Open(datadict.get('path') + datadict.get('filename'))
ExcelConn.Interactive = False
ExcelConn.Visible = False
ExcelConn.DisplayAlerts = False
ExcelConn.EnableEvents = False
logging.Log_script_message(id = log_id, message = 'Refreshing excel first time')
PS.RefreshAll()
ExcelConn.CalculateUntilAsyncQueriesDone()
time.sleep(pause_for_refresh)
logging.Log_script_message(id = log_id, message = 'Refreshing excel second time')
PS.RefreshAll() #Refresh again to update any pivots
ExcelConn.CalculateUntilAsyncQueriesDone()
time.sleep(pause_for_refresh)
logging.Log_script_message(id = log_id, message = 'Saving workbook')
PS.SaveAs(Report)
time.sleep(pause_for_refresh)
logging.Log_script_message(id = log_id, message = 'Closing workbook')
PS.Close(SaveChanges = True)
time.sleep(pause_for_refresh)
PS = None
logging.Log_script_message(id = log_id, message = 'Closing filehandle')
ExcelConn.Quit()
ExcelConn = None
except:
logging.Log_script_message(id = log_id, message = 'Refreshed failed, closing filehandle')
PS.Close(SaveChanges = False)
PS = None
ExcelConn.Quit()
ExcelConn = None
I believe the issue lies in not having a screen for Excel to do its work, but I have not been able to prove that. We get NO ERRORS at all, either way it is run. I would expect that there would be an error in the job scenario, since it doesn't do what it says that it is, but that is not the case.
Any help would be much appreciated!!
--MIKE--
Edit: the Interactive, Visible, DisplayAlerts, and EnableEvents was put in as testing to see if we could use those to fix the issue. They did not work, no matter how they were set, but left them in in case they came up in discussion.
I am using Inspect.exe to identify the Windows control names that I wanted to reference in my UI automation script using pywinauto/Python. When I rename a control (eg. sheet/page name) of a Windows App I am automating, that control name will register as "" Name, not with the new name it is assigned with, even after I restart the said app.
Is there a way to refresh the app (may it be in Python or other way) so the new name will register/refresh as well in Inspect.exe without rebooting the OS (in my case, the new name correctly appeared on Inspect.exe only after I rebooted my PC).
UPDATED 03/10/2020 --------------------------------------------------
Below is the snippet of my automation script using pywinauto:
def change_view(display_time_A, display_time_B, numPages):
SHEET_NAME_PREFIX = "Page"
while True:
# Connect pywinauto
print("Looking for Power BI Window")
app = Application(backend='uia', allow_magic_lookup=False).connect(path="PBIDesktop.exe")
win = app.window(title_re='.*Power BI Desktop')
time.sleep(5)
win.wait("enabled", timeout=300)
win.set_focus()
# Check if Page0 exists and show it within the specified display time A
sheetName = SHEET_NAME_PREFIX + "0"
try:
win[sheetName].click_input()
time.sleep(display_time_A * 60)
except (ElementAmbiguousError, MatchError, RuntimeError):
print(sheetName + " was NOT FOUND.")
# Check if Page 1 to N exist and show them within the specified display time B
for sheetNum in range(1, numPages):
sheetName = SHEET_NAME_PREFIX + str(sheetNum)
print("Checking if " + sheetName + " exists...")
try:
win[sheetName].click_input()
time.sleep(display_time_B * 60)
except (ElementAmbiguousError, MatchError, RuntimeError):
print(sheetName + " was NOT FOUND.")
Any suggestion would be highly appreciated. Thank you!
Can someone tell me how I can get all the selected files on Windowsd desktop in Python? I've been searching for a way to do it and I can't find anyone. The only one I found is for C#, but I don't code in C#, so I don't even know if it works: Get list of selected files from Windows Desktop (if someone understands it and could explain/convert it, that'd be appreciated too). I've found something very near of this, but I can only make it get the number of seleted files, not their path, as I'd like:
import ctypes
from commctrl import LVM_GETITEMCOUNT,LVM_GETSELECTEDCOUNT
#The LVM_GETITEMCOUNT came with the script, I got the other one from Microsoft documentation about SendMessage(), and both are near, but none returns the paths, only numbers
import pywintypes
import win32gui
GetShellWindow = ctypes.windll.user32.GetShellWindow
def get_desktop():
"""Get the window of the icons, the desktop window contains this window"""
shell_window = GetShellWindow()
shell_dll_defview = win32gui.FindWindowEx(shell_window, 0, "SHELLDLL_DefView", "")
if shell_dll_defview == 0:
sys_listview_container = []
try:
win32gui.EnumWindows(_callback, sys_listview_container)
except pywintypes.error as e:
if e.winerror != 0:
raise
sys_listview = sys_listview_container[0]
else:
sys_listview = win32gui.FindWindowEx(shell_dll_defview, 0, "SysListView32", "FolderView")
return sys_listview
def _callback(hwnd, extra):
class_name = win32gui.GetClassName(hwnd)
if class_name == "WorkerW":
child = win32gui.FindWindowEx(hwnd, 0, "SHELLDLL_DefView", "")
if child != 0:
sys_listview = win32gui.FindWindowEx(child, 0, "SysListView32", "FolderView")
extra.append(sys_listview)
return False
return True
def get_item_count(window):
return win32gui.SendMessage(window, LVM_GETSELECTEDCOUNT)
desktop = get_desktop()
print(get_item_count(desktop))
I've searched on the commands that can be sent to a window, but I didn't find anyone to get the path of the selected items (maybe I missed one?).
A way I found of getting the selected files from Windows Explorer windows, but now from the desktop: https://stackoverflow.com/a/21250927/8228163.
Any help (with any Windows, preferably 7) is much appreciated. Thanks in advance!
So I'm creating a basic TUI for a script I created. The goal is to collect several variables that include paths to directories and files. What I'm not sure about is once I've created the visual aspect of it, how to get those pieces of information to interact with other parts of the code.
Below is what I have so far in terms of the visual portion (the other part is about 500 lines), and honestly I'm at a loss on how to even print any of the variables set under the class and any pointers would be greatly appreciated.
#!/usr/bin/env python
# encoding: utf-8
import npyscreen
class PlistCreator(npyscreen.NPSApp):
def main(self):
screen = npyscreen.Form(name="Welcome to Nicks Playlist Creator!")
plistName = screen.add(npyscreen.TitleText, name="Playlist Name:" )
csvPath = screen.add(npyscreen.TitleFilenameCombo, name="CSV Schedule:")
toaPath = screen.add(npyscreen.TitleFilenameCombo, name="Path to ToA Video Folder:", use_two_lines=True)
outputPath = screen.add(npyscreen.TitleFilenameCombo, name = "Output Folder:", use_two_lines=True)
dateOfAir = screen.add(npyscreen.TitleDateCombo, name="Date of Air:")
timeOfStart = screen.add(npyscreen.TitleText, name="Time of Air (TC):")
screen.edit()
if __name__ == "__main__":
App = PlistCreator()
App.run()
You can get the value of any form object using the dit notation.
plistName = screen.add(npyscreen.TitleText, name="Playlist Name:" )
playlist_name = self.screen.plistName.value
etc. Note there are no parentheses after value. Once you have it in a variable, you can build another method in the class to handle the information.
First off, I am brand new to programming, python, and this forum so sorry for any mistakes.
I wrote a python script but want to be able to run it on a computer without python installed, so I did some research and found I would need to download a program in order to convert py to exe. cx_freeze was the only one that supported python 3.4.
I followed the instructions in a popular YouTube video (https://www.youtube.com/watch?v=XHcDHSWRCRQ) but when I double click the exe, the command box pops open for a split second and then closes. There is some text but it goes too quickly for me to read it.
It looks like these threads are about the same problem but they went unanswered. Any ideas?
Command prompt disappears with cx_freeze
cx_Freeze exe file opens for a second then closes
Thanks!
Edit: If it helps, here is my setup.py
from cx_Freeze import setup, Executable
setup(
name = "Teacher Pages Search" ,
version = "1" ,
description = "By Gambiteer" , executables = [Executable("Teacher Pages Search.py")] ,
)
Here is Teacher Pages Search.py
import urllib.request
import html.parser
import webbrowser
class MyHTMLParser(html.parser.HTMLParser):
def __init__(self):
super().__init__(False)
self.teacherLink = False
self.url = ""
def handle_starttag(self, tag, attrs):
if tag == 'a':
for combo in attrs:
if "sw-directory-item" in combo[1]:
self.teacherLink = True
if self.teacherLink is True:
if "http:" in combo[1]:
self.url = combo[1]
def handle_data(self, data):
data = data.lower()
data = data.replace("'","")
data = data.replace("\\","")
data = data.replace(" ","")
if self.teacherLink is True:
for teacher in teacherList:
if teacher in data:
webbrowser.open(self.url)
self.teacherLink = False
teacherListInput = input("Enter the last name of your teachers, without punctuation, separated by commas:\n")
teacherListInput = teacherListInput.replace(" ","")
teacherList = list()
while teacherListInput.find(',') != -1:
commaLoc = teacherListInput.find(',')
teacherName = teacherListInput[0:commaLoc]
teacherList.append(teacherName)
teacherListInput = teacherListInput[commaLoc+1:]
teacherList.append(teacherListInput)
f = urllib.request.urlopen("http://www.scarsdaleschools.k12.ny.us/site/Default.aspx?PageType=1&SiteID=65&ChannelID=94&DirectoryType=6")
webpage = f.read()
parser = MyHTMLParser()
html_parser = html.parser.HTMLParser()
unescaped = html_parser.unescape(str(webpage))
parser.feed(unescaped)
input("Press enter to exit")