这几天打算做一个c#安装部署项目,附带要还原Oracle数据库,之前的想法是想在Web服务器上能够自动还原Oracle数据库(不管Web服务器是否已安装Oracle客户端或服务端),后来经过验证此法是行不通的,不过SqlServer就可以,它是可以调用Interop.SQLDMO.dll组件,但是Oracle的话需要调用SqlPlus或imp、Exp等工具,这样的话必须要安装Oracle,后来在网上找了几种Oracle免安装方式,有些是可以直接连Oracle服务器了,但是没imp、exp等工具,后来好不容易找了一个有imp、exp工具的,可以将数据导出来,但是我试了一下午导入(用自己开发的一个导入程序),结果试了一下午就是不行。表现出来的效果好像是死锁了,但是后来我直接用command命令一试,结果表明是我的免安装的Oracle环境问题。
无奈我想只能调整一下我的方案,在web服务器上安装时让用户自己选择安装项目(选安装网站),在数据库服务器选“安装数据库”。
今天主要实验的是用C#调用command命令行来执行Oracle的导入或执行Oracle 的 Sql操作:
如果想获取标准输出流或错误输出流时,在执行WaitForExit()方法时可能会导致死锁情况的发生,可以有几种方式
1. 异步读取流。
2.使用两个线程分别读取标准输出流和错误输出流。
1.异步读流:
private void Imp1() { string user; string paw; string server; string excute, path; try { user = txtUser.Text; paw = txtPwd.Text; server = txtServer.Text; path = txtPath.Text; excute = "imp" + " " + user + "/" + paw + "@" + server + " buffer=10000000 full=y " + "file = " + path + " log=imp.txt"; //excute = "sqlplus" + " " + user + "/" + paw + "@" + server + " @createUser.sql"; ProcessStartInfo pi = new ProcessStartInfo(); pi.FileName = "Imput.bat"; pi.UseShellExecute = false; pi.RedirectStandardOutput = false; pi.RedirectStandardError = true; pi.RedirectStandardInput = false; pi.CreateNoWindow = true; pi.WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory; Process p = new Process(); p.StartInfo = pi; p.Start(); p.BeginErrorReadLine();//异步读取 p.WaitForExit();//等待程序执行完退出进程 p.Close();//关闭进程 MessageBox.Show("导入成功", "提示信息"); } catch (Exception ex) { MessageBox.Show(ex.Message, "提示信息"); } }
----------------------------------------------------------------------------------------
2.使用线程
private void Imp2() { string user; string paw; string server; string excute, path; try { user = txtUser.Text; paw = txtPwd.Text; server = txtServer.Text; path = txtPath.Text; excute = "imp" + " " + user + "/" + paw + "@" + server + " buffer=10000000 full=y " + "file = " + path + " log=imp.txt"; Process p = new Process(); p.StartInfo.FileName = "cmd.exe"; p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardInput = true; p.StartInfo.RedirectStandardOutput = true; p.StartInfo.RedirectStandardError = true; p.StartInfo.CreateNoWindow = true; p.Start(); p.StandardInput.WriteLine(excute); p.StandardInput.WriteLine("pause"); p.EnableRaisingEvents = true; p.BeginOutputReadLine();//开始异步读取 //string error = p.StandardError.ReadToEnd(); //同步读取 ThreadStandardOutput t1 = new ThreadStandardOutput(p); ThreadStandError t2 = new ThreadStandError(p); Thread thread1 = new Thread(new ThreadStart(t1.Read)); Thread thread2 = new Thread(new ThreadStart(t2.Read)); thread1.Start(); thread2.Start(); StreamReader reader = p.StandardOutput; string line = reader.ReadLine();//每次读取一行 while (!reader.EndOfStream) { richTextBox1.AppendText(line + " "); MessageBox.Show(line); richTextBox1.AppendText("\n"); line = reader.ReadLine(); } p.WaitForExit();//等待程序执行完退出进程 p.Close();//关闭进程 MessageBox.Show("导入成功", "提示信息"); } catch (Exception ex) { MessageBox.Show(ex.Message, "提示信息"); } } /// <summary> /// ThreadStandardOutput /// </summary> class ThreadStandardOutput { Process p; public ThreadStandardOutput(Process p) { this.p = p; } public void Read() { int a = -1; while ((a = p.StandardOutput.Read()) > 0) { //File.AppendAllText(AppDomain.CurrentDomain.BaseDirectory + "implog.txt", ((char)a).ToString()); } Thread.CurrentThread.Abort(); } } /// <summary> /// ThreadStandError /// </summary> class ThreadStandError { Process p; public ThreadStandError(Process p) { this.p = p; } public void Read() { int a = -1; while ((a = p.StandardError.Read()) > 0) { //File.AppendAllText(AppDomain.CurrentDomain.BaseDirectory + "implog.txt", ((char)a).ToString()); } Thread.CurrentThread.Abort(); } }
input.bat 内容:
imp testUser/123@ORCL buffer=10000000 full=y file=C:\sfsb_7_29.dmp log=C:\sfsb_7_29imp.txt
Insert.bat 内容:
sqlplus testuser/123@orcl11 '@c:\Insert.sql','@c:\Insert.sql'
Insert.Sql 内容
insert into testtab(Userid,username) values('user1','用户1');
insert into testtab(Userid,username) values('user2','用户2');
commit;
浙公网安备 33010602011771号