我需要在命令提示符下执行以下命令。
C:\MySQL\MySQL Server 5.0\bin>mysql -uroot -ppassword < d:/admindb/aar.sql
当我在cmd中手动执行此操作时,我会得到我的结果。
现在我尝试以编程方式执行此操作,以便从c#代码中执行cmd。
我使用以下代码来执行此操作。我没有收到任何错误和结果!!!
当我调试时,我得到字符串commandLine的值,如下所示,
"\"C:\\MySQL\\MySQL Server 5.0\\bin\\\" -uroot -ppassword > \"D:/admindb/AAR12.sql"
我猜问题是这个字符串,传递给cmd。怎么解决这个问题??。
public void Execute()
{
string commandLine = "\"" + MySqlCommandPath + "\"" + " -u" + DbUid + " -p" + DbPwd + " > " + "\"" + Path.Combine(Path_Backup, FileName_Backup + ExcID + ".sql");
System.Diagnostics.ProcessStartInfo PSI = new System.Diagnostics.ProcessStartInfo("cmd.exe");
PSI.RedirectStandardInput = true;
PSI.RedirectStandardOutput = true;
PSI.RedirectStandardError = true;
PSI.UseShellExecute = false;
System.Diagnostics.Process p = System.Diagnostics.Process.Start(PSI);
System.IO.StreamWriter SW = p.StandardInput;
System.IO.StreamReader SR = p.StandardOutput;
SW.WriteLine(commandLine);
SW.Close();
}
答案 0 :(得分:4)
我使用了更多面向对象的approch来执行相同的任务。
我使用StreamReader读取文件并使用控制台重定向将文本直接注入mysql exe文件。像魅力一样。
更新:这是代码,它是VB而不是C#,但应该很容易翻译。 我使用此代码为某些单元测试创建一个空数据库。与仅使用文件作为输入从命令行启动mysql的优点是
a)如果出现故障,我会创建一个例外 b)您可以轻松地使用此代码来控制mysql而无需实际文件 c)在TestProject中,如果抛出异常,则直接在TestProtocol中从mysql获取错误输出。
请注意,我的班级中的UserName,UserName,Password,Schema是共享属性,您只需用字符串替换它们或修改函数调用。
Public Shared Sub SetupDatabase()
' basic configuration
Dim infile As String = "..\..\..\MyProject\initial_db.sql"
Dim mysql_binary As String = "mysql.exe"
Dim mysql_args As String = String.Format("-h {0} -u{1} -p{2} {3}", HostName, UserName, Password, Schema)
' Creates a StreamReader from infile
Dim reader As New StreamReader(infile)
' Create the process
Dim p As New Process()
p.StartInfo.FileName = mysql_binary
p.StartInfo.Arguments = mysql_args
' Redirect input/output/stderr
p.StartInfo.RedirectStandardOutput = True
p.StartInfo.RedirectStandardError = True
p.StartInfo.RedirectStandardInput = True
p.StartInfo.UseShellExecute = False
p.StartInfo.CreateNoWindow = True
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
' start the process
p.Start()
' read from infile and pass it to mysql
Do While reader.EndOfStream = False
p.StandardInput.WriteLine(reader.ReadLine)
Loop
' close stdin
p.StandardInput.Close()
' read from stdout / stderr
Dim stdout As String = p.StandardOutput.ReadToEnd()
Dim stderr As String = p.StandardError.ReadToEnd()
' wait for mysql to stop
p.WaitForExit()
' if exitcode != 0 we raise an exception and include the output from stderr
If p.ExitCode <> 0 Then
Throw New Exception("Initial DB Setup failed with Exitcode " & p.ExitCode & ":" & vbNewLine & stderr)
End If
p.Close()
reader.Close()
End Sub
答案 1 :(得分:1)
可能是因为你想进行I / O重定向,所以你正在向cmd.exe
进行外壳攻击。为什么不自己设置文件句柄,然后直接调用MySQL.exe?
public void Execute() {
Process p = new Process();
p.StartInfo.FileName = @"C:\MySQL\MySQL Server 5.0\bin\mysql.exe";
p.StartInfo.Arguments = String.Format( "-u{0} -p{1}", user, password );
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.Start();
System.IO.StreamWriter SW = p.StandardInput;
System.IO.StreamReader SR = p.StandardOutput;
/* Send data to MySQL and capture results */
SW.Close();
}
您可能还需要/需要设置WorkingDirectory
属性...
当然,真正的问题是,为什么不使用ODBC或某些更高级别的API与MySQL交谈而不是尝试自己运行mysql.exe
?我可以看到使用它运行mysqladmin.exe
,但mysql.exe
的所有功能都可以从ODBC获得。
如果你真的想在cmd.exe上推出那个可怕的命令行,那么你应该@try @-quoting syntax for strings - 它允许你避免转义反斜杠,并使用""
来表示{{ 1}}在字符串中。你的字符串最终定义如下:
"
编写字符串连接的更好方法是使用String.Format(),如下所示:
@"""C:\MySQL\MySQL Server 5.0\bin\mysql.exe"" -uroot -password < ""D:/admindb/AAR12.SQL"""