单车男

每天进步一点点,积累下来就不得了...
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

账套工具的总结

Posted on 2013-08-05 15:47  单车男  阅读(445)  评论(0编辑  收藏  举报
最近在写账套工具,写一些总结和体会。
 
1) 注册DLL,OCX
最简单的方法,直接使用Process.Start(cmd路径)来执行注册,其中cmd为可参考为如下
 
regsvr32 "C:\Program Files\Microsoft SQL Server\80\Tools\Binn\sqldmo.dll"
@echo off
echo 注册成功,谢谢您的使用!
Pause
 
2)复制文件夹路径
复制文件很简单,但是直接复制文件夹呢,就稍微麻烦些,因为毕竟微软没提供这样的API,所以只能自己写
 
参考了下网上有人提供的源代码,再稍微修改了下,其实思路很简单,就是用递归的方式,一层一层的复制,直到最后一层
 
    private void CopyDirectory(string srcdir, string desdir)
        {
            string folderName = srcdir.Substring(srcdir.LastIndexOf("\\") + 1);
            string desfolderdir = desdir + "\\" + folderName;
            if (desdir.LastIndexOf("\\") == (desdir.Length - 1))
            {
                desfolderdir = desdir + folderName;
            }
            string[] filenames = Directory.GetFileSystemEntries(srcdir);
            foreach (string file in filenames)     // 遍历所有的文件和目录
            {
                if (Directory.Exists(file))// 先当作目录处理如果存在这个目录就递归Copy该目录下面的文件
                {
                    string currentdir = desfolderdir + "\\" + file.Substring(file.LastIndexOf("\\") + 1);
                    if (!Directory.Exists(currentdir))
                    {
                        Directory.CreateDirectory(currentdir);
                    }
                    CopyDirectory(file, desfolderdir);
                }
                else // 否则直接copy文件
                {
                    string srcfileName = file.Substring(file.LastIndexOf("\\") + 1);
                    srcfileName = desfolderdir + "\\" + srcfileName;
 
                    if (!Directory.Exists(desfolderdir))  //已存在就不创建
                    {
                        Directory.CreateDirectory(desfolderdir);
                    }
                    File.Copy(file, srcfileName, true);  //覆盖
                }
            }
        }
 
3)  数据库备份,还原
方法1:利用SQLDMO方式,缺点是需要注册,SQLSERVER默认安装并不支持这个,注册可参考文件说明:
 
 
代码可参考:
            //备份
            SQLDMO.Backup oBackup = new SQLDMO.BackupClass();
            SQLDMO.SQLServer oSQLServer = new SQLDMO.SQLServerClass();
            try
            {
                oSQLServer.LoginSecure = false;
                oSQLServer.Connect(".", "sa", "a1~");//服务器名、账号、密码
                oBackup.Action = SQLDMO.SQLDMO_BACKUP_TYPE.SQLDMOBackup_Database;
                oBackup.Database = "b22";
                oBackup.Files = "[" + @"C:\123.bak" + "]";
                oBackup.BackupSetName = "b22";
                oBackup.BackupSetDescription = "数据库备份";
                oBackup.Initialize = true;
                oBackup.SQLBackup(oSQLServer);
             }
            catch
            {
                throw;
            }
            finally
            {
                oSQLServer.DisConnect();
            }
        
            //还原
            SQLDMO.Restore oRestore = new SQLDMO.RestoreClass();
            SQLDMO.SQLServer oSQLServer = new SQLDMO.SQLServerClass();
            try
            {
                oSQLServer.LoginSecure = false;
                oSQLServer.Connect(".", "sa", "a1~");
                oRestore.Action = SQLDMO.SQLDMO_RESTORE_TYPE.SQLDMORestore_Database;
                oRestore.Database = "b22_bb";
                oRestore.Files = @"D:\temp\123.bak";
                oRestore.RelocateFiles = "fzdrp," +
                        @"[D:\temp\123.mdf]," +
                        "fzdrp_log," +
                        @"[D:\temp\123.ldf],";
                oRestore.FileNumber = 1;
                oRestore.ReplaceDatabase = true;
                oRestore.SQLRestore(oSQLServer);
            }
            catch
            {
                throw;
            }
            finally
            {
                oSQLServer.DisConnect();
            }
优点:比较对象化,方便,缺点非本机备份还原,相对麻烦(我也没研究过非本机的,因客户要求,只是在数据库服务器上操作)
 
方法2:利用SQLSERVER自己的SQL命令,也算比较简单,有一些附加命令可用,以下列出最简单的DEMO
 
--备份
backup database test to disk='d:\temp\b22.bak'
 
--恢复
use master
go
 
ALTER DATABASE B22 SET OFFLINE  --目的是杀掉其他连接,强制脱机
restore database b22 from disk='d:\temp\b22.bak'
 
4) 升级数据库
 
方法一:这个是最折腾人的,我当时利用process来启动osql.exe进程来执行。在网上找了很多资料,大概调用如下:
 
            Process osqlProcess = new Process();
            osqlProcess.StartInfo.FileName = "osql.exe";
            string sqlpath =  System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"updatesql.sql") ;
            osqlProcess.StartInfo.Arguments = String.Format("  -U {0}   -P {1}   -S {2}   -d {3}   -i {4} -b", "sa", "a1~", "LJUN", "b22", sqlpath);
            osqlProcess.StartInfo.UseShellExecute = false;
            osqlProcess.StartInfo.RedirectStandardOutput = true;  //重定向输出
            osqlProcess.StartInfo.CreateNoWindow = true;
 
            osqlProcess.Start();  //执行输出
            //osqlProcess.StandardOutput.ReadToEnd();  //加上后若在小文件执行时,发生错误没有输出值;没有则在大文件执行时却会被停止,加与不加根据实际情况考虑
            osqlProcess.WaitForExit();
            int code = osqlProcess.ExitCode;
            StreamReader sr = osqlProcess.StandardOutput;
 
             //升级失败
            if (code != 0)
            {
                MessageBox.Show("脚本执行失败,关闭后可查看日志了解详情!");
                string strMsg = sr.ReadToEnd();
                string filepath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"err.txt");
                StreamWriter sw = new StreamWriter(filepath);
                sw.Write(strMsg);
                sw.Flush();
                sw.Close();
                sw.Dispose();
                Process.Start(filepath);
            }
            else {
                MessageBox.Show("执行成功!");
            }
            osqlProcess.Close();
            sr.Close();
            sr.Dispose();
 
最扯蛋的就是中间注释成红色的这段,加上后若在小文件执行时,发生错误没有输出值;如不加则在大文件执行时却会被停止,进程处于死锁状态。查了很多资料,才发现这篇文章,给大家分享: http://www.cnblogs.com/angus332770349/archive/2012/06/15/2550247.html ,看来加与不加根据实际情况考虑。
 
方法二: 直接将上面的osql.exe 替换成sqlcmd.exe,因为调用一样,所以其他不变,经测试,并不出现上述的问题,看来问题完美解决,然后又查了一些资料,关于osql.exe,sqlcmd.exe,还有isql.exe,得出结论
 
这3个工具使用了不同的SQL连接部件,sqlcmd用在sql 2005或更高版本,因为性能更好;osql 主要用于sql 7.0和sql 2000;isql主要用于sql 6.5及更早的版本!所以当可以使用sqlcmd时,优先选择这个
 
5) 重启SQL服务
 
方法1: 写入一个cmd文件来重启,用Process.Start来调用,cmd文件命令如下
 
net stop mssqlserver
net start mssqlserver
@echo off
echo 重启服务成功!
Pause
 
方法2: C#代码,直接来对MSSQLSERVER的服务进行入手,先停止,再启用服务
 
            ServiceController sc = new ServiceController("MSSQLSERVER");  //重启A-B服务
            sc.Stop();
            sc.WaitForStatus(ServiceControllerStatus.Stopped);
            sc.Start();
            sc.WaitForStatus(ServiceControllerStatus.Running);
            sc.Close();
            sc.Dispose();
 
6) 禁用IIS服务
 
同样也有如上两种方式,不过第1种我没试成功,win7下好像不行,win2003是可以的!第2种比较好
 
方法1:直接关闭iisadmin服务
 
            ServiceController sc = new ServiceController("iisadmin");
            sc.Stop();
            sc.WaitForStatus(ServiceControllerStatus.Stopped);
 
 
方法2:利用进程启动cmd方式
 
            Process cmdProcess = new Process();
            cmdProcess.StartInfo.FileName = "cmd.exe";    
            cmdProcess.StartInfo.Arguments = "net stop w3svc";
            cmdProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            cmdProcess.Start();
            cmdProcess.WaitForExit();
            cmdProcess.Close();
 
 -------------------------------------------------华丽的分割线---------------------------------------------------------------------------
 
随笔记录,LZ比较懒,大家凑合看看,格式就懒得调了,原创文章,转载请注明.....
 
----------------------------------------------------------------------------------------------------------------------------------------