Windows Restore Service必须等待整个过程完成吗?

时间:2019-06-03 20:06:04

标签: c# .net windows-services

我正在使用Windows服务,该服务将在特定文件夹中查找备份文件。找到新的备份文件后,该服务将从该位置移走所有备份文件,并将它们移至存档文件夹,然后还原数据库并在其中触发存储过程。

我以前使用过FileSystemWatcher,但是由于它在服务器上不起作用,所以我使用DirectoryInfo查找文件。

以下是流程:

using System.Collections.Generic;
using System.Data;
using System.ServiceProcess;
using System.IO;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Common;
using System.Data.SqlClient;
using System.Configuration;
using System.Net.Configuration;
using System;
using System.Linq;
using System.Net.Mail;
using System.Timers;
using System.Threading;

namespace DashboardDataRefresh
{
    public partial class Service : ServiceBase
    {


        /// <summary>
        /// Component initializer.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="LinkLabelLinkClickedEventArgs"/> instance containing the event data.</param>
        public Service()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Component initializer. What Happens when the Service starts.
        /// </summary>
        protected override void OnStart(string[] args)
        {

            DirectoryInfo dir = new DirectoryInfo(backupdirectory);
            try
            {

            // Determine whether the dirrectory exists.
            if (!dir.Exists)
            {
                // Indicate that the dirrectory already exists.
            }

            // Move all the Backup files to Processed folder at certain intervals.
            createOrderTimer = new System.Timers.Timer();
            createOrderTimer.Elapsed += CreateOrderTimer_Elapsed;
            createOrderTimer.Interval = TimeSpan.FromMinutes(5).TotalMilliseconds; // 5 min
            MoveToProcessed(processed);
            createOrderTimer.Enabled = true;
            createOrderTimer.AutoReset = true;

            }
            catch (Exception e)
            {
                // Catch Ex
            }


        }

        /// <summary>
        /// Elapsed event handler calls our other method
        /// </summary>
        private void CreateOrderTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {

            MoveToProcessed(processed);

        }

        /// <summary>
        /// Copy all the backup files to Processed folder.
        /// </summary>
        private void MoveToProcessed(string processed)
        {
            string pattern = "*.bak";
            DirectoryInfo dirTarget = new DirectoryInfo(processed);
            DirectoryInfo dirSource = new DirectoryInfo(backupdirectory);
            try {

            foreach (FileInfo file in dirSource.GetFiles(pattern))
            {
                file.MoveTo(Path.Combine(dirTarget.ToString(), file.Name));
            }

            var Latestfile = (from f in dirTarget.GetFiles(pattern) orderby f.LastWriteTime descending select f).First();

            // Restore Begins.
            RestoreDatabase(Latestfile.FullName);

            }
            catch(Exception e)
            {
                // Catch Ex.
            }


        }

        /// <summary>
        /// Restore Database.
        /// </summary>
        private void RestoreDatabase(string latestFile)
        {
            string db_name = ConfigurationManager.AppSettings["database"];
            string server_name = ConfigurationManager.AppSettings["serverName"];
            string user_name = ConfigurationManager.AppSettings["userName"];
            string password = ConfigurationManager.AppSettings["password"];

            String _sp_connectionString =   "Server=" + ConfigurationManager.AppSettings["sp_serverName"] + 
                            ";DataBase=" + ConfigurationManager.AppSettings["sp_database"] + 
                            ";User Id=" + ConfigurationManager.AppSettings["sp_userName"] + 
                            ";Password=" + ConfigurationManager.AppSettings["sp_password"];


            try
            {


                Restore sqlRestore = new Restore();
                BackupDeviceItem deviceItem = new BackupDeviceItem(latestFile, DeviceType.File);
                sqlRestore.Devices.Add(deviceItem);
                sqlRestore.Database = db_name;

                ServerConnection connection = new ServerConnection(server_name, user_name, password);
                Server sqlServer = new Server(connection);

                Database db = sqlServer.Databases[db_name];
                sqlRestore.Action = RestoreActionType.Database;
                db = sqlServer.Databases[db_name];

                sqlRestore.ReplaceDatabase = true;

                // Restoration in process. The Database is Restored at a Default location. Under the DATA Folder.
                sqlRestore.SqlRestore(sqlServer);
                db = sqlServer.Databases[db_name];
                db.SetOnline();
                sqlServer.Refresh();

                // Calling SP.  
                InvokeSP(_sp_connectionString);

            }
            catch (Exception e)
            {
                // Catch Ex.
            }
        }

        /// <summary>
        /// Invokes SP from other Database after restore is complete.
        /// </summary>
        private void InvokeSP(string connStr)
        {
            SqlConnection conn = new SqlConnection(connStr);

            try
            {

                conn.Open();

                //1. Create a command object identifying the stored procedure.
                SqlCommand cmd = new SqlCommand(ConfigurationManager.AppSettings["storedProdcedure"], conn);
                cmd.CommandTimeout = 0;
                // 2. set the command object so it knows to execute a stored procedure.
                cmd.CommandType = CommandType.StoredProcedure;

                // Add a check here as well.
                // execute the command.
                SqlDataReader rdr = cmd.ExecuteReader();


                // Since we are not using - using block we have to explicitly call Close() to close the connection.
                conn.Close();
            }
            catch (SqlException SqlEx)
            {
                // Catch Ex.
            }
            finally
            {
                conn.Close();
            }


        }

    }
}

我的问题是,如何仅在完成存储过程执行后才寻找新文件,这是过程的最后一步。

0 个答案:

没有答案