How call a Windows program (.exe file) from Python 3 - python

I know this may seem a common question, yes, there are many questions similar to mine and yes, apparently there are solutions but the problem is that I tried them but they do not work.
This is my code:
def testOne():
output = subprocess.run(["htpasswd.exe", "-nb", "spock", "volerevolare"], capture_output=True)
print( output )
print("out: <{o}>".format(o=output.stdout.decode()))
print( "return code: dec {d:d} hex {h:X}".format(d=output.returncode, h=output.returncode) )
#---------------------------------------------------------------------------
and this is its output:
CompletedProcess(args=['htpasswd.exe', '-nb', 'spock', 'volerevolare'], returncode=3221225781, stdout=b'', stderr=b'')
out: <>
return code: dec 3221225781 hex C0000135
so in my opinion after looking at the error code I think that my little applications does not work and htpasswd.exe is not executed.
O.S. is Win 7, normal user (not admin user).
What I missed?
Thanks,
Massimo

OK, problem found, I have also cygwin installed so it was a problem related to PATH. Copying locally the right htpasswd.exe (Windows 10 version) solved the problem. The htpasswd windows version is already installed in Win 10, for previous release I verified it works since Win 7 it is downloadable here: https://www.exefiles.com/it/exe/htpasswd-exe/

Related

Commenting print() breaks the Python code

I was faced with a very strange problem.
With print() this code works.
def max_pairwise_product(numbers):
max_1 = max(numbers)
numbers.remove(max_1)
max_2 = max(numbers)
return max_1 * max_2
if __name__ == '__main__':
input_n = int(input())
print() # <- comment of this line breaks the code
input_numbers = [int(x) for x in input().split()]
print(max_pairwise_product(input_numbers))
If I comment or delete the 10-th line with print() I got an error:
Traceback (most recent call last):
File "C:\Users\...\maximum_pairwise_product_fast.py", line 12, in <module>
print(max_pairwise_product(input_numbers))
File "C:\Users\...\maximum_pairwise_product_fast.py", line 2, in max_pairwise_product
max_1 = max(numbers)
ValueError: max() arg is an empty sequence*
Process finished with exit code 1
I use Python 3.9. PyCharm.
I tried to launch with different virtual environments with Python 3.8 and 3.10 – the same error.
When I launch in Jupyter and Colab – it is fane – no error.
There are no issues with any other Python script. I used the installation for several months and there was nothing strange.
It is so strange that I have no idea. Could you please help me?
Try checking if your python interpreter is working correctly and is the latest python
It might fix it or there's probably a problem with your ide.
Thank you all for helping to refer me in the right direction.
The reason for the error was a bug in PyCharm. It sent not was typed. The issue disappeared after the PyCharm update from version 2022.1.1 to 2022.1.2.
Back in 2018 or so, I found a similar strange issue in a Python program I downloaded that solved Rubik's cubes. Basically, the program ran just fine under Linux, but under Windows it was erroring out at a certain line that looked fine.
I ran "pyflakes" on that program, but pyflakes reported that nothing was wrong. Odd.
The line that supposedly contained the error was a list comprehension, much like your line here:
input_numbers = [int(x) for x in input().split()]
I replaced the list comprehension with a normal for-loop, and then the code ran fine with no errors. Basically, if I were to rewrite your line, I would replace it with the following four lines:
input_numbers = []
for x in input().split():
input_numbers.append(int(x))
assert input_numbers, "input_numbers is empty!"
I have no idea why the error was happening in the first place, and only on Windows. (The version of Python3 I was using certainly supported list comprehensions; I checked.) But once I replaced the list comprehensions with a for-loop, the code worked.
So my advice is to replace your list-comprehension with a for-loop and see if that solves anything.
I don't know if that will work, but it's worth a shot, as it seems that your input_numbers list is not actually being populated before it's passed to max_pairwise_product().
You might even try putting the assert statement:
assert input_numbers, "input_numbers is empty!"
after the list comprehension to verify that input_numbers is truly being populated. If it's not, then you at least have narrowed down your problem, and will now have to figure out why it's not being populated.
P.S. I'm curious: Which operating system(s) does the error happen on?
P.P.S. I recommend adding input text to your input() calls (such as input("Type some space-separated numbers: "), even if just for posting here. Otherwise, when stackoverflow users run your code, it looks like your code is hanging.

UNC Path With Python Subprocess_checkCall

I have a python program which in turn calls an R script for doing some calculations. This worked great till I switched over to UNC. I am on Windows and I tried all that has been suggested on StackOverflow but I still keep getting an error saying "base package can't be opened"
I have tried with backward slashes meaning on the lines of \\server/abc/a.exe etc as well as \\server\abc\a.exe
What am I missing? It seems the problem is that the executable can't have a UNC path , in this case the variable rscriptpath. I really need that to be a UNC as the caller program would not in the same server. Thanks in advance.
import subprocess
Date='2018-03-01'
env='PROD'
main_dir=r'\\sandbox0968\QRMPortfolioRisk\QRMPortfolioRisk'
rscriptpath = r'\\sandbox0968\bin\Rscript.exe'
dailymain = r'\\sandbox0968\QRMPortfolioRisk\QRMPortfolioRisk\src\daily\DailyMain_cmd.R'
dailymainstatic = r'\\sandbox0968\QRMPortfolioRisk\QRMPortfolioRisk\src\daily\DailyMainStatic.R'
cxo_script = r'\\sandbox0968\QRMPortfolioRisk\QRMPortfolioRisk\src\daily\CXOdump.R'
calc_dir = r'\\sandbox0968\QRMPortfolioRisk\QRMPortfolioRisk\data\calculations'
reestimate = r'\\sandbox0968\QRMPortfolioRisk\QRMPortfolioRisk\src\estimation\EstimationMain_cmd.R'
#
subprocess.check_call([rscriptpath, '--vanilla', dailymain, str(Date), str(main_dir), env])

Pythondialog: Unable to retrieve the version of the dialog-like backend

Minimal code example, run on OSX and Python 3:
#! /usr/bin/env python3
from dialog import Dialog
d = Dialog(dialog="dialog")
sel = d.menu("Test",
choices=[ ("FooTag", "Foo", False, "FooHelp"),
("BarTag", "Bar", True, "BarHelp")]
)
I get the error message:
Traceback (most recent call last):
File "./test.py", line 5, in <module>
d = Dialog(dialog="dialog")
File "/usr/local/lib/python3.3/site-packages/dialog.py", line 1371, in __init__
self.backend_version())
File "/usr/local/lib/python3.3/site-packages/dialog.py", line 2012, in backend_version
"{1!r}".format(self._dialog_prg, output))
dialog.UnableToRetrieveBackendVersion: Unable to retrieve the version of the dialog-like backend: unable to parse the output of '/usr/local/bin/dialog --print-version': ''
However, dialog reports correctly:
> dialog --print-version
Version: 1.1-20100428
>
Nothing changes, if I use the absolut path /usr/local/bin/dialog. I guess, it is an install problem, but I've no clue.
As you have found yourself, the problem is caused by the fact that your dialog program prints its version on stdout whereas more recent versions print it on stderr. So, the string pythondialog tries to parse as a version number is empty in such a case.
pythondialog 3.2.2rc1 (latest release at the time of this writing) detects this situation and automatically reruns dialog --stdout --print-version, making sure this time to read from dialog's stdout stream. Since this is only done once at Dialog instance creation (the backend version being cached), the impact of this workaround is minimal.
It is better than your solution (passing use_stdout=True to the Dialog constructor), because it allows the rest of pythondialog to use dialog's stderr stream normally: the use of --stdout is only limited to retrieving the version of dialog. On the contrary, the solution you found will pass --stdout to all dialog calls which, according to the dialog(1) manual page, may fail "depending on the platform and your environment".
Had you reported this problem on the pythondialog issue tracker or mailing list, the workaround I mentioned here would certainly have been implemented earlier...
Your example with little fixes for on my computer (i changed False to 'False'). Your issue is that version is not matched against regex. This is code from pythondialog:
mo = self._print_version_cre.match(output)
if mo:
return mo.group("version")
else:
raise UnableToRetrieveBackendVersion(
"unable to parse the output of '{0} --print-version': "
"{1!r}".format(self._dialog_prg, output))
#this is located upper
_print_version_cre = re.compile(r"^Version:[ \t]+(?P<version>.+?)[ \t]*$", re.MULTILINE)
I've tested your version with this regexp and it matched on my computer, but I guess you have other version of pythondialog. So check _print_version_cre in your dialog.py and try to much with dialog version.
I found the solution myself:
dialog in OSX reports to stdout, not stderr.
By using
d = Dialog(dialog="dialog", use_stdout=True)
I get the expected result.

PyQt4 Highlighting

I'm trying to add some syntax highlighting to a text editor in PyQt4. I've found an example in the documentation which works find when compiled from C++ but when i convert it to Python/PyQt it no longer works.
The part of the code that fails (no longer highlights anything) is:
def highlightCurrentLine(self):
extraSelections = []
if not self.isReadOnly():
selection = QTextEdit.ExtraSelection()
lineColor = QColor(Qt.yellow).lighter(160)
selection.format.setBackground(lineColor)
selection.format.setProperty(QTextFormat.FullWidthSelection, QVariant(True))
selection.cursor = self.textCursor()
selection.cursor.clearSelection()
extraSelections.append(selection)
self.setExtraSelections(extraSelections)
which is called by:
self.connect(self, SIGNAL('cursorPositionChanged()'), self.highlightCurrentLine)
Anyone have any idea why this doesn't work?
The versions i am usuing are: Python 2.6.2, PyQt 4.4.4
Ok... turns out i wasn't going mad, i was just using an out of date version of PyQt4.
For information the version of PyQt4 that ships with Ubuntu 9.04 is 4.4.4 but this functionality seems to require 4.5+.
I've upgraded to PyQt4 4.6 and it works fine (plus 4.6 seems to have some nice new functionality too).
Save lineColor somewhere (like self.lineColor). Otherwise, Python will discard the object when the method returns and the format will use an illegal pointer.

Detect 64bit OS (windows) in Python

Does anyone know how I would go about detected what bit version Windows is under Python. I need to know this as a way of using the right folder for Program Files.
Many thanks
I think the best solution to the problem has been posted by Mark Ribau.
The best answer to the question for Python 2.7 and newer is:
def is_os_64bit():
return platform.machine().endswith('64')
On windows the cross-platform-function platform.machine() internally uses the environmental variables used in Matthew Scoutens answer.
I found the following values:
WinXP-32: x86
Vista-32: x86
Win7-64: AMD64
Debian-32: i686
Debian-64: x86_64
For Python 2.6 and older:
def is_windows_64bit():
if 'PROCESSOR_ARCHITEW6432' in os.environ:
return True
return os.environ['PROCESSOR_ARCHITECTURE'].endswith('64')
To find the Python interpreter bit version I use:
def is_python_64bit():
return (struct.calcsize("P") == 8)
I guess you should look in os.environ['PROGRAMFILES'] for the program files folder.
platform module -- Access to underlying platform’s identifying data
>>> import platform
>>> platform.architecture()
('32bit', 'WindowsPE')
On 64-bit Windows, 32-bit Python returns:
('32bit', 'WindowsPE')
And that means that this answer, even though it has been accepted, is incorrect. Please see some of the answers below for options that may work for different situations.
Came here searching for properly detecting if running on 64bit windows, compiling all the above into something more concise.
Below you will find a function to test if running on 64bit windows, a function to get the 32bit Program Files folder, and a function to get the 64bit Program Files folder; all regardless of running 32bit or 64bit python. When running 32bit python, most things report as if 32bit when running on 64bit, even os.environ['PROGRAMFILES'].
import os
def Is64Windows():
return 'PROGRAMFILES(X86)' in os.environ
def GetProgramFiles32():
if Is64Windows():
return os.environ['PROGRAMFILES(X86)']
else:
return os.environ['PROGRAMFILES']
def GetProgramFiles64():
if Is64Windows():
return os.environ['PROGRAMW6432']
else:
return None
Note: Yes, this is a bit hackish. All other methods that "should just work", do not work when running 32bit Python on 64bit Windows (at least for the various 2.x and 3.x versions I have tried).
Edits:
2011-09-07 - Added a note about why only this hackish method works properly.
def os_platform():
true_platform = os.environ['PROCESSOR_ARCHITECTURE']
try:
true_platform = os.environ["PROCESSOR_ARCHITEW6432"]
except KeyError:
pass
#true_platform not assigned to if this does not exist
return true_platform
http://blogs.msdn.com/b/david.wang/archive/2006/03/26/howto-detect-process-bitness.aspx
Many of these proposed solutions, such as platform.architecture(), fail because their results depend on whether you are running 32-bit or 64-bit Python.
The only reliable method I have found is to check for the existence of os.environ['PROGRAMFILES(X86)'], which is unfortunately hackish.
You should be using environment variables to access this. The program files directory is stored in the environment variable PROGRAMFILES on x86 Windows, the 32-bit program files is directory is stored in the PROGRAMFILES(X86) environment variable, these can be accessed by using os.environ('PROGRAMFILES').
Use sys.getwindowsversion() or the existence of PROGRAMFILES(X86) (if 'PROGRAMFILES(X86)' in os.environ) to determine what version of Windows you are using.
Following this documentation, try this code:
is_64bits = sys.maxsize > 2**32
Im aware that in comments of the question this method was already used.
This is the method the .net framework uses:
import ctypes
def is64_bit_os():
""" Returns wethever system is a 64bit operating system"""
is64bit = ctypes.c_bool()
handle = ctypes.windll.kernel32.GetCurrentProcess() # should be -1, because the current process is currently defined as (HANDLE) -1
success = ctypes.windll.kernel32.IsWow64Process(handle, ctypes.byref(is64bit)) #should return 1
return (success and is64bit).value
print(is64_bit_os())
I just found another way to do this, which may be useful in some situations.
import subprocess
import os
def os_arch():
os_arch = '32-bit'
if os.name == 'nt':
output = subprocess.check_output(['wmic', 'os', 'get', 'OSArchitecture'])
os_arch = output.split()[1]
else:
output = subprocess.check_output(['uname', '-m'])
if 'x86_64' in output:
os_arch = '64-bit'
else:
os_arch = '32-bit'
return os_arch
print 'os_arch=%s' % os_arch()
I tested this code in the following environments:
Ubuntu 16.04 + Python 2.7.12
Mac OS Sierra + Python 2.7.11
Windows 7 Pro 32-bit + Python 2.7.5 (32-bit)
Windows 10 Home 64-bit + Python 2.7.13 (32-bit)
The subject lines asks about detecting 64 or 32bit OS, while the body talks about determining the location of ProgramFiles. The latter has a couple of workable answers here. I'd like to add another solution generalized to handle StartMenu, Desktop, etc. as well as ProgramFiles: How to get path of Start Menu's Programs directory?
When you need to find out things about windows system, it is usually somewhere in the registry, according to MS documentation, you should look at (http://support.microsoft.com/kb/556009) this key value:
HKLM\HARDWARE\DESCRIPTION\System\CentralProcessor\0
and if it is:
0x00000020 (32 in decimal)
It is a 32 bit machine.
64-bit versions of Windows use something called registry redirection and reflection keys. There is a compatibility layer called WoW64 which enables compatibility of 32-bit applications. Starting from Windows 7 and Windows Server 2008 R2 WoW64 registry keys are not longer reflected but shared. You can read about it here:
registry-reflection: msdn.microsoft.com/en-us/library/aa384235(v=vs.85).aspx
affected-keys: msdn.microsoft.com/en-us/library/aa384253(v=vs.85).aspx
wikipedia: en.wikipedia.org/wiki/WoW64
All you need to do is detect existence of those keys. You can use _winreg for that. Use try: and try opening key, example:
try:
aReg = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Run")
import _winreg
def get_registry_value(key, subkey, value):
key = getattr(_winreg, key)
handle = _winreg.OpenKey(key, subkey )
(value, type) = _winreg.QueryValueEx(handle, value)
return value
windowsbit=cputype = get_registry_value(
"HKEY_LOCAL_MACHINE",
"SYSTEM\\CurrentControlSet\Control\\Session Manager\\Environment",
"PROCESSOR_ARCHITECTURE")
print windowsbit
just run this code
if you are working on 64 bit windows machine this will print AMD64
or if you are working on 32 bit it will print AMD32
i hope this code can help to solve this problem fully
This works for me in the Python versions I use: 2.7 and 2.5.4
import win32com.client
import _winreg
shell = win32com.client.Dispatch('WScript.Shell')
proc_arch = shell.ExpandEnvironmentStrings(r'%PROCESSOR_ARCHITECTURE%').lower()
if proc_arch == 'x86':
print "32 bit"
elif proc_arch == 'amd64':
print "64 bit"
else:
raise Exception("Unhandled arch: %s" % proc_arch)
Just to update this old thread - it looks like the platform module reports the correct architecture now (at least, in Python 2.7.8):
c:\python27\python.exe -c "import platform; print platform.architecture(), platform.python_version()"
('32bit', 'WindowsPE') 2.7.6
c:\home\python278-x64\python.exe -c "import platform; print platform.architecture(), platform.python_version()"
('64bit', 'WindowsPE') 2.7.8
(sorry I don't have the rep to comment on the first answer which still claims to be wrong :)
import platform
platform.architecture()[0]
It will return '32bit' or '64bit' depending on system architecture.
The solution posted by Alexander Brüsch is the correct solution, but it has a bug that only reveals itself on python3.x. He neglected to cast the returned value from GetCurrentProcess() to a HANDLE type. Passing a simple integer as the first parameter of IsWow64Process() returns 0 (which is an error flag from win32api). Also, Alexander incorrectly handles the return statement (success has no .value attribute).
For those who stumble on this thread, here is the corrected code:
import ctypes
def is64_bit_os():
"""Returns True if running 32-bit code on 64-bit operating system"""
is64bit = ctypes.c_bool()
handle = ctypes.wintypes.HANDLE(ctypes.windll.kernel32.GetCurrentProcess())
success = ctypes.windll.kernel32.IsWow64Process(handle, ctypes.byref(is64bit))
return success and is64bit.value
print(is64_bit_os())
There is a function named machine in platform module. I installed both Python3.8 32-bit and 64-bit versions on the same 64-bit machine with 64-bit Windows 10 and here is what I found:
And it looks like platform.machine returns machine architecture without bothering what type of python is installed. so here is my
final compilation
import platform
def is_64bit():
return platform.machine().endswith('64')
Most of the answers here are incorrect :/
Here is a simple translation of the well known method used in CMD and this is how microsoft do it too.
import os
_os_bit=64
if os.environ.get('PROCESSOR_ARCHITECTURE').lower() == 'x86' and os.environ.get('PROCESSOR_ARCHITEW6432') is None: _os_bit=32
print(_os_bit)
but remember: Windows 10 on ARM includes an x86-on-ARM64 emulation, so the possible values for PROCESSOR_ARCHITECTURE are: AMD64 or IA64 or ARM64 or x86
A solution, putting together the options from the links below and using os module:
import os
#next save the response from the command prompt saved to a file
window = os.system('PowerShell.exe "gwmi win32_operatingsystem | select osarchitecture" > prompt.txt')
#next read the file
f = open('prompt.txt','r')
windowsos = f.readlines()
f.close()
print(windowsos[3][:-1])
https://datatofish.com/command-prompt-python/
https://www.radishlogic.com/windows/how-to-check-if-your-windows-10-is-64-bit-or-32-bit/
https://www.tutorialspoint.com/how-to-run-a-powershell-script-from-the-command-prompt
import struct
def is64Windows():
return struct.calcsize('P') * 8 == 64
There should be a directory under Windows 64bit, a Folder called \Windows\WinSxS64 for 64 bit, under Windows 32bit, it's WinSxS.

Categories