You will have to delay the reading of the file probably if you are executing things like that that require time… i have no idea how you would now when a process is done
The script execution time is actually pretty immediate, to be honest. I’m probably going to put a small delay before reading the .log file, just to be sure.
I’m pasting the PowerShell script if anyone is ever going to need it.
Ignition’s scripting functions target the common case, usually. In this case, you want to use the java Process class directly. Full control over the created OS process, including the option to connect and work with standard pipes in parallel. So, no need for a log file. The process can just write to its standard output and the java side can read it.
here is a simple example in python using subprocess, we use to execute powershell 7 via perspective.
def executePowerShell(commands):
"""
Executes the given command(s) string in Windows PowerShell 7
:param commands: The string of command(s) to execute.
Example:
'''
hostname
"test string"
'''
Yields:
1ABCD-HOSTNAME
test string
:type commands: str
:returns: The stdout and the return code from the PowerShell process.
Example: ("ABCD-HOSTNAME\ntest string", 0)
:rtype: tuple
"""
import subprocess
cmd = subprocess.Popen(['pwsh'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
stdout = cmd.communicate(commands)[0]
return stdout, cmd.returncode
Yes. It can be used anywhere you can run a script. You could add it to the project library or re-write it directly into an action script.
You don't necessarily need the function to wrap it, but as you learn Ignition you will find you should be organizing you scripts for re-use where needed. Its not obvious early on, but spending time thinking about the structure of your code/scripts etc. goes a long way to keep things sane as your project grow.
Correct, scripting uses jython, so you can use java functions in addition to jython functions. To me it comes down to what your comfortable with, but sometimes you need to evaluate performance as well. Sometimes the Java might be harder to write, but gives you more control and better performance. Sometimes it comes down to skill/comfort level. I just know python better and others know java better. You'll see both approaches debated all over the forums I've learned a lot of java stuff from @pturmel over the years for sure!
jython has bugs and poor performing implementations scattered through its library. I've long advocated the use of java equivalents instead of jython wherever possible. Anything to do with network traffic, datetime, and proper handling of international strings/bytes streams in particular.
So, I strongly encourage using java's Process over jython's subprocess. Especially if character encoding on the traffic matters.
Trying this script right now in 7.9 and it doesn't work as from what I understand .readAllBytes() was not introduced yet. Trying process.getInputStream().readAllBytes() yields AttributeError: 'java.io.BufferedInputStream' object has no attribute 'readAllBytes', I tried process.getInputStream().toString() but that is only giving me stuff like java.io.BufferedInputStream@64418d37. Do you know how can I do this in 7.9?
Edit:
I was able to accomplish it like this
from java.lang import ProcessBuilder
from java.io import ByteArrayOutputStream
import java.nio.charset.StandardCharsets as StandardCharsets
import jarray
commands = ['someCommandHere']
pb = ProcessBuilder(commands)
process = pb.start()
result = ByteArrayOutputStream()
buffer = jarray.zeros(1024, 'b')
while True:
length = process.getInputStream().read(buffer)
if length == -1:
break
result.write(buffer, 0, length)
print result.toString(StandardCharsets.UTF_8.name())