StackOverflow

:rofl:
I always wondered what does StackOverflow means.

image

Does anyone have any suggestion how to fix the code below?

import clr

clr.AddReference("mscorlib")
import System

from System.Diagnostics import Process



""" Example"""

class P(System.Diagnostics.Process):
    def __init__(self):
        self.StartInfo.UseShellExecute = True
        self.StartInfo.FileName = r"C:\Windows\System32\cmd.exe"
        self.StartInfo.CreateNoWindow = False
        self.standard_input = None
        self.standard_output = None
        self.standard_error = None
        
    
    @property
    def StandardInput(self):
        return self.standard_input
    
    @StandardInput.getter
    def StandardInput(self):
        return self.standard_input
    
    @StandardInput.setter
    def StandardInput(self, val):
        self.standard_input = System.IO.StreamWriter(val)
    
    def Start(self):
        return self.Start()
    
    
p_instance = P()
p_instance.Start()
p_instance.StandardInput("dir")

Thanks in advance.

self.Start() calls self.Start()? Do you mean fix the design of the code, or find that problem?

1 Like

ha :smiley:

Thanks @jdhill. What should it be?

def Start(self):
    return System.Diagnostics.Process.Start(self)

Can’t say I’ve done a whole lot with .NET python, nor with inheriting from Process … but maybe you are looking for super.Start().

As far as I understand super is the class my class is derived from.

Meaning:
super.Start() == System.Diagnostics.Process.Start()

Which is internal or whatever they call methods that are only called from an instance of the class in .net

Solution here seems to work, but how can I do this with my own class?

I’ll try "".format()

I’ve found super() in the context of Rhino/Ironpython to be strange.

Maybe helpful:
https://ironpython.net/documentation/dotnet/dotnet.html#calling-base-constructor

Also the syntax for using super in 2.7 is different than 3.+:

https://docs.python.org/2.7/library/functions.html#super

class C(B):
    def method(self, arg):
        super(C, self).method(arg)
1 Like

weird

import clr

clr.AddReference("mscorlib")
import System

from System.Diagnostics import Process



pi = System.Diagnostics.ProcessStartInfo("CMD.exe")
pi.ArgumentList.Add("cd /")
pi.ArgumentList.Add("dir")
pi.ArgumentList.Add("cd Windows")
pi.ArgumentList.Add("dir")

p = System.Diagnostics.Process(pi)
p.Start()

result:

but ProcessStartInfo has a property ArgumentList according to this:
https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.processstartinfo.argumentlist?view=netcore-3.0&viewFallbackFrom=netframework-4.8

Update:
Just noticed the link it has view=netcore-3.0&viewFallbackFrom=netframework-4.8

Is it possible that ArgumentList was added in a version not yet supported by IronPython?

LOL

I have a little progress:

import clr

clr.AddReference("mscorlib")
import System

from System.Diagnostics import Process

class MyTestProcess:
    def __init__(self):
        p = Process()
        p.StartInfo.UseShellExecute = False
        p.StartInfo.RedirectStandardInput = True
        p.StartInfo.RedirectStandardOutput = True

        p.StartInfo.FileName = r"C:\Windows\System32\cmd.exe"
        p.StartInfo.CreateNoWindow = False
        p.Start()

        #System.IO.StreamWriter wr = p.StandardInput
        #System.IO.StreamReader rr = p.StandardOutput
        #
        #wr.Write("dir" + "\n")
        #System.Console.WriteLine(rr.ReadToEnd())
        #wr.Flush()


mp = MyTestProcess()

I need to figure out how to translate the commented part
(code taken from here)

Regarding the ArgumentList, the docs say that is supported on .NET Core & Standard 2.1, but 2.1 is not supported on .NET 4.8, let alone the .NET 4.0 that I see for the IronPython in my Rhino install. You may use ProcessStartInfo.Arguments instead.

I realized that is not what I need, I need to start CMD with commands and not some.exe -arg which I understand ProcessStartInfo.Arguments is for.

my batch looks like this echo some command with arguments | cmd.exe

the “|” pipes the ‘some command with arguments’ into the process of cmd.exe.

I wish to implement this without having to create .bat (.cmd) file

Not sure I understand without more context; I imagine you mean you are doing something like echo python --version | cmd.exe ?

yes, imagine this is the batch.

I want to get rid of this batch and launch similar from .net (preferably with python)

if you have more than one command currently I have to do:

batch 1:
echo start batch2 arg1 | cmd.exe

batch 2:
echo command arg1 arg2

in order to get all necessary inputs inside the same cmd.exe process.

I think I did it:

This is the answer:


import clr

clr.AddReference("mscorlib")
import System

System.Diagnostics.Process.Start(r"C:\Windows\System32\cmd.exe", "/c cd c:/ & dir & cd windows & dir & pause")

This will probably work now with StartInfo.Arguments

fwiw, a couple other examples:

import subprocess

python_output = subprocess.check_output('C:\\Python27\\python.exe --version', stderr=subprocess.STDOUT)
print('python_output: {0}'.format(python_output))

cmdexe_output = subprocess.check_output('cmd.exe /c echo cmd.exe got {0}'.format(python_output))
print('cmdexe_output: {0}'.format(cmdexe_output))

And:

import clr

clr.AddReference("mscorlib")
import System

from System.Diagnostics import *

def call(exe, args):
    pi = ProcessStartInfo()
    pi.UseShellExecute = False
    pi.CreateNoWindow = True
    pi.FileName = exe
    pi.Arguments = args
    pi.RedirectStandardError = True
    pi.RedirectStandardOutput = True
    p = Process.Start(pi)
    p_out = p.StandardOutput
    p_err = p.StandardError
    p.WaitForExit()
    return p_out.ReadToEnd(), p_err.ReadToEnd()

python_output = call('C:\\Python27\\python.exe', '--version')
cmdexe_output = call('cmd.exe', '/c echo cmd.exe got {0}'.format(python_output))

print('cmdexe_output: {0}'.format(cmdexe_output))
1 Like

Thanks JD(@jdhill),

The first example seems to gets stuck somehow but the second one is working.

Simplified: Whenever you allocate memory (directly or indirectly) you can do that on the heap or on the stack. A value type such as float, char or struct usually gets allocated on the stack by default, because they usually are small and need to be executed fast.
Objects which require much more space in memory such a class usually gets allocated on the heap, a bigger but slower piece of memory. Now a stack overflow usually appears when there is no memory left on your stack, usually this only happen nowadays if there is a memory leak somewhere (or if you are a victim of an attack)

1 Like

Thanks @TomTom,

I am still not quite sure what ‘heap’ and ‘stack’ are. At first I thought both are like two lists. One containing the variable names and the other containing the values. Reading your answer makes me understand I am dead wrong. :roll_eyes:

its just memory in your RAM. They work differently but are doing the same.

1 Like