#![windows_subsystem = "windows"]
use std::{
fmt::Display,
io::prelude::*,
time::{Duration, Instant},
};
use conpty::io::PipeReader;
fn main() {
let mut p = conpty::spawn("cmd").unwrap();
to_file(format!("Process PID={:?}", p.pid()));
let mut input = p.input().unwrap();
let mut output = p.output().unwrap();
output.blocking(false);
to_file(format!(
"{:?}",
wait_for(&mut output, "All rights reserved")
));
input
.write_all("echo \"This is a test string 😁\"\r\n".as_bytes())
.unwrap();
to_file(format!("{:?}", wait_for(&mut output, "😁")));
input.write_all(b"powershell\r\n").unwrap();
to_file(format!(
"{:?}",
wait_for(&mut output, "https://aka.ms/PSWindows")
));
input.write_all(b"cat examples/cat.rs\r\n").unwrap();
to_file(format!("{:?}", wait_for(&mut output, "main")));
}
fn wait_for(output: &mut PipeReader, s: &str) -> String {
let treashhold = Duration::from_secs(2);
let now = Instant::now();
let mut out = vec![0; 1000];
let mut buf = String::new();
loop {
try_read(output, &mut out, &mut buf);
if buf.contains(s) {
return buf;
}
if now.elapsed() > treashhold {
panic!("TIMEOUT REACHED")
}
}
}
fn try_read(o: &mut PipeReader, out: &mut Vec<u8>, buf: &mut String) {
match o.read(out) {
Ok(n) => {
let s = String::from_utf8_lossy(&out[..n]);
buf.push_str(&s);
}
Err(err) => {
if err.kind() == std::io::ErrorKind::WouldBlock {
return;
}
panic!("{:?}", err);
}
}
}
fn to_file(text: impl Display) {
let mut f = std::fs::File::options()
.append(true)
.create(true)
.write(true)
.open("info.txt")
.unwrap();
f.write_all(format!("{}\n", text).as_bytes()).unwrap();
f.flush().unwrap();
}