Invoking 64-bit console from 32-bit python - python

I'm attempting to write a script that will gather the output of a few basic windows commands into a set of files, and am finding my vssadmin commands frustrating. The command is a relatively simple
os.system('vssadmin list writers>> x:\foo\vss.txt')
The problem is that I'm writing in python 32-bit and want to make sure this will function on 64-bit Windows. When executing this, the return is:
vssadmin 1.1 - Volume Shadow Copy Service administrative command-line
tool (C) Copyright 2001-2005 Microsoft Corp.
Error: A Volume Shadow Copy Service component encountered an
unexpected error. Check the Application event log for more
information.
Can I invoke a 64-bit command line from 32-bit python and decide whether to invoke it with a bit-depth detecting function, or is there another more elegant solution?
Follow-up: using MBu as a jumping off point I found that the following command does the trick:
os.system('%systemroot%\\sysnative\\cmd.exe /c vssadmin list writers > x:\\foo\\vss.txt')

Under Windows 2008 or newer you can launch c:\Windows\Sysnative\vssadmin.exe. Under Windows 2003 a hotfix is needed, but you can also create a filesystem junction to reach the 64-bit system file from 32-bit applications. For details see my answer to this question. While it was about launching 64-bit cmd.exe from 32-bit cmd.exe, the rules stay the same for all applications.

Launch C:\Windows\SysWOW64\vssadmin.exe explicitly to always get the 64-bit version.

Related

executing java command from script gives error even though same command from cli works fine

I'm writing a python script that amongst other things launches a jar file.
I'm using the following method to fire the java command:
def first_launch(self):
if self.is_initialize:
subprocess.run(
[f"-Xmx{self.max_memory}M", f"-Xms{self.min_memory}M", f"-jar server.jar", "nogui"],
executable="/usr/bin/java",
cwd=self.directory
)
else:
raise Exception("Server is not initialized")
Where the var values are:
directory: /Users/cschmitz/Desktop/opt/minecraft/server
max memory: 2048
min memory: 1024
which should all come out to be the command:
/usr/bin/java -Xmx2048M -Xms1024M -jar server.jar nogui
When I run this command from my terminal it works fine:
But when I try firing it from the python subprocess I get the error:
The operation couldn’t be completed. Unable to locate a Java Runtime that supports -Xmx2048M.
Please visit http://www.java.com for information on installing Java.
I'm using an absolute path to my java executable (the same one I'm using on in the CLI) so it seems unlikely that I'd be grabbing a different version of the command (like if my cli path included a different version of the command than what my python file had access to).
I searched around for answers online and I saw where you'd see this message if you only had the java runtime and not the dev kit, but as far as I can tell I have the jdk installed (or at least I figured that if I installed open jdk I wouldn't get just the runtime environment).
❯ java -version
openjdk version "19.0.1" 2022-10-18
OpenJDK Runtime Environment Homebrew (build 19.0.1)
OpenJDK 64-Bit Server VM Homebrew (build 19.0.1, mixed mode, sharing)
And really the fact that I can launch it just fine from the cli suggests that I have the right tools installed.
Any ideas of what I'm doing wrong or misunderstanding??
/usr/bin/java should be the first argument, not (or at least, not just) the executable.
You only need to set executable when you need to pass a program a argv[0] that differs from the executable name; there's no reason for them to be different here. The immediate error you get appears to be the JVM treating the basename of (which is to say, everything past the last / in) argv[0] as the name of an operational mode it's supposed to run in; the normal operating mode is java, but there's no mode named -Xmx2048m.
Software deciding what mode to run in based on its argv[0] is fairly common: For example, if you call executable='/bin/bash' with an argv[0] of sh, bash runs in POSIX sh compatibility mode, turning off several non-POSIX features.
As an additional issue, -jar and server.jar should be two separate arguments: -jar is specified as an argument that specifies that the next argument is the jar to run.
Thus, correct code would look more like:
subprocess.run(
['/usr/bin/java',
f'-Xmx{self.max_memory}M',
f'-Xms{self.min_memory}M',
'-jar', 'server.jar',
'nogui'],
cwd=self.directory
)

Runaway Jedi Language task in VSCode

Every time I close VSCode (after running some Python script) I have a Python task that lingers in my terminal running 90-100% CPU on my M1 MacBook Air, and I have to manually kill it every time. I ran the following on the PID:
ps aux | grep <PID>
and it returns the same thing every time...
Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/Resources/Python.app/Contents/MacOS/Python /Users/<user>/.vscode/extensions/ms-python.python-2021.2.625869727/pythonFiles/runJediLanguageServer.py
I checked my VSCode extensions, and I don't have any "Jedi" ones installed, but maybe it's a lingering task from some other extension.
Any ideas how to fix this?
The solution as provided in the link Valy provided above is to:
Open the command palette (View > Command Palette...)
Run the "Preferences: Open Settings (JSON)" command. This will open the user settings in VS code
Paste the following line in the settings file:
"python.experiments.optOutFrom": ["pythonJediLSP"]
Reload the window (either by closing VS Code and opening it again or running the "Developer: Reload Window" command from the command palette)
reference: Rogue Python Processes with High CPU Consumption issue #15586
I had the same issue as apparently VSC is experimenting with a new feature. Another user helped me find the solution, which can be found here: https://github.com/microsoft/vscode-python/issues/15586#issuecomment-792360066
When using python in VS Code, it requires us to install the "python" extension, and it will automatically load the corresponding language service to better identify and analyze the code.
"Visual Studio Code provides smart editing features for different programming languages through Language Extensions. VS Code doesn't provide built-in language support but offers a set of APIs that enable rich language features."
We can use different python language services: Jedi, Microsoft, Pylance, and so on, and VS Code uses Jedi by default:
Reference:Language Server Extension Guide and Language Extensions Overview.

Python shutil.which not working with wsl.exe

I am trying to use shutil.which to check if the Linux Subsystem is installed on Windows 10.
Using the Windows where command in Command Prompt, I can see the location of the wsl.exe executable.
C:\Users\spike>where wsl
C:\Windows\System32\wsl.exe
The above shows that WSL does exist, and is in my system PATH.
When I use the which function in Python, it says that the executable was not found.
print(which("wsl")) # Returns None
Just to make sure that which works, I test it on cmd.exe.
print(which("cmd")) # Returns "C:\Windows\System32\cmd.exe"
That works. Well, what if I make a system shell call with the command that did work?
print(system("where wsl")) # Returns 1
Exit code 1, the command wsl was not found.
So I test it on cmd.exe again.
print(system("where cmd")) # Returns 0
Okay, so that does work. What is the problem?
For each Python 3 example assume these imports.
from shutil import which
from os import system
Why can Python not find wsl.exe even though it is proven to exist?
Thanks.
Credit to #eryksun, who helped solve this in the comments.
The issue is that I am using 32 bit Python, and wsl.exe is only in C:/Windows/System32. The problem with this is that Python is looking in C:/Windows/SysWOW64 for the executable instead.
wsl.exe is only 64-bit, and you're looking in SysWOW64 instead of the real System32 because you're using 32-bit Python. – eryksun
Because WSL only supports 64-bit systems, I ended up just running my code with 64-bit Python. However, and alternate solution if you only use Py32 would be to access SysWOW64 directly, using the system root environment variable and os.path.join.
In Windows 7+, the real System32 directory is accessible in a 32-bit process as "SysNative". Unfortunately this virtual directory isn't available in a native 64-bit process, so you need to first check whether it exists. For example: sysnative = os.path.join(os.environ['SystemRoot'], 'SysNative'); if os.path.exists(sysnative): .... – eryksun
Now you can install python in 64 bit and everything will work just fine. (Be careful that when the python installer runs, there should be written 64 bit packages and other things as 64 bits [right where the loading bar is])

Running C Program on Windows 8.1 using Python (or not Python)

The original goal was to write a software executable on Windows platform that could read numbers from 7-segment displays and record it at a constant time interval. I tried out a couple of OCR libraries in Python (since I was planning to write the program in Python) but learned that they are more suitable for handwritten letters and soon redirected my attention to another open source program written in C, specifically designed for reading numbers from 7-segment displays: http://www.unix-ag.uni-kl.de/~auerswal/ssocr/
So I compiled the source code in Linux and planned to move the compiled file, along with its linked library files, to the Windows machine, naively believing that I could simply "exec" from a Python script to execute the program. It turns out it couldn't - just trying to run the program (after manually adding an .exe extension at the end and double clicking) generates a response "the app cannot run on this pc. to find a version for this computer, check with the software publisher".
So my question is, whether there is a way to simply execute the C program from a script on Windows platform, and if not, what you might suggest me do to complete the aforementioned task?
You can execute any program using Python (like other programming languages). But what happens (for all languages) is that they do a system call and ask the underlying operating system to execute the program, because that is one of the responsibilities of the OS.
Open a Python REPL (or write a Python script) and try this (This is only one of the ways to execute a program from python)
import subprocess
# if you're on windows call this
subprocess.call("notepad", shell=True)
# If on Linux call this
subprocess.call("ls", shell=True)
What happens is that Python asks OS to execute the specified program (notepad or ls), weather OS can run the requested application is another story.
Your C program is compiled on Linux so it is an executable in a format that Linux can run (probably ELF format). Windows requires executable files to be in a different file format. File extensions just help the environment to treat files appropriately. If you change the extension of your Linux executable to '.exe', it does not change its content, so Windows still would not be able to run it.
You need to recompile your C program on Windows so the compiled program is executable on Windows. If the program requires a POSIX environment (for example if it uses fork() syscalls or etc.), then you could use Cygwin on Windows (that provides system calls and libraries available in Linux for Windows) to compile it.

Cross-platform way to specify Python interpreter when running with execv

I am currently running a Python scripts both on Linux and Windows 7. The file is executed in an execv style with which I mean that the interpreter is defined in the beginning of the file in a command.
In Windows system, the interpreter specification is:
#!C:\Python26\python.exe
However in Linux this needs to be
#!/usr/bin/python
I would like to run this script in both systems without having to change this line again and again.
I have tried out the following:
#!C:\Python26\python.exe
#!/usr/bin/python
as well as:
#!C:\Python26\python.exe;/usr/bin/python
So: is there any way I could specify multiple interpreters?
Depending on what you're trying to do, this might be a bit heavy-weight, but 0install can run your program will the appropriate Python interpreter for your platform. In your program's XML description, do something like this (e.g. if you want Python >= 2.6, < 3):
<command name="run" path="myprog.py">
<runner interface="http://repo.roscidus.com/python/python">
<version not-before="2.6" before="3"/>
</runner>
</command>
See: http://www.0install.net/local-feeds.html
This will also make 0install download a suitable version of Python if the user doesn't have it already.
Note that you may want to do this even if you're only targetting Linux, because with Python 3 there is no single #! line that works on all platforms (some platforms, e.g. Arch, require "python2" not "python", while others, e.g. Debian, don't provide "python2", only "python").
#!/usr/bin/env python
That will call the env program to search your PATH for a Python executable.
If you need to ensure a specific version of Python you can do e.g.:
#!/usr/bin/env python3.11
Is there any way I could specify multiple interpreters ?
You don't need to. On Windows (at least as long as you don't have CygWin or similar installed), the Shebang line is treated as a normal Python comment; that means, it is ignored. Windows knows that it should run .py and .pyw files with the Python interpreter, because it is told that upon installation of Python.

Categories