我正在学习C#,我正在创建一个简单的WinForms应用程序,它的作用是启动一个简单的OpenVPN客户端:
void button_Connect_Click(object sender, EventArgs e)
{
var proc = new Process();
proc.StartInfo.FileName = "CMD.exe";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.WorkingDirectory = @"C:\Program Files (x86)\OpenVPN\bin";
proc.StartInfo.Arguments = "/c openvpn.exe --config config.ovpn --auto-proxy";
// set up output redirection
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardError = true;
// Input
proc.StartInfo.RedirectStandardInput = true;
// Other
proc.EnableRaisingEvents = true;
proc.StartInfo.CreateNoWindow = false;
// see below for output handler
proc.ErrorDataReceived += proc_DataReceived;
proc.OutputDataReceived += proc_DataReceived;
proc.Start();
StreamWriter myStreamWriter = proc.StandardInput;
proc.BeginErrorReadLine();
proc.BeginOutputReadLine();
proc.WaitForExit();
}
void proc_DataReceived(object sender, DataReceivedEventArgs e)
{
// output will be in string e.Data
if (e.Data != null)
{
string Data = e.Data.ToString();
if (Data.Contains("Enter Auth Username"))
{
myStreamWriter("myusername");
}
//MessageBox.Show(Data);
}
}
它现在做的是将CMD的所有输出发送到我的程序,该程序根据输出运行命令。
我目前的问题是,我需要写入流。我在myStreamWriter
中使用proc_DataReceived
,但它不在同一个上下文中,因此无效。
我收到以下错误:The name 'myStreamWriter' does not exist in the current context
,在该范围内显然不存在。
如何使这项工作?获取/设置属性?就像我说的那样,我对C#很陌生,所以对任何帮助表示赞赏。
答案 0 :(得分:2)
在表单中,添加以下字段:
public class Form1Whatevver: Form {
private StreamWriter myStreamWriter;
}
然后在你的代码中:
proc.Start();
this.myStreamWriter = proc.StandardInput;
proc.BeginErrorReadLine();
proc.BeginOutputReadLine();
现在,myStreamWriter将可用于proc_DataReceived()
void proc_DataReceived(object sender, DataReceivedEventArgs e)
{
// output will be in string e.Data
if (e.Data != null)
{
string Data = e.Data.ToString();
if (Data.Contains("Enter Auth Username"))
{
if (myStreamWriter != null) // Just in case
{
myStreamWriter("myusername");
}
}
//MessageBox.Show(Data);
}
}
答案 1 :(得分:1)
您所谈论的概念是Scope而非背景。
您可以通过多种方式更改代码,以便从myStreamWriter
访问proc_DataReceived
。
可以说是最简单的,就是将你想要效果的对象作为参数传递给函数。从未来的多线程和实现功能的角度来看,这通常是一种很好的方法。
void proc_DataReceived(
object sender,
DataReceivedEventArgs e,
StreamWriter writer)
{
...
writer("myusername");
...
}
然而,proc_DataReceived
显然是一个事件处理程序,您可能不想更改该函数的签名。
如果您在班级级别将myStreamWriter
声明为私有成员变量,则可以从班级中的任何位置进行访问。 this
是可选的但很好的形式。
class YourForm : Form
{
private StreamWriter myStreamWriter;
void button_Connect_Click(...
{
...
this.myStreamWriter = proc.StandardInput;
...
}
void proc_DataRecieved(...
{
...
this.myStreamWriter("myusername");
...
}
}
除非您想从类/表单外部访问StreamWriter
,否则不需要执行属性。
答案 2 :(得分:1)
简单的快速修复是将myStreamWriter
定义为类中的一个字段(即在方法的范围之外),然后在其中一个范围内实例化它:
private StreamWriter _myStreamWriter;
void button_Connect_Click(object sender, EventArgs e)
{
// Do some stuff
_myStreamWriter = proc.StandardInput;
// Do some stuff
}
这样做可以让你在课堂上的任何地方使用它。