public JsonResult BackupSelect(string toPath)
        {
            List <EnvDetail> envPathList = PublishModel.ReadServerCsv();

            EnvDetail envPath = envPathList.Find(r => r.ToPath == toPath);

            List <BackupPathDetail> backupPathList = null;

            // selectIndexに当てはまる商材の情報がない場合、nullを返す
            if (envPath != null)
            {
                string backupDirectory = ConfigurationManager.AppSettings["BackupDirectory"];

                // 発行先(toPath)の最後のディレクトリ名 = 現在のインスタンスの名前を取得
                string toDirectory = new DirectoryInfo(envPath.ToPath).Name;

                // バックアップ先のパス
                string backupPath = backupDirectory + toDirectory;

                // ディレクトリが存在する場合、ディレクトリ一覧を取得する
                if (Directory.Exists(backupPath))
                {
                    backupPathList = new List <BackupPathDetail>();

                    DirectoryInfo backupDir = new DirectoryInfo(backupPath);

                    int count = 1;
                    foreach (DirectoryInfo dir in backupDir.GetDirectories())
                    {
                        // ディレクトリ名が"LatestBackup"(ロールバック用の臨時バックアップ)の場合、表示しない
                        if (dir.Name != "LatestBackup")
                        {
                            BackupPathDetail bp = new BackupPathDetail();
                            bp.viewName     = dir.Name;
                            bp.value        = Convert.ToString(count);
                            bp.BackupPath   = backupPath + @"\" + dir.Name;
                            bp.CreationTime = dir.CreationTime;
                            backupPathList.Add(bp);
                            count++;
                        }
                    }

                    // フォルダの作成日付を基準にソート
                    backupPathList.Sort(CreationTimeComparer);
                }
            }
            // APIとして下記を設定してJsonで返す
            // JsonRequestBehavior.AllowGet > クライアントからの HTTP GET 要求を許可します。
            return(Json(backupPathList, JsonRequestBehavior.AllowGet));
        }
        /// <summary>
        /// 発行コントロール
        /// </summary>
        /// <param name="publishModel">publishMode to join.</param>
        /// <param name="guid">guid</param>
        /// <param name="productDivision">商材区分</param>
        /// <param name="backupDivision">バックアップ区分(バックアップ管理画面用)</param>
        /// <returns>publishMode</returns>
        private PublishModel PublishControl(PublishModel publishModel, string guid, string productDivision, string backupDivision)
        {
            // 多重起動を禁止する。
            string mutexName = "publish";

            System.Threading.Mutex mutex = null;
            // 商材詳細
            EnvDetail envDetail = null;
            // メッセージ
            string message = string.Empty;

            try
            {
                // 固有のmutexNameを持つmutexを呼び出す。
                mutex = System.Threading.Mutex.OpenExisting(mutexName);
            }
            catch (System.Threading.WaitHandleCannotBeOpenedException ex)
            {
                // 現在起動しているものがない場合、Exception発生するのが当たり前なので、このまま流す。
            }

            // mutexがnullか確認する。
            if ((mutex == null))
            {
                // mutexを生成する。
                mutex = new System.Threading.Mutex(true, mutexName);
            }
            else
            {
                // mutexがnullではない場合、現在起動中のものがあるという意味なのでエラーを返す。
                Logger.Info("多重起動エラー:ただいま発行処理を実施しているため、この処理は中止します。guid:" + guid);
                ModelState.AddModelError(string.Empty, "ただいま発行処理を実施しています。時間をおいて再度お試しください。");
                return(publishModel);
            }

            try
            {
                Logger.Info("### Start Publish ### -- guid:" + guid);

                // 入力フォームから渡された発行元と発行先の情報が正しいか確認(サーバー一覧から逆検索して確認)
                //EnvDetail serverDetail = null;
                foreach (EnvDetail server in PublishModel.ReadServerCsv())
                {
                    var serverValue = server.value.ToString().Split(',');
                    // 商材区分、発行元、発行先が一致するサーバー情報があるか確認
                    // バックアップからの発行の場合はFromPathは比較対象から外す
                    if (backupDivision == null &&
                        productDivision.Equals(serverValue[2]) &&
                        publishModel.FromPath.Equals(server.FromPath) &&
                        publishModel.ToPath.Equals(server.ToPath))
                    {
                        envDetail = server;
                        break;
                    }
                    else if (backupDivision != null &&
                             productDivision.Equals(serverValue[2]) &&
                             publishModel.ToPath.Equals(server.ToPath))
                    {
                        envDetail = server;
                        break;
                    }
                }

                // 商材の情報がある場合、発行処理を行う
                if (envDetail != null)
                {
                    // 商材区分に商材名と発行先のhttpHeadをに表示する
                    envDetail.viewName = envDetail.httpHeader + "|" + envDetail.viewName;

                    Logger.Info("発行を開始します。商材区分:" + envDetail.viewName);

                    // バックアップ区分がある場合(=バックアップからの発行の場合)
                    if (backupDivision != null)
                    {
                        // 選択したバックアップ元を発行元とする。
                        envDetail.FromPath = backupDivision;

                        // バックアップ元のディレクトリが存在する場合、エラーを返す。
                        if (!Directory.Exists(backupDivision))
                        {
                            // バックアップ元のディレクトリが存在しない場合、エラーを返す。
                            message = "選択したバックアップディレクトリが存在しません。再度お試しください。";
                            Logger.Info(message);
                            ModelState.AddModelError(string.Empty, message);
                            return(publishModel);
                        }
                    }

                    // 発行処理。PublishControlの処理結果がtrueの場合のみ、完了メッセージを返す。
                    // (PublishControlの結果がfalseの場合はエラー発生箇所で格納したエラーメッセージを表示する)

                    // 商材名
                    string productName = envDetail.viewName;
                    // 発行元(商材から選択した場合は【仮本番】になる)
                    string fromPath = envDetail.FromPath;
                    // 発行先(商材から選択した場合は【本番】になる)
                    string toPath = Common.GetDirectoryPath(envDetail.ToPath);

                    // 最新バックアップ(ロールバック時にはここでバックアップしたソースが元になる)
                    if (LatestBackup(productName, toPath))
                    {
                        // 発行
                        if (Publisher(productName, fromPath, toPath))
                        {
                            // バックアップ
                            if (Backup(productName, toPath))
                            {
                                // 発行元、発行先の情報を画面のフォームに返す
                                ModelState.SetModelValue("FromPath", new ValueProviderResult(envDetail.FromPath, envDetail.FromPath, null));
                                ModelState.SetModelValue("ToPath", new ValueProviderResult(envDetail.ToPath, envDetail.ToPath, null));

                                // 完了メッセージを返す
                                message = "発行が完了しました。商材区分:" + envDetail.viewName + "、発行元(From):" + envDetail.FromPath + "、発行先(To):" + envDetail.ToPath;
                                Logger.Info(message);
                                // メール送信
                                Common.SendMail(message, ": publish complete: " + envDetail.viewName);

                                ModelState.AddModelError(string.Empty, message);
                            }
                        }
                    }
                }
                else
                {
                    // 商材情報がない場合、エラーを返す。
                    message = "商材区分が正しくありません。";
                    Logger.Info(message);
                    ModelState.AddModelError(string.Empty, message);
                }

                Logger.Info("### End Publish ### -- guid:" + guid);
            }
            catch (Exception e)
            {
                message = "発行処理中にエラーが発生しました。";
                string subject = "";

                // 商材の情報がある場合、内容を表示する。
                if (envDetail != null)
                {
                    message += "商材区分:" + envDetail.viewName + "、発行元(From):" + envDetail.FromPath + "、発行先(To):" + envDetail.ToPath + "。";
                    subject  = envDetail.viewName;
                }

                // メール送信
                Common.SendMail(message, ": catch error: " + subject);

                Logger.Info(message + "StackTrace:" + e.StackTrace + "、message : " + e.Message);
                ModelState.AddModelError(string.Empty, message);
            }
            finally
            {
                // mutexを開放する(次の起動ok)
                mutex.Close();
            }

            return(publishModel);
        }