I am trying to execute an AutoIt script via Python using os.system(). However, the program freezes and crashes without any error code. When I am executing the AutoIt script manually it works fine.
Python code:
def main():
Exe_file_dir = "C:\\Users\\matan\\Downloads\\npp.8.2.Installer.x64.exe"
os.system("C:\\Users\\matan\\Desktop\\14th\\gal\\The_project\\startAutoIt\\RealMain.exe
" + "Record#"+Exe_file_dir)
Autoit code:
#RequireAdmin
#include <Array.au3>
#include <GUIConstantsEx.au3>
#include <EditConstants.au3>
#include <GuiButton.au3>
#include ".\RecordMain.au3"
#include ".\RunMain.au3"
#include <MsgBoxConstants.au3>
Main()
Func Main()
If $CmdLine[0] > 0 Then
If $CmdLine[1] <> #ScriptName Then
$mode = $CmdLine[1]
;~ $dir = $CmdLine[2] ;Now, you can use the variable $PAR in your script.
$parmeters = StringSplit($mode,'#')
$mode = $parmeters[1]
$dir = $parmeters[2]
Endif
Endif
If $mode = 'Record' Then ;RecordMode
RecordMain($dir)
ElseIf $mode = 'Run' Then ;RunMode
RunMain($dir)
EndIf
;~ Global $aFileList[0] ;Reset file list
EndFunc
This the Autoit function I run:
Func RecordMain($sFile) ; Open the installation, and get controls that user click on them until the instalatin ended.
Opt("MouseCoordMode", 2) ; Change relative Coords of Mouse to the active window
_MouseSetOnEvent($MOUSE_WHEELSCROLLDOWN_EVENT, "MouseWheel_Events") ; MouseWheelEvents start
_MouseSetOnEvent($MOUSE_WHEELSCROLLUP_EVENT, "MouseWheel_Events") ; MouseWheelEvents start
If (Not StringInStr($sFile, ".msi") = 0 Or Not StringInStr($sFile, ".MSI") = 0) Then;if it msi fie
$iPID = Run("msiexec /i "&$sFile)
$sLog = StringReplace($sFile, ".msi", ".txt") ; Name for log file.
Else ;if it exe file
$iPID = Run($sFile)
$sLog = StringReplace($sFile, "exe", "txt") ; Name for log file.
EndIf
_FileCreate($sLog) ; Create log file. locate in the wizard location
Global $hFileOpen = FileOpen($sLog, $FO_APPEND) ; Open log file
Global $hDLL = DllOpen("user32.dll") ; For _IsPressed func
While 1
If _IsPressed("01", $hDLL) Then ; When mouse click
$sWinIdentify = WinIdentify() ; Identify the window
$sReturn = GetControlOnMouse(WinGetHandle("[ACTIVE]")) ; Get Control On Mouse
;~ MsgBox($MB_SYSTEMMODAL, "Title", $sReturn, 10)
If Not $sReturn = False Then ; When have control
FileWrite($hFileOpen, $sWinIdentify & $sReturn & #CRLF) ; Write data to file
EndIf
While _IsPressed("01", $hDLL)
Sleep(100)
;~ MsgBox($MB_SYSTEMMODAL, "Title", "sleep", 10)
WEnd
EndIf
If Not ProcessExists($iPID) Then ;check if the file stil open
;~ MsgBox($MB_SYSTEMMODAL, "Title", "before", 10)
ExitLoop
EndIf
WEnd
DllClose($hDLL)
FileClose($hFileOpen) ; Close log file
_MouseSetOnEvent($MOUSE_WHEELSCROLLDOWN_EVENT) ; MouseWheelEvents stop
_MouseSetOnEvent($MOUSE_WHEELSCROLLUP_EVENT) ; MouseWheelEvents stop
EndFunc
I tried to reproduce your issue and copied your Python code and create stub functions for AutoIt functions (see code snippets and possible solution below).
First of all, current version of main() Python function has syntax error (the quotation mark should be on the first line in call os.system(). I didn't manage to edit description). Check your local code (use double backslashes as editor suggested you.). But this is not a cause of issue because you would have seen the error "SyntaxError: EOL while scanning string literal" in terminal
As you said, manually running AutoIt script works fine and you don't see any error in terminal. So I guess that cause in executing of RealMain.exe file. Some antivirus apps block execution of such executable files that operates with important files and folders (user Downloads folder in your case). For example when I tested your code my Windows Security app suggested me to send them this compiled .exe (by Aut2exe.exe utility) and check it. You could miss a blocking notification from your antivirus.
Try to substitute your .exe file to not compiled .au3 file and check result. i.e.
os.system("D:\\tmp\\tmp_autoit\\RealMain.au3 "
+ "Record#"+Exe_file_dir)
But don't forget that default shell behaviour for .au3 files must be 'Run', not 'Edit'. You can check it in advance by double clicking on RealMain.au3 file. But watch for antivirus notification, because AutoIt3.exe also can be blocked.
Also check carefully how and where you run your Python script (adding if __name__ == "__main__": block at the end of script is a good practice).
My code snippets to quick reproduce:
# run_real_main_script.py
import os
def main():
Exe_file_dir = "D:\\tmp\\tmp_autoit\\Sample.log"
os.system("C:\\Users\\myuser\\Downloads\\RealMain.exe "
+ "Record#"+Exe_file_dir)
if __name__ == "__main__":
main()
;~ RunMain.au3
#include <AutoItConstants.au3>
#include <MsgBoxConstants.au3>
Func RunMain($sFile)
MsgBox($MB_SYSTEMMODAL, "", "Run RunMain() function" & #CRLF & "$sFile=" & $sFile)
EndFunc
;~ RecordMain.au3
#include <AutoItConstants.au3>
#include <MsgBoxConstants.au3>
Func RecordMain($sFile)
MsgBox($MB_SYSTEMMODAL, "", "Run RecordMain() function" & #CRLF & "$sFile=" & $sFile)
EndFunc
RealMain.au3 is the exact copy of "Autoit code:" snippet in the description.
I executed run_real_main_script.py script with installed Python 3.9.2 interpreter in PowerShell as:
python "D:\tmp\tmp_autoit\check_scripts\run_real_main_script.py"
Related
I'm facing quite simple problem, yet still not able to figure out what in particular causes that, and - more importantly - how to solve it.
I'm currently on Linux, and I would like to run an python app (script) from a Java application. The script is on PATH, thus I really would like to utilise that (avoid using absolute path to the script), if possible.
However, all I tried resulted in various forms of "File does not exist".
Sample
As a demonstration, I've tried to run one python3-based app (meld)
and one binary-built app (ls) for comparison:
$ which ls
/usr/bin/ls
$ file /usr/bin/ls
/usr/bin/ls: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=[...], for GNU/Linux 3.2.0, stripped
$ which meld
/usr/bin/meld
$ file /usr/bin/meld
/usr/bin/meld: Python script, UTF-8 Unicode text executable
$ head -n1 /usr/bin/meld
#!/usr/bin/python3
Nextly, I've created simple Java main, which tries several ways how to start theese:
package cz.martlin.processes;
import java.io.File;
import java.io.IOException;
import java.lang.ProcessBuilder.Redirect;
import java.util.List;
import java.util.stream.Collectors;
public class ProcessPlaying {
public static void main(String[] args) {
List<List<String>> commands = List.of(
List.of("ls"),
List.of("/usr/bin/ls"),
List.of("meld"),
List.of("/usr/bin/meld"),
List.of("python3", "/usr/bin/meld"),
List.of("/usr/bin/python3", "/usr/bin/meld"),
List.of("sh", "-c", "meld"),
List.of("sh", "-c", "/usr/bin/meld"),
List.of("sh", "-c", "python3 /usr/bin/meld")
);
for (List<String> command : commands) {
run(command);
}
}
private static void run(List<String> command) {
System.out.println("Running: " + command);
//String executable = command.get(0);
//boolean exists = new File(executable).exists();
//System.out.println("Exists the " + executable + " ? " + exists);
try {
ProcessBuilder pb = new ProcessBuilder(command);
pb.redirectError(Redirect.INHERIT);
Process proc = pb.start();
// Process proc = Runtime.getRuntime().exec(command.stream().collect(Collectors.joining(" ")));
int code = proc.waitFor();
System.out.println("OK, return code: " + code);
} catch (IOException e) {
System.out.println("Failed to start: " + e.toString());
} catch (InterruptedException e) {
System.out.println("Failed to await: " + e.toString());
}
System.out.println();
}
}
Here are the results:
Running: [ls]
OK, return code: 0
Running: [/usr/bin/ls]
OK, return code: 0
Running: [meld]
Failed to start: java.io.IOException: Cannot run program "meld": error=2, Directory or file doesn't exist
Running: [/usr/bin/meld]
Failed to start: java.io.IOException: Cannot run program "/usr/bin/meld": error=2, Directory or file doesn't exist
Running: [python3, /usr/bin/meld]
python3: can't open file '/usr/bin/meld': [Errno 2] No such file or directory
OK, return code: 2
Running: [/usr/bin/python3, /usr/bin/meld]
/usr/bin/python3: can't open file '/usr/bin/meld': [Errno 2] No such file or directory
OK, return code: 2
Running: [sh, -c, meld]
sh: line 1: meld: command not found
OK, return code: 127
Running: [sh, -c, /usr/bin/meld]
sh: line 1: /usr/bin/meld: Directory or file doesn't exist
OK, return code: 127
Running: [sh, -c, python3 /usr/bin/meld]
python3: can't open file '/usr/bin/meld': [Errno 2] No such file or directory
OK, return code: 2
To sum it up:
all of the commands tried works when executed directly from the shell (either sh or bash)
executing the binary works either by the full path (/usr/bin/ls) or by just the name (ls)
executing the python script the same way doesn't work neither way
when trying to run the python3 interpreter and populate the script path as an argument to the python, now the python yields the script file doesn't exist
trying to populate it as a command to the brand new shell didn't help either
I've tried to use the Runtime#exec (based on this comment: https://stackoverflow.com/a/36783743/3797793) to start the process (both the exec(String) and exec(String[] forms), but no sucess (none of the listed commands did actually execute).
Thus, my question is/are:
What do I understand wrong?
How to start the Python script from Java?
Would some small (ba)sh script wrapper do the job?
Since it's python3-based, Jython wouldn't help here (because the latest one is 2.7.*), would it?
Further requirements:
As mentioned, I would like to be able to avoid using full path to the Python script
Also, I would like to have platform independant solution (at least Linux and Windows compatible)
Thanks in advance
I've created a DotNet Core Razor MVC project and in there, I have created a directory called python. Within that python directory, I have created a python script called myscript.py.
Following the real-time chat example for SignalR, I have added a function to my ChatHub which is supposed to execute myscript.py:
private string ProcessMessage(string message)
{
ProcessStartInfo start = new ProcessStartInfo();
start.FileName = "/Users/SomeUser/Documents/Code/VisualStudio/MyProject/MyProject/python/myscript.py";
start.Arguments = message;
start.UseShellExecute = false;// Do not use OS shell
start.CreateNoWindow = true; // We don't need new window
start.RedirectStandardOutput = true;// Any output, generated by application will be redirected back
start.RedirectStandardError = true; // Any error in standard output will be redirected back (for example exceptions)
using (Process process = Process.Start(start))
{
using (StreamReader reader = process.StandardOutput)
{
string stderr = process.StandardError.ReadToEnd(); // Here are the exceptions from our Python script
string result = reader.ReadToEnd(); // Here is the result of StdOut(for example: print "test")
return result;
}
}
}
Notice I have provided the full path to start.FileName. However, when I run this, I get a permission denied error.
I've tried various combinations of that path (e.g. ~/python/myscript.py)
How can I resolve this? I'm running VS for Mac, if that makes a difference.
I am currently running this on Raspbian OS - Debian.
I have two separate programs running in unison. I have a c++ 'engine' and a python 'gui' interface. I know there is probably a much better practice, but at the moment they are communicating via flat files. Essentially the python GUI writes to a file, cmd.sf, with specific text and the engine then decodes that exact same file and executes whatever it needs to do.
The setup is quite simple:
C++ Engine:
The C++ program is constantly reading the cmd.sf file and stays in an infinite loop within the engine if the context of the file is -1. The moment the file changes the engine should parse what the Python GUI essentially wrote and upon successful execution of whatever the contents told the engine to do, it writes back to the file -1
Python GUI
On the GUI end, it's the same concept except it is reversed. GUI also constantly reads from the cmd.sf file and doesn't proceed with writing the same or different instruction until it knows the C++ engine is done with its previous instruction. So it essentially checks the file to make sure it is anything BUT -1
The problem lies where if I initially set cmd.sf to -1, the C++ engine does what it needs to do successfully, by constantly reading and checking the contents of the file. However, the moment I instruct the GUI to change the file's contents, the C++ engine hangs, spits out a seg fault, and aborts.
However, I have found something that does work and I can not for the life of me figure out why. If I was to open cmd.sf in a text-editor such as geany (I am Raspbian) and change the contents via the editor and save it, it does not cause a segfault error. In fact the C++ engine notices the change of the file contents, executes the instruction appropriately and write -1 back to the file. It seems to not like it when I programatically change the contents of the file.
Here is a snippet of my python code that changes the contents of the file, this is nested in a loop:
scan_cmd = AllCommands.start_scan
# generate the key cmd packet for engine to start listening to incoming switches
#
# with open("../data/switches_debug.sf") as sw_file:
# switch_ids = [i.split(",")[0] for i in sw_file.readlines()]
# #print(switch_ids)
packet = CommandPacket(0xFFFFFF, scan_cmd)
content = ""
can_edit_file = False
while not can_edit_file:
with open("../data/cmd.sf", "r") as cmd_file:
try:
content = int(cmd_file.readlines()[0])
except ValueError:
# means gui has already written to file and is in the form of x,x,x,...,x
# 12345,67,8
# The beginning of this function should just check to see if
# file content IS NOT -1 in order to prevent engine and gui
# writing to the file at the same time
#
# So if GUI has written to file and in the
# form of csv, it is obviously not -1
#
# assign content a value that is not -1
content = 0
if content == -1:
can_edit_file = True
msg = "Begin Listening... [%s]" % packet.hex()
print(msg)
content = ','.join(str(x) for x in packet.plist)
# open as 'w' to overrite content of file
with open("../data/cmd.sf", "w") as cmd_file:
cmd_file.write(content)
print("Wrote [%s] to ../data/cmd.sf" % packet.hex())
Similarly, this is the C++ code that reads and checks if the file has changed:
Scribe Cher("../data/cmd.sf");
for (;;) {
std::cout << std::flush;
// cpu_timer tmr;
// loop forever and read from cmd.sf for instructions
// if file contents is != -1 instruction from GUI is set; read and execute
// upon successful instruction execution write '-1' to file
// read contents of cmd.sf file
bool file_is_ready = false;
int u = 0;
do{
Cher.ReadFile(); // custome object that actually does the reading
cmd_file = std::stoi(Cher.FileContents); // Cher.FileContents is std::string
//debugging section
if(u % 10000 == 0){
std::cout << std::flush;
fmt::printf("File Contents: {%s}\n", Cher.FileContents);
}
if(cmd_file != -1){
file_is_ready = true;
}
u++;
}while(!file_is_ready);
}
The Cher instance is of object Scribe with is a helper class that controls reading/writing to files. Upon initialization, it sets one important member within the class and that is the path to file.. each "Scribe" is assigned to one file.
void Scribe::ReadFile(){
std::string file_contents;
std::vector<std::string> vstring;
this->File.close(); //in case the file is opened
if(!this->File.open(std::ios::in)){
throw std::ios::failure("Unable to open file.");
//std::cout << "Unable to Open" << std::endl;
}
this->File.clear();
this->File.seekg(0, std::ios_base::beg);
while(this->File >> file_contents){
std::cout << "infinite loop" << std::endl;
vstring.push_back(file_contents);
}
//for(auto &i: vstring){
// std::cout << i << std::endl;
//
this->FileContents = vstring[0];
this->File.close();
}
Here is an example stdout output from the terminal when I run this by initially setting the cmd.sf to -1
File Contents: -1
File Contents: -1
File Contents: -1
File Contents: -1
File Contents: -1
File Contents: -1
File Contents: -1
File Contents: -1
File Contents: -1
File Contents: -1
File Contents: -1
Segmentation Fault //this is when I use the python gui to change file contents
OK, so after searching a little too hard over the internet I still have my same issue. I have a very simple python script that opens up the specified excel file and then runs a macro.
I know for a fact that my python script runs as it should stand alone.
I know for a fact that my C++ code runs as it should.
But the combo of both creates a 'com_error'. Just so anyone who sees this knows, these are all the tests I have ran:
(1) simple python script (just prints hello) --> passed
(2) use C++ to run same simple .py script --> passed
(3) more advanecd python script (opens excel, runs macro, save and close) --> pass
(4) usc C++ code to run advanced .py script --> fail.
And there is my problem. this has something to do with the win32com.client and an error the server throws because it cant find the file location (but trust me it can because it passed the 'find file' test)
I'm running Windows7, Python 2.7, And the latest version of JetBrains Clion (2017.1.2).
Any help would be so appreciated. Thanks! Happy coding.
C++ code:
#include <iostream>
#include <Windows.h>
using namespace std;
int main() {
const char *cmd = "python C:\\Users\\Alex.Valente\\Desktop\\python.py";
PROCESS_INFORMATION processInformation = {0};
STARTUPINFO startupInfo = {0};
startupInfo.cb = sizeof(startupInfo);
BOOL result = CreateProcess(NULL, (LPSTR)cmd,
NULL, NULL, FALSE,
NORMAL_PRIORITY_CLASS,
GetEnvironmentStrings(), NULL, &startupInfo, &processInformation);
if(!result){
return -1;
}
WaitForSingleObject( processInformation.hProcess, INFINITE );
return 0;
}
Python Script:
from __future__ import print_function
import unittest
import os.path
import win32com.client
import os
class ExcelMacro(unittest.TestCase):
def test_excel_macro(self):
xlApp = win32com.client.DispatchEx('Excel.Application')
xlsPath = r'C:\Users\Alex.Valente\Desktop\Data.csv'
xlApp.Visible = True
wb = xlApp.Workbooks.Open(Filename=xlsPath)
xlApp.Run("PERSONAL.XLSB!PythonTest")
wb.Save()
wb.Close()
xlApp.Quit()
print("Macro ran successfully!")
if __name__ == "__main__":
unittest.main()
And the Error that is printed after I run it:
======================================================================
ERROR: test_excel_macro (__main__.ExcelMacro)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Users\Alex.Valente\Desktop\python.py", line 25, in test_excel_macro
wb = xlApp.Workbooks.Open(Filename=xlsPath)
File "<COMObject <unknown>>", line 8, in Open
com_error: (-2147417851, 'The server threw an exception.', None, None)
----------------------------------------------------------------------
Ran 1 test in 6.305s
FAILED (errors=1)
I'm trying to write a vim plugin that uses a Python code block inside of it. I would like to get the full path of myvim.vim (/home/myusername/.vim/bundle/myvim/plugin/myvim.vim) inside of my python code block. Unfortunately you can't get the path by using __file__ as in a .py file. I can't use vim.command(':pwd') either because that just prints the path of the location where the plugin function is called from.
myvim.vim
function! Myvim()
python << EOF
import vim
vim_path = "full myvim.vim path here"
print vim_path
EOF
endfunction
EDIT
#actionshrimp, I'm trying this:
myvim.vim
function! Myvim()
let s:curfile = expand("<sfile>")
let s:curfiledir = fnamemodify(s:curfile, ":h")
python << EOF
import vim
py vim_path = vim.eval('expand("<sfile>")')
print vim_path
EOF
endfunction
You can use <sfile> to get the path of the currently executing vimscript, like so:
let s:curfile = expand("<sfile>")
let s:curfiledir = fnamemodify(s:curfile, ":h")
To pass that to python you should be able to use:
py vim_path = vim.eval('expand("<sfile>")')
or if you've set the variable:
py vim_path = vim.eval('s:curfile')
For clarity here's a full example (saved as 'D:\tmp\test.vim'):
python << EOF
import vim
vim_path = vim.eval('expand("<sfile>")')
print vim_path
EOF
When I have it open and type :so % it shows 'D:\tmp\test.vim' at the bottom.