Can Python read from a Windows Powershell namedpipe? - python

I have the following named pipe created in Windows Powershell.
# .NET 3.5 is required to use the System.IO.Pipes namespace
[reflection.Assembly]::LoadWithPartialName("system.core") | Out-Null
$pipeName = "pipename"
$pipeDir = [System.IO.Pipes.PipeDirection]::InOut
$pipe = New-Object system.IO.Pipes.NamedPipeServerStream( $pipeName, $pipeDir )
Now, what i need is some Python code snippet to read from the above named pipe created. Can Python do that ?
Thanks in advance !

Courtesy :http://jonathonreinhart.blogspot.com/2012/12/named-pipes-between-c-and-python.html
Here's the C# Code
using System;
using System.IO;
using System.IO.Pipes;
using System.Text;
class PipeServer
{
static void Main()
{
var server = new NamedPipeServerStream("NPtest");
Console.WriteLine("Waiting for connection...");
server.WaitForConnection();
Console.WriteLine("Connected.");
var br = new BinaryReader(server);
var bw = new BinaryWriter(server);
while (true)
{
try
{
var len = (int)br.ReadUInt32(); // Read string length
var str = new string(br.ReadChars(len)); // Read string
Console.WriteLine("Read: \"{0}\"", str);
//str = new string(str.Reverse().ToArray()); // Aravind's edit: since Reverse() is not working, might require some import. Felt it as irrelevant
var buf = Encoding.ASCII.GetBytes(str); // Get ASCII byte array
bw.Write((uint)buf.Length); // Write string length
bw.Write(buf); // Write string
Console.WriteLine("Wrote: \"{0}\"", str);
}
catch (EndOfStreamException)
{
break; // When client disconnects
}
}
}
}
And here's the Python code:
import time
import struct
f = open(r'\\.\pipe\NPtest', 'r+b', 0)
i = 1
while True:
s = 'Message[{0}]'.format(i)
i += 1
f.write(struct.pack('I', len(s)) + s) # Write str length and str
f.seek(0) # EDIT: This is also necessary
print 'Wrote:', s
n = struct.unpack('I', f.read(4))[0] # Read str length
s = f.read(n) # Read str
f.seek(0) # Important!!!
print 'Read:', s
time.sleep(2)
Convert the C# code into a .ps1 file.

Related

Getting output from Python files when executed through C#

Im calling Python script from a C# app to execute with the code below
string srCommandName = "customWhisper.py D:\Tas\Monitor\Stemme_226.m4a 41f850e7-455e-4f84-b1eb-a5cccea49046.txt"
ProcessStartInfo psInfo = new ProcessStartInfo(srCommandName);
psInfo.UseShellExecute= false;
psInfo.RedirectStandardOutput = true;
using (Process process = Process.Start(psInfo))
{
using (StreamReader reader = process.StandardOutput)
{
string result = reader.ReadToEnd();
if (result=="")
{ }
}
}
My Python code is:
try:
if len(sys.argv)==3:
mediaPath = sys.argv[1]
textFilePath = sys.argv[2]
model = whisper.load_model("tiny")
isExist = os.path.exists(mediaPath)
if isExist:
results = model.transcribe(mediaPath, language = "da")
stab_segments = results['segments']
text_file = open(textFilePath, "w",encoding="utf-8")
for i in stab_segments:
text_file.write(i["text"] + '\n')
text_file.close()
print(0)
else:
print(1)
else:
print(len(sys.argv))
except Exception as er:
print(er)
The desired output from string result = reader.ReadToEnd(); should had been 0 (print 0) on success or one of the other prints. But its the srCommandName
Is there any way to get Python to return a value when called from C#
I use the below method to call python script from c# and get the result from python standard output back as a string. The FileName property of ProcessStartInfo should point to the python interpreter to use - not the python script. The python script should be sent as first argument.
private (string output, int exitCode) RunPythonScript(string pathToPythonFile, string args)
{
ProcessStartInfo start = new ProcessStartInfo();
start.FileName = #"C:\MyPathToPythonInterpreter\Scripts\python.exe";
start.Arguments = string.Format("{0} {1}", pathToPythonFile, args);
start.UseShellExecute = false;
start.RedirectStandardOutput = true;
using (Process process = Process.Start(start))
{
process.WaitForExit();
using (StreamReader reader = process.StandardOutput)
{
string result = reader.ReadToEnd();
return (result, process.ExitCode);
}
}
}

Ctypes calling Go Dll with arguments (C string)

How to pass a string as argument from Python to a Go Dll using ctypes:
Go-code:
package main
import "C"
import "fmt"
//export GetInt
func GetInt() int32 {
return 42
}
//export GetString
func GetString() {
fmt.Println("Foo")
}
//export PrintHello
func PrintHello(name string) {
// if name == "hello" { ... }
fmt.Printf("From DLL: Hello, %s!", name)
}
func main() {
// Need a main function to make CGO compile package as C shared library
}
Compiled on MacOs using: GOOS=windows GOARCH=386 CGO_ENABLED=1 CC=i686-w64-mingw32-gcc go build -buildmode=c-shared -o ./dist/perf_nlp.dll
Python code:
import ctypes
def getString():
nlp = ctypes.windll.LoadLibrary("H:/perf_nlp.dll")
dllFunc = nlp.GetString
dllFunc.restype = ctypes.c_char_p
return dllFunc()
def getInt():
nlp = ctypes.windll.LoadLibrary("H:/perf_nlp.dll")
dllFunc = nlp.GetInt
dllFunc.restype = int
return dllFunc()
def readString():
nlp = ctypes.windll.LoadLibrary("H:/perf_nlp.dll")
dllFunc = nlp.ReadString
dllFunc.argtypes = [ctypes.c_char_p]
dllFunc.restype = ctypes.c_char_p
return dllFunc(b'Foo')
print(getInt())
print(getString())
print(readString()). # Fails
Out:
42
Foo
None
unexpected fault address 0x871000
fatal error: fault
[signal 0xc0000005 code=0x0 addr=0x871000 pc=0x623e501f]
goroutine 17 [running, locked to thread]:
runtime.throw(0x6245b592, 0x5)
/Users/foobar/.goenv/versions/1.14.15/src/runtime/panic.go:1116 +0x64 fp=0x1242fda4 sp=0x1242fd90 pc=0x623be404
runtime.sigpanic()
/Users/foobar/.goenv/versions/1.14.15/src/runtime/signal_windows.go:249 +0x1ed fp=0x1242fdb8 sp=0x1242fda4 pc=0x623ceb8d
runtime.memmove(0x12500011, 0x800588, 0x32efe4)
/Users/foobar/.goenv/versions/1.14.15/src/runtime/memmove_386.s:89 +0x7f fp=0x1242fdbc sp=0x1242fdb8 pc=0x623e501f
fmt.(*buffer).writeString(...)
/Users/foobar/.goenv/versions/1.14.15/src/fmt/print.go:82
fmt.(*fmt).padString(0x124a60b0, 0x800588, 0x32efe4)
/Users/foobar/.goenv/versions/1.14.15/src/fmt/format.go:110 +0x6c fp=0x1242fdfc sp=0x1242fdbc pc=0x6241576c
fmt.(*fmt).fmtS(0x124a60b0, 0x800588, 0x32efe4)
/Users/foobar/.goenv/versions/1.14.15/src/fmt/format.go:359 +0x4d fp=0x1242fe14 sp=0x1242fdfc pc=0x6241664d
fmt.(*pp).fmtString(0x124a6090, 0x800588, 0x32efe4, 0x73)
/Users/foobar/.goenv/versions/1.14.15/src/fmt/print.go:450 +0x188 fp=0x1242fe38 sp=0x1242fe14 pc=0x62418f58
fmt.(*pp).printArg(0x124a6090, 0x62447c80, 0x1248c110, 0x73)
/Users/foobar/.goenv/versions/1.14.15/src/fmt/print.go:698 +0x776 fp=0x1242fe80 sp=0x1242fe38 pc=0x6241ad56
fmt.(*pp).doPrintf(0x124a6090, 0x6245e0a5, 0x14, 0x1242ff48, 0x1, 0x1)
/Users/foobar/.goenv/versions/1.14.15/src/fmt/print.go:1030 +0x12b fp=0x1242fef0 sp=0x1242fe80 pc=0x6241d81b
fmt.Fprintf(0x62476550, 0x1248c0d8, 0x6245e0a5, 0x14, 0x1242ff48, 0x1, 0x1, 0x623e2fe7, 0x0, 0x12488030)
/Users/foobar/.goenv/versions/1.14.15/src/fmt/print.go:204 +0x52 fp=0x1242ff20 sp=0x1242fef0 pc=0x62417bd2
fmt.Printf(...)
/Users/foobar/.goenv/versions/1.14.15/src/fmt/print.go:213
main.ReadString(...)
/Users/foobar/__projects__/heine/db_dll/perf_nlp.go:19
main._cgoexpwrap_c3579cea1e16_ReadString(0x800588, 0x32efe4)
_cgo_gotypes.go:71 +0x8d fp=0x1242ff54 sp=0x1242ff20 pc=0x6241e9bd
runtime.call16(0x0, 0x32ef1c, 0x32ef68, 0x8, 0x0)
/Users/foobar/.goenv/versions/1.14.15/src/runtime/asm_386.s:565 +0x30 fp=0x1242ff68 sp=0x1242ff54 pc=0x623e3020
runtime.cgocallbackg1(0x0)
/Users/foobar/.goenv/versions/1.14.15/src/runtime/cgocall.go:332 +0x149 fp=0x1242ffb0 sp=0x1242ff68 pc=0x62393f59
runtime.cgocallbackg(0x0)
/Users/foobar/.goenv/versions/1.14.15/src/runtime/cgocall.go:207 +0xb5 fp=0x1242ffe0 sp=0x1242ffb0 pc=0x62393d85
runtime.cgocallback_gofunc(0x0, 0x0, 0x0, 0x0)
/Users/foobar/.goenv/versions/1.14.15/src/runtime/asm_386.s:806 +0x7e fp=0x1242fff0 sp=0x1242ffe0 pc=0x623e419e
runtime.goexit()
/Users/foobar/.goenv/versions/1.14.15/src/runtime/asm_386.s:1337 +0x1 fp=0x1242fff4 sp=0x1242fff0 pc=0x623e4651
Working solution:
//export ReadString
func ReadString(name *C.char) *C.char {
res := "";
goName := C.GoString(name);
if goName == "Foo" {
res = "From DLL: Hello, Foo"
}else{
res = "From DLL: Hello!"
}
return C.CString(res)
}
Python:
def readString():
nlp = ctypes.windll.LoadLibrary("H:/perf_nlp.dll")
dllFunc = nlp.ReadString
dllFunc.argtypes = [ctypes.c_char_p]
dllFunc.restype = ctypes.c_char_p
return dllFunc(b'cFoo')
A Go string and a C string are entirely unrelated (except in that both are called strings, which is a lie for at least one of them).
Here Python is sending a C string because you've told it to, but Go expects a Go string, which has a completely diffrent layout so it blows up. And if it didn't blow up at the callsite it'd probably blow up when the GC tries to handle the string, which it can't, because it's not a Go string.
You want to look at the magical "C" pseudo-package: you need to take in a *C.char and copy that to a Go string using C.GoString before you can pass it to anything expecting a go String. Or something along those lines, my experience with cgo (especially calling into it) is limited to avoiding this as a bad idea.
Regardless you probably want to at the very least read the cgo documentation in full, FFI is tricky at the best of time, and FFI between two managed languages much more so.

How to print the file path from an open syscall using ebpf python?

I use bpf from the python bcc module, and I want that my probe function will print the file path of the current file (kind of a custom simplified opensnoop).
How can I do that?
This is what I have so far:
b = BPF(text="""
#include <linux/ptrace.h>
#include<linux/sched.h>
BPF_HASH(last);
int trace_entry(struct pt_regs *ctx)
{
char fileName[200] = {0};
bpf_probe_read(fileName, sizeof(fileName), &PT_REGS_PARM1(ctx));
bpf_trace_printk("File Opened<%s>\\n", fileName);
return 0;
}
""")
print("Tracing for open... Ctrl-C to end")
b.attach_kprobe(event="do_sys_open", fn_name="trace_entry")
#b.attach_kprobe(event=b.get_syscall_fnname("open"), fn_name='funcky')
b.trace_print()
Easy:
Insert this in kernel code:
// Nicer way to call bpf_trace_printk()
#define bpf_custom_printk(fmt, ...) \
({ \
char ____fmt[] = fmt; \
bpf_trace_printk(____fmt, sizeof(____fmt), \
##__VA_ARGS__); \
})
struct pair {
uint32_t lip; // local IP
uint32_t rip; // remote IP
};
and in kernel code insert print out code. This function call works exactly like printf with all format and placeholder ...
bpf_custom_printk("This year is %d\n", 2020);
Print output:
sudo cat /sys/kernel/debug/tracing/trace_pipe

Windows pipes: Write from C - read in Python

I'd like to transmit a few bytes of data though a pipe to plot it from python.
I started with some snippets I found here but I cant get them working.
I've created the pipe like this:
int main(void){
HANDLE hPipe;
char buffer[24];
DWORD dwRead;
hPipe = CreateNamedPipe(TEXT("\\\\.\\pipe\\Pipe"),
PIPE_ACCESS_DUPLEX | PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, // FILE_FLAG_FIRST_PIPE_INSTANCE is not needed but forces CreateNamedPipe(..) to fail if the pipe already exists...
PIPE_WAIT,
1,
24 * 16,
24 * 16,
NMPWAIT_USE_DEFAULT_WAIT,
NULL);
while (hPipe != INVALID_HANDLE_VALUE)
{
if (ConnectNamedPipe(hPipe, NULL) != FALSE) // wait for someone to connect to the pipe
{
while (ReadFile(hPipe, buffer, sizeof(buffer) - 1, &dwRead, NULL) != FALSE)
{
/* add terminating zero */
buffer[dwRead] = '\0';
/* do something with data in buffer */
printf("%s", buffer);
}
}
DisconnectNamedPipe(hPipe);
}
return 0;}
If I execute the following code it writes but the read part blocks:
import time
import struct
f = open(r'\\.\\pipe\\Pipe', 'r+b', 0)
i = 1
sss='ccccc'
while True:
s = sss.format(i)
i += 1
f.write(struct.pack('I', len(s)) + s) # Write str length and str
f.seek(0) # EDIT: This is also necessary
print 'Wrote:', s
n = struct.unpack('I', f.read(4))[0] # Read str length
s = f.read(n) # Read str
f.seek(0) # Important!!!
print 'Read:', s
time.sleep(2)
I tried commenting the ReadFile part in the C code but It did not work. Is there any other way to achieve this? I want to write from C and read from python. I tried writing into the pipe with CreateFile (from C) and it worked as expected. I only need the read part with python.
On most systems pipe is one-directional and you use two pipes to get two-directional (bidirectional) connection.
In your Python code you can open two connections
and then you don't need seek
import time
import struct
wf = open(r'Pipe', 'wb', 0)
rf = open(r'Pipe', 'rb', 0)
i = 0
template = 'Hello World {}'
while True:
i += 1
text = template.format(i)
# write text length and text
wf.write(struct.pack('I', len(text)))
wf.write(text)
print 'Wrote:', text
# read text length and text
n = struct.unpack('I', rf.read(4))[0]
read = rf.read(n)
print 'Read:', read
time.sleep(2)
EDIT: tested on Linux Mint 17, Python 3.4 & 2.7
I've solved it with PyWin32(http://sourceforge.net/projects/pywin32/files/) which seems to be the right tool for windows. I would rather use something more cross-plataform oriented but it has solved the problem.

How to properly handle file read/write errors in C?

I want to rewrite yEnc code to make it compilable on Win32 with Visual Studio 2008.
The issue is that yEnc uses unistd.h (UNIX) functions fcntl to check if a file is readable or writable. It is of course not compatible with MS Visual Studio.
Here's what I want to be remove:
static Bool writable(FILE *file)
{
int mode = fcntl(fileno(file),F_GETFL) & O_ACCMODE;
return (mode == O_WRONLY) || (mode == O_RDWR);
}
static Bool readable(FILE *file)
{
int mode = fcntl(fileno(file),F_GETFL) & O_ACCMODE;
return (mode == O_RDONLY) || (mode == O_RDWR);
}
And here is how it is called:
FILE* infile = PyFile_AsFile(Py_infile);
FILE* outfile = PyFile_AsFile(Py_outfile);
if(!readable(infile) || !writable(outfile) ) {
return PyErr_Format(PyExc_ValueError, "file objects not writeable/readable");
}
/* File stuff including */
fread(&read_buffer, 1, in_ind, infile);
if(ferror(infile) || ferror(outfile)) {
return PyErr_Format(PyExc_IOError, "I/O Error while encoding");
}
fputc(CR, outfile);
fputc(LF, outfile);
fflush(outfile);
/* End of file stuff */
Can someone help me converting this readable/writable check (with equivalent of try {} catch {} instead) ?
I believe it is easier to handle errors on file read/write than trying to know if a Windows file is readable/writable, because there doesn't seem to be simple Windows equivalents to fcntl/F_GETFL.
The solution doesn't seem complicated but as I'm new to C and Python, I don't want to take the risk of making a buggy exception handler.
Thanks for your help.
You don't have to convert it just install windows POSIX.
http://www.cygwin.com/
Finally, I think the following checks will be sufficient:
infile == NULL
outfile == NULL
fread != read_count
fwrite != write_count
ferror
This should be sufficient. Moreover, the file have been opened in Python first and I presume this file open has been tested for exceptions.
{
public string writepath;
public string readpath;
public string line;
public List<Reciepient> reciepients = new List<Reciepient>();//linking my ist from my rec class
public int index;
public Form1()
{
InitializeComponent();
writebutton.Enabled = false;//disables write button
}
public void createbutton_Click(object sender, EventArgs e)
{
writebutton.Enabled = true;//enables write button
folderBrowserDialog1.ShowDialog();//open folder browser
writepath = folderBrowserDialog1.SelectedPath+ #"\test.txt";//generate path
StreamWriter sw = new StreamWriter(writepath);//open new sw
textBox1.Text = writepath;//write path to textbox1
sw.Close();//close my sw
}
public void readbutton_Click(object sender, EventArgs e)
{
openFileDialog1.ShowDialog();//open my file browser
readpath = openFileDialog1.FileName;//grabbing file name
StreamReader sr = new StreamReader(readpath);//creating new sr
textBox2.Text = readpath;//putting readpath in textbox2
while(sr.Peek()!= -1)//will stop reading if noo more lines
{
line = sr.ReadLine();//tells to read lines listed
Console.WriteLine(line);
/*if (line.Length > 0)
continue; messing up!!
else
MessageBox.Show("Line Cannot be Read");
*/
string fname = line.Substring(0, 5);
string lname = line.Substring(6, 6);
int loccode = Int32.Parse(line.Substring(13, 1));
int wcode = Int32.Parse(line.Substring(15, 1));
double itemcost = double.Parse(line.Substring(17, 5));
int acode = Int32.Parse(line.Substring(23, 1));
Reciepient file = new Reciepient(fname, lname, loccode, wcode, itemcost,
acode);
reciepients.Add(file);//add to list
}
sr.Close();//closes streamreader
}
public void writebutton_Click(object sender, EventArgs e)
{
StreamWriter sw = new StreamWriter(writepath);
Console.WriteLine(reciepients.Count);
for (int index = 0; index < reciepients.Count(); index++)
{
Reciepient file = reciepients.ElementAt(index);
sw.WriteLine(file.fname + " " + file.lname +" "+ "="+ file.totalcost);
}
sw.Close();
}

Categories

Resources