public ResolveConflictWhenCommitForm(CommitCompareResult compareResult, CommitExcelInfo localExcelInfo, CommitExcelInfo svnExcelInfo) { InitializeComponent(); // 记录各对比类型功能区所包含的控件 _partControls = new Dictionary <string, _PartControls>(); // 主语言译文不同功能区 _PartControls diffInfoPartControls = new _PartControls(); diffInfoPartControls.PartName = _PART_NAME_DIFF_INFO; diffInfoPartControls.DataGridView = dgvDiffDefaultLanguageInfo; diffInfoPartControls.ComboBox = cmbDiffInfoUnifiedResolveConflictWay; diffInfoPartControls.CheckBox = chkDiffInfoIgnoreSvnRevisionChange; _partControls.Add(_PART_NAME_DIFF_INFO, diffInfoPartControls); // 本地表新增Key功能区 _PartControls localAddKeyPartControls = new _PartControls(); localAddKeyPartControls.PartName = _PART_NAME_LOCAL_ADD_KEY; localAddKeyPartControls.DataGridView = dgvLocalAddKeyInfo; localAddKeyPartControls.ComboBox = cmbLocalAddKeyInfoUnifiedResolveConflictWay; localAddKeyPartControls.CheckBox = chkLocalAddKeyInfoIgnoreSvnRevisionChange; _partControls.Add(_PART_NAME_LOCAL_ADD_KEY, localAddKeyPartControls); // SVN表新增Key功能区 _PartControls svnAddKeyPartControls = new _PartControls(); svnAddKeyPartControls.PartName = _PART_NAME_SVN_ADD_KEY; svnAddKeyPartControls.DataGridView = dgvSvnAddKeyInfo; svnAddKeyPartControls.ComboBox = cmbSvnAddKeyInfoUnifiedResolveConflictWay; svnAddKeyPartControls.CheckBox = chkSvnAddKeyInfoIgnoreSvnRevisionChange; _partControls.Add(_PART_NAME_SVN_ADD_KEY, svnAddKeyPartControls); // 设置用于统一处理差异处理方式的ComboBox选项 foreach (_PartControls onePartControls in _partControls.Values) { // 设置选项内容 onePartControls.ComboBox.Items.AddRange(AppValues.RESOLVE_COMMIT_DIFF_WAYS); // 绑定点击响应事件 onePartControls.ComboBox.SelectedIndexChanged += _OnChangedUnifiedResolveConflictWay; } // 设置用于让用户选择每条差异处理方式的DataGridViewComboBoxColumn选项 foreach (_PartControls onePartControls in _partControls.Values) { DataGridViewComboBoxColumn comboBoxColumn = onePartControls.DataGridView.Columns[onePartControls.PartName + _RESOLVE_CONFLICT_WAY_COLUMN_NAME] as DataGridViewComboBoxColumn; comboBoxColumn.Items.AddRange(AppValues.RESOLVE_COMMIT_DIFF_WAYS); } _localExcelInfo = localExcelInfo; _lastSvnExcelInfo = svnExcelInfo; _newestSvnExcelInfo = svnExcelInfo; _compareResult = compareResult; _InitDataGridView(compareResult); }
// 点击“提交”按钮 private void btnCommit_Click(object sender, EventArgs e) { // 判断是否填写了提交所需的LogMessage信息 string logMessage = txtCommitLogMessage.Text.Trim(); if (string.IsNullOrEmpty(logMessage)) { MessageBox.Show("执行SVN提交操作时必须填写说明信息", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // 记录用户是否选择了至少一处需要合并到SVN中的差异内容 bool isChooseCommitChange = false; // 记录未对主语言译文不同的差异条目进行处理方式选择的编号 List <int> unresolvedDiffInfoNum = new List <int>(); // 记录未对本地表新增Key条目进行处理方式选择的编号 List <int> unresolvedLocalAddKeyNum = new List <int>(); // 记录未对SVN表新增Key条目进行处理方式选择的编号 List <int> unresolvedSvnAddKeyNum = new List <int>(); // 记录要进行提交的差异项 CommitCompareResult commitCompareResult = new CommitCompareResult(); // 检查用户是否对每一条差异都选择了处理方式 // 主语言译文不同 const string PART_DIFF_INFO_RESOLVE_CONFLICT_WAY_COLUMN_NAME = _PART_NAME_DIFF_INFO + _RESOLVE_CONFLICT_WAY_COLUMN_NAME; int diffInfoCount = _compareResult.DiffInfo.Count; for (int i = 0; i < diffInfoCount; ++i) { CommitDifferentDefaultLanguageInfo oneDiffInfo = _compareResult.DiffInfo[i]; string selectedValue = _partControls[_PART_NAME_DIFF_INFO].DataGridView.Rows[i].Cells[PART_DIFF_INFO_RESOLVE_CONFLICT_WAY_COLUMN_NAME].Value as string; if (AppValues.RESOLVE_COMMIT_DIFF_WAYS[0].Equals(selectedValue)) { oneDiffInfo.ResolveConflictWay = ResolveConflictWays.UseLocal; commitCompareResult.DiffInfo.Add(oneDiffInfo); isChooseCommitChange = true; } else if (AppValues.RESOLVE_COMMIT_DIFF_WAYS[1].Equals(selectedValue)) { oneDiffInfo.ResolveConflictWay = ResolveConflictWays.UseSvn; } else { oneDiffInfo.ResolveConflictWay = ResolveConflictWays.NotChoose; int num = i + 1; unresolvedDiffInfoNum.Add(num); } } // 本地表新增Key const string PART_LOCAL_ADD_KEY_RESOLVE_CONFLICT_WAY_COLUMN_NAME = _PART_NAME_LOCAL_ADD_KEY + _RESOLVE_CONFLICT_WAY_COLUMN_NAME; int localAddKeyCount = _compareResult.LocalAddKeyInfo.Count; for (int i = 0; i < localAddKeyCount; ++i) { CommitDifferentKeyInfo oneLocalAddKey = _compareResult.LocalAddKeyInfo[i]; string selectedValue = _partControls[_PART_NAME_LOCAL_ADD_KEY].DataGridView.Rows[i].Cells[PART_LOCAL_ADD_KEY_RESOLVE_CONFLICT_WAY_COLUMN_NAME].Value as string; if (AppValues.RESOLVE_COMMIT_DIFF_WAYS[0].Equals(selectedValue)) { oneLocalAddKey.ResolveConflictWay = ResolveConflictWays.UseLocal; commitCompareResult.LocalAddKeyInfo.Add(oneLocalAddKey); isChooseCommitChange = true; } else if (AppValues.RESOLVE_COMMIT_DIFF_WAYS[1].Equals(selectedValue)) { oneLocalAddKey.ResolveConflictWay = ResolveConflictWays.UseSvn; } else { oneLocalAddKey.ResolveConflictWay = ResolveConflictWays.NotChoose; int num = i + 1; unresolvedLocalAddKeyNum.Add(num); } } // SVN表新增Key const string PART_SVN_ADD_KEY_RESOLVE_CONFLICT_WAY_COLUMN_NAME = _PART_NAME_SVN_ADD_KEY + _RESOLVE_CONFLICT_WAY_COLUMN_NAME; int svnAddKeyCount = _compareResult.SvnAddKeyInfo.Count; for (int i = 0; i < svnAddKeyCount; ++i) { CommitDifferentKeyInfo oneSvnAddKey = _compareResult.SvnAddKeyInfo[i]; string selectedValue = _partControls[_PART_NAME_SVN_ADD_KEY].DataGridView.Rows[i].Cells[PART_SVN_ADD_KEY_RESOLVE_CONFLICT_WAY_COLUMN_NAME].Value as string; if (AppValues.RESOLVE_COMMIT_DIFF_WAYS[0].Equals(selectedValue)) { oneSvnAddKey.ResolveConflictWay = ResolveConflictWays.UseLocal; commitCompareResult.SvnAddKeyInfo.Add(oneSvnAddKey); isChooseCommitChange = true; } else if (AppValues.RESOLVE_COMMIT_DIFF_WAYS[1].Equals(selectedValue)) { oneSvnAddKey.ResolveConflictWay = ResolveConflictWays.UseSvn; } else { oneSvnAddKey.ResolveConflictWay = ResolveConflictWays.NotChoose; int num = i + 1; unresolvedSvnAddKeyNum.Add(num); } } StringBuilder unresolvedConflictStringBuilder = new StringBuilder(); if (unresolvedDiffInfoNum.Count > 0) { unresolvedConflictStringBuilder.Append("主语言译文不同的差异条目中,以下编号的行未选择处理方式:"); unresolvedConflictStringBuilder.AppendLine(Utils.CombineString <int>(unresolvedDiffInfoNum, ",")); } if (unresolvedLocalAddKeyNum.Count > 0) { unresolvedConflictStringBuilder.Append("本地表新增Key的差异条目中,以下编号的行未选择处理方式:"); unresolvedConflictStringBuilder.AppendLine(Utils.CombineString <int>(unresolvedLocalAddKeyNum, ",")); } if (unresolvedSvnAddKeyNum.Count > 0) { unresolvedConflictStringBuilder.Append("SVN表新增Key的差异条目中,以下编号的行未选择处理方式:"); unresolvedConflictStringBuilder.AppendLine(Utils.CombineString <int>(unresolvedSvnAddKeyNum, ",")); } string unresolvedConflictString = unresolvedConflictStringBuilder.ToString(); if (!string.IsNullOrEmpty(unresolvedConflictString)) { MessageBox.Show(string.Concat("存在以下未选择处理方式的差异条目,请全部选择处理方式后重试\n\n", unresolvedConflictString), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // 判断用户是否选择了至少一处需要合并到SVN中的差异内容 if (isChooseCommitChange == false) { MessageBox.Show("未选择将任一差异提交到SVN表,无需进行提交操作", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } // 即将提交时判断此时SVN中最新版本号是否还是进入此界面时与本地表对比的版本号,如果不是需要重新对比 SvnException svnException = null; SvnInfoEventArgs svnFileInfo = OperateSvnHelper.GetSvnFileInfo(AppValues.SvnExcelFilePath, out svnException); if (svnException == null) { // 若此时SVN最新版本仍旧为之前与之对比的版本,则根据用户选择将结果合并到最新SVN母表副本中然后上传 if (svnFileInfo.LastChangeRevision == _compareResult.SvnFileRevision) { string errorString = null; string mergedExcelFilePath = CommitExcelFileHelper.GenerateCommitExcelFile(_compareResult, _localExcelInfo, _newestSvnExcelInfo, out errorString); if (errorString != null) { MessageBox.Show(string.Format("生成合并之后的Excel母表文件失败,错误原因为:{0}\n\n提交操作被迫中止", errorString), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // 进行SVN提交操作(将本地Working Copy文件备份至本工具所在路径,然后用合并后的Excel母表替换Working Copy文件后执行SVN提交操作) string backupFilePath = Utils.CombinePath(AppValues.PROGRAM_FOLDER_PATH, string.Format("备份自己修改的本地表 {0:yyyy年MM月dd日 HH时mm分ss秒} 对应SVN版本号{1}.xlsx", DateTime.Now, _localExcelInfo.Revision)); try { File.Copy(AppValues.LocalExcelFilePath, backupFilePath, true); } catch (Exception exception) { MessageBox.Show(string.Format("自动备份本地表至本工具所在路径失败,错误原因为:{0}\n\n为了防止因不备份导致自己编辑的原始本地表丢失,提交SVN操作被迫中止", exception.ToString()), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // 因为SVN提交文件需要在同一版本号下进行且SVN无法在Update时对Excel进行Merge操作,则如果本地表的版本号低于SVN最新版本,必须将本地表执行Revert和Update操作后才可以提交 if (_compareResult.LocalFileRevision != _compareResult.SvnFileRevision) { // Revert操作 bool revertResult = OperateSvnHelper.Revert(AppValues.LocalExcelFilePath, out svnException); if (svnException == null) { if (revertResult == false) { MessageBox.Show("因本地表版本不是SVN中最新的,必须执行Revert以及Update操作后才可以提交\n但因为Revert失败,提交SVN操作被迫中止", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } else { MessageBox.Show(string.Format("因本地表版本不是SVN中最新的,必须执行Revert以及Update操作后才可以提交\n但因为Revert失败,错误原因为:{0}\n提交SVN操作被迫中止", svnException.Message), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // Update操作 bool updateResult = OperateSvnHelper.Update(AppValues.LocalExcelFilePath, out svnException); if (svnException == null) { if (updateResult == false) { MessageBox.Show("因本地表版本不是SVN中最新的,必须执行Revert以及Update操作后才可以提交\n但因为Update失败,提交SVN操作被迫中止", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } else { if (svnException is SvnAuthorizationException || svnException is SvnOperationCanceledException) { MessageBox.Show("因本地表版本不是SVN中最新的,必须执行Revert以及Update操作后才可以提交\n但因为没有权限进行Update操作,提交SVN操作被迫中止,请输入合法的SVN账户信息后重试", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } else { MessageBox.Show(string.Format("因本地表版本不是SVN中最新的,必须执行Revert以及Update操作后才可以提交\n但因为Update失败,错误原因为:{0}\n提交SVN操作被迫中止", svnException.Message), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } } // 用合并后的Excel文件覆盖掉原有的本地表 try { File.Copy(mergedExcelFilePath, AppValues.LocalExcelFilePath, true); } catch (Exception exception) { MessageBox.Show(string.Format("将合并后的Excel母表覆盖到本地表所在路径失败,错误原因为:{0}\n\n提交SVN操作被迫中止", exception), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // 执行提交操作 bool commitResult = OperateSvnHelper.Commit(AppValues.LocalExcelFilePath, logMessage, out svnException); if (svnException == null) { if (commitResult == false) { MessageBox.Show("执行提交操作失败", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } else { MessageBox.Show(string.Concat("执行提交操作成功\n\n自己修改的原始本地表备份至:", backupFilePath), "恭喜", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } } else { MessageBox.Show(string.Format("执行提交操作失败,错误原因为:{0}\n\n请修正错误后重试", svnException.RootCause.Message), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } else { MessageBox.Show(string.Format("很遗憾,在提交时发现了更新的SVN表的版本({0}),需要重新对比与新表的差异(本次新发现的差异项会将“编号”列的单元格背景调为橙色突出显示)然后选择处理方式后再提交\n\n但之前已选择的差异项的处理方式将被保留,直接在下拉列表中默认选中刚才你选择的处理方式\n\n注意:在展示主语言不同(第1个表格)以及SVN表新增Key(第2个表格)的表格中,若两次SVN表主语言译文发生变动,会将“SVN表主语言译文”列的单元格背景调为橙色突出显示", svnFileInfo.LastChangeRevision), "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning); // 需要下载SVN最新版本表与本地表进行对比 string svnNewRevisionCopySavePath = Utils.CombinePath(AppValues.PROGRAM_FOLDER_PATH, string.Format("SVN最新母表副本 {0:yyyy年MM月dd日 HH时mm分ss秒} 对应SVN版本号{1}.xlsx", DateTime.Now, svnFileInfo.LastChangeRevision)); Exception exportException; bool result = OperateSvnHelper.ExportSvnFileToLocal(AppValues.SvnExcelFilePath, svnNewRevisionCopySavePath, svnFileInfo.LastChangeRevision, out exportException); if (exportException != null) { MessageBox.Show(string.Format("下载SVN中最新版本号({0})的母表文件存到本地失败,错误原因为:{1}", svnFileInfo.LastChangeRevision, exportException.Message), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); this.Close(); return; } else if (result == false) { MessageBox.Show(string.Format("下载SVN中最新版本号({0})的母表文件存到本地失败", svnFileInfo.LastChangeRevision), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); this.Close(); return; } // 解析SVN中最新的母表文件 string errorString; CommitExcelInfo newRevisionExcelInfo = CommitExcelFileHelper.AnalyzeCommitExcelFile(svnNewRevisionCopySavePath, AppValues.CommentLineStartChar, svnFileInfo.LastChangeRevision, out errorString); if (errorString != null) { MessageBox.Show(string.Format("下载的SVN中最新版本号({0})的母表文件存在以下错误,请修正后重试\n\n{1}", svnFileInfo.LastChangeRevision, errorString), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); this.Close(); return; } _newestSvnExcelInfo = newRevisionExcelInfo; // 对比本地表与SVN中最新母表文件 CommitCompareResult newCompareResult = CommitExcelFileHelper.CompareCommitExcelFile(_localExcelInfo, newRevisionExcelInfo); // 如果最新的SVN中母表与本地表反而没有任何差异,则无需提交 if (newCompareResult.IsHasDiff() == false) { _compareResult = newCompareResult; // 清空DataGridView中的内容 _CleanDataGridView(); // 更新SVN版本号显示 txtSvnFileRevision.Text = svnFileInfo.LastChangeRevision.ToString(); txtSvnFileRevision.BackColor = Color.Orange; MessageBox.Show("经对比发现本地母表与SVN中最新版本内容完全相同,无需进行提交操作", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } _RefreshDataGridView(newCompareResult); } } else { MessageBox.Show(string.Format("无法获取SVN中最新母表信息,错误原因为:{0}\n\n提交操作被迫中止", svnException.Message), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } }
// 用刚进入此界面时的对比结果初始化DataGridView中的数据 private void _InitDataGridView(CommitCompareResult compareResult) { // 本地表以及SVN表的版本号 txtLocalFileRevision.Text = compareResult.LocalFileRevision.ToString(); txtSvnFileRevision.Text = compareResult.SvnFileRevision.ToString(); bool isSameRevision = (compareResult.LocalFileRevision == compareResult.SvnFileRevision); // 若版本号相同,SVN表版本号TextBox背景色设为绿色否则为橙色 if (isSameRevision == true) { txtSvnFileRevision.BackColor = Color.LightGreen; } else { txtSvnFileRevision.BackColor = Color.Orange; } // 若版本号不同,每个DataGridView中倒数第2列显示“版本变动”列,否则不显示 _ShowIsChangedBySvnRevisionColumn(isSameRevision == false); // 如果版本号不同,需要下载SVN中与本地表相同版本号的母表文件与本地表进行对比 CommitCompareResult compareSameRevisionResult = null; if (isSameRevision == false) { // 下载SVN中与本地表相同版本号的母表 string svnSameRevisionCopySavePath = Utils.CombinePath(AppValues.PROGRAM_FOLDER_PATH, string.Format("SVN母表副本 {0:yyyy年MM月dd日 HH时mm分ss秒} 对应SVN版本号{1}.xlsx", DateTime.Now, compareResult.LocalFileRevision)); Exception exportException; bool result = OperateSvnHelper.ExportSvnFileToLocal(AppValues.SvnExcelFilePath, svnSameRevisionCopySavePath, compareResult.LocalFileRevision, out exportException); if (exportException != null) { MessageBox.Show(string.Format("下载SVN中与本地表相同版本号({0})的母表文件存到本地失败,错误原因为:{1}", compareResult.LocalFileRevision, exportException.Message), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); this.Close(); return; } else if (result == false) { MessageBox.Show(string.Format("下载SVN中与本地表相同版本号({0})的母表文件存到本地失败", compareResult.LocalFileRevision), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); this.Close(); return; } // 解析SVN中与本地表相同版本号的母表 string errorString; CommitExcelInfo svnSameRevisionExcelInfo = CommitExcelFileHelper.AnalyzeCommitExcelFile(svnSameRevisionCopySavePath, AppValues.CommentLineStartChar, compareResult.LocalFileRevision, out errorString); if (errorString != null) { MessageBox.Show(string.Format("下载的SVN中与本地表相同版本号({0})的母表文件存在以下错误,请修正后重试\n\n{1}", compareResult.LocalFileRevision, errorString), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); this.Close(); return; } _svnSameRevisionExcelInfo = svnSameRevisionExcelInfo; // 对比两文件 compareSameRevisionResult = CommitExcelFileHelper.CompareCommitExcelFile(_localExcelInfo, svnSameRevisionExcelInfo); } else { _svnSameRevisionExcelInfo = _lastSvnExcelInfo; } // Key相同但主语言译文不同的信息 const string PART_DIFF_INFO_RESOLVE_CONFLICT_WAY_COLUMN_NAME = _PART_NAME_DIFF_INFO + _RESOLVE_CONFLICT_WAY_COLUMN_NAME; const string PART_DIFF_INFO_IS_CHANGED_BY_SVN_REVISION_COLUMN_NAME = _PART_NAME_DIFF_INFO + _IS_CHANGED_BY_SVN_REVISION_COLUMN_NAME; int diffInfoCount = compareResult.DiffInfo.Count; for (int i = 0; i < diffInfoCount; ++i) { CommitDifferentDefaultLanguageInfo oneDiffInfo = compareResult.DiffInfo[i]; List <object> showDataList = new List <object>(); // 编号 showDataList.Add(i + 1); // Key showDataList.Add(oneDiffInfo.Key); // 本地表主语言译文 showDataList.Add(oneDiffInfo.LocalFileDefaultLanguageValue); // SVN表主语言译文 showDataList.Add(oneDiffInfo.SvnFileDefaultLanguageValue); // 本地表行号 showDataList.Add(oneDiffInfo.LocalFileLineNum); // SVN表行号 showDataList.Add(oneDiffInfo.SvnFileLineNum); // 版本变动 bool isChangedBySvnRevision = false; if (isSameRevision == false) { // 判断此差异是否为SVN中两版本本身存在的差异,如本地表与同版本SVN表相同,但与最新SVN表不同,则说明该项差异来自SVN版本的变动 if (_svnSameRevisionExcelInfo.Keys.Contains(oneDiffInfo.Key) && _localExcelInfo.GetDataByKey(oneDiffInfo.Key).Equals(_svnSameRevisionExcelInfo.GetDataByKey(oneDiffInfo.Key))) { isChangedBySvnRevision = true; } showDataList.Add(isChangedBySvnRevision == true ? "是" : string.Empty); } DataGridView dataGridView = _partControls[_PART_NAME_DIFF_INFO].DataGridView; int index = dataGridView.Rows.Add(showDataList.ToArray()); // 如果差异来自SVN版本的变动,则“版本变动”列的单元格背景色变为浅灰色,并默认将“处理方式”的ComboBox选择为“使用SVN表” if (isChangedBySvnRevision == true) { dataGridView.Rows[index].Cells[PART_DIFF_INFO_IS_CHANGED_BY_SVN_REVISION_COLUMN_NAME].Style.BackColor = Color.LightGray; dataGridView.Rows[index].Cells[PART_DIFF_INFO_RESOLVE_CONFLICT_WAY_COLUMN_NAME].Value = AppValues.RESOLVE_COMMIT_DIFF_WAYS[1]; } } // 本地表新增Key信息(本地表含有但最新SVN表中没有某个Key) const string PART_LOCAL_ADD_KEY_RESOLVE_CONFLICT_WAY_COLUMN_NAME = _PART_NAME_LOCAL_ADD_KEY + _RESOLVE_CONFLICT_WAY_COLUMN_NAME; const string PART_LOCAL_ADD_KEY_IS_CHANGED_BY_SVN_REVISION_COLUMN_NAME = _PART_NAME_LOCAL_ADD_KEY + _IS_CHANGED_BY_SVN_REVISION_COLUMN_NAME; int localAddKeyCount = compareResult.LocalAddKeyInfo.Count; for (int i = 0; i < localAddKeyCount; ++i) { CommitDifferentKeyInfo oneLocalAddKeyInfo = compareResult.LocalAddKeyInfo[i]; List <object> showDataList = new List <object>(); // 编号 showDataList.Add(i + 1); // Key showDataList.Add(oneLocalAddKeyInfo.Key); // 本地表主语言译文 showDataList.Add(oneLocalAddKeyInfo.DefaultLanguageValue); // 本地表行号 showDataList.Add(oneLocalAddKeyInfo.ExcelLineNum); // 版本变动 bool isChangedBySvnRevision = false; if (isSameRevision == false) { // 判断此差异是否为SVN中两版本本身存在的差异,如果与本地表、同版本的SVN表还存在此Key,但最新版本SVN表已经没有了,说明是因为SVN版本变动导致此Key被删除,而非用户有意新增Key if (_svnSameRevisionExcelInfo.Keys.Contains(oneLocalAddKeyInfo.Key)) { isChangedBySvnRevision = true; } showDataList.Add(isChangedBySvnRevision == true ? "是" : string.Empty); } DataGridView dataGridView = _partControls[_PART_NAME_LOCAL_ADD_KEY].DataGridView; int index = dataGridView.Rows.Add(showDataList.ToArray()); // 如果差异来自SVN版本的变动,则“版本变动”列的单元格背景色变为浅灰色,并默认将“处理方式”的ComboBox选择为“使用SVN表” if (isChangedBySvnRevision == true) { dataGridView.Rows[index].Cells[PART_LOCAL_ADD_KEY_IS_CHANGED_BY_SVN_REVISION_COLUMN_NAME].Style.BackColor = Color.LightGray; dataGridView.Rows[index].Cells[PART_LOCAL_ADD_KEY_RESOLVE_CONFLICT_WAY_COLUMN_NAME].Value = AppValues.RESOLVE_COMMIT_DIFF_WAYS[1]; } } // SVN表新增Key信息(最新SVN表含有但本地表中没有某个Key) const string PART_SVN_ADD_KEY_RESOLVE_CONFLICT_WAY_COLUMN_NAME = _PART_NAME_SVN_ADD_KEY + _RESOLVE_CONFLICT_WAY_COLUMN_NAME; const string PART_SVN_ADD_KEY_IS_CHANGED_BY_SVN_REVISION_COLUMN_NAME = _PART_NAME_SVN_ADD_KEY + _IS_CHANGED_BY_SVN_REVISION_COLUMN_NAME; int svnAddKeyCount = compareResult.SvnAddKeyInfo.Count; for (int i = 0; i < svnAddKeyCount; ++i) { CommitDifferentKeyInfo oneSvnAddKeyInfo = compareResult.SvnAddKeyInfo[i]; List <object> showDataList = new List <object>(); // 编号 showDataList.Add(i + 1); // Key showDataList.Add(oneSvnAddKeyInfo.Key); // SVN表主语言译文 showDataList.Add(oneSvnAddKeyInfo.DefaultLanguageValue); // SVN表行号 showDataList.Add(oneSvnAddKeyInfo.ExcelLineNum); // 版本变动 bool isChangedBySvnRevision = true; if (isSameRevision == false) { // 判断此差异是否为SVN中两版本本身存在的差异,如果与本地表、同版本的SVN表均没有此Key,但最新版本SVN表中有,说明是因为SVN版本变动导致此Key被新增,而非用户有意删除Key if (_svnSameRevisionExcelInfo.Keys.Contains(oneSvnAddKeyInfo.Key)) { isChangedBySvnRevision = false; } showDataList.Add(isChangedBySvnRevision == true ? "是" : string.Empty); } else { isChangedBySvnRevision = false; } DataGridView dataGridView = _partControls[_PART_NAME_SVN_ADD_KEY].DataGridView; int index = dataGridView.Rows.Add(showDataList.ToArray()); // 如果差异来自SVN版本的变动,则“版本变动”列的单元格背景色变为浅灰色,并默认将“处理方式”的ComboBox选择为“使用SVN表” if (isChangedBySvnRevision == true) { dataGridView.Rows[index].Cells[PART_SVN_ADD_KEY_IS_CHANGED_BY_SVN_REVISION_COLUMN_NAME].Style.BackColor = Color.LightGray; dataGridView.Rows[index].Cells[PART_SVN_ADD_KEY_RESOLVE_CONFLICT_WAY_COLUMN_NAME].Value = AppValues.RESOLVE_COMMIT_DIFF_WAYS[1]; } } }
/// <summary> /// 根据用户选择的差异处理结果,以SVN最新版本文件作为副本,与本地表内容进行合并生成新的Excel母表文件,返回生成文件的路径 /// </summary> public static string GenerateCommitExcelFile(CommitCompareResult compareResult, CommitExcelInfo localExcelInfo, CommitExcelInfo svnExcelInfo, out string errorString) { // 下载对应版本的SVN表,以此作为副本进行修改合并 string svnCopySavePath = Utils.CombinePath(AppValues.PROGRAM_FOLDER_PATH, string.Format("合并后用于提交的SVN母表副本 {0:yyyy年MM月dd日 HH时mm分ss秒} 对应SVN版本号{1}.xlsx", DateTime.Now, compareResult.SvnFileRevision)); Exception exportException; bool result = OperateSvnHelper.ExportSvnFileToLocal(AppValues.SvnExcelFilePath, svnCopySavePath, compareResult.SvnFileRevision, out exportException); if (exportException != null) { errorString = string.Format("下载SVN中最新版本号({0})的母表文件存到本地失败,错误原因为:{1}", compareResult.SvnFileRevision, exportException.Message); return(null); } else if (result == false) { errorString = string.Format("下载SVN中最新版本号({0})的母表文件存到本地失败", compareResult.SvnFileRevision); return(null); } // 打开并编辑这个Excel文件,写入本地表中要合并进去的变动 Excel.Application application = new Excel.Application(); // 不显示Excel窗口 application.Visible = false; // 不显示警告对话框 application.DisplayAlerts = false; // 禁止屏幕刷新 application.ScreenUpdating = false; // 编辑非空单元格时不进行警告提示 application.AlertBeforeOverwriting = false; // 打开Excel工作簿 Excel.Workbook workbook = application.Workbooks.Open(svnCopySavePath); // 找到名为data的Sheet表 Excel.Worksheet dataWorksheet = null; int sheetCount = workbook.Sheets.Count; string DATA_SHEET_NAME = AppValues.EXCEL_DATA_SHEET_NAME.Replace("$", ""); for (int i = 1; i <= sheetCount; ++i) { Excel.Worksheet sheet = workbook.Sheets[i] as Excel.Worksheet; if (sheet.Name.Equals(DATA_SHEET_NAME)) { dataWorksheet = sheet; break; } } if (dataWorksheet == null) { errorString = string.Format("新版母表({0})找不到Sheet名为{1}的数据表,请勿在使用本工具过程中对母表文件进行操作,导出操作被迫中止", AppValues.ExcelFullPath, DATA_SHEET_NAME); return(null); } // 将要提交的变动与该最新SVN表进行合并 // 最新SVN表中主语言列的列号 int defaultLanguageColumnNumInSvnFile = svnExcelInfo.DataColumnIndex; // 先合并主语言译文不同的差异项,只需将该表中Key对应的主语言译文替换为本地表中的内容即可 int diffInfoCount = compareResult.DiffInfo.Count; for (int i = 0; i < diffInfoCount; ++i) { CommitDifferentDefaultLanguageInfo oneDiffInfo = compareResult.DiffInfo[i]; if (oneDiffInfo.ResolveConflictWay == ResolveConflictWays.UseLocal) { string key = oneDiffInfo.Key; string replaceValue = oneDiffInfo.LocalFileDefaultLanguageValue; int dataIndexInSvnFile = svnExcelInfo.KeyToDataIndex[key]; dataWorksheet.Cells[dataIndexInSvnFile + AppValues.EXCEL_DATA_START_INDEX, defaultLanguageColumnNumInSvnFile] = replaceValue; } } // 克隆一份SVN表中的Key信息供之后进行修改而不影响到引用的svnExcelInfo中的Key列表 List <string> cloneSvnKeys = new List <string>(svnExcelInfo.Keys); // 再从该最新SVN表中删除用户选定的Key行 // 先在最新SVN表中找到要删除Key所在的行号,但要注意因为是逐条删除,删除上一条之后下一条所在行号减一,下下条减二,以此类推 List <int> deleteLineNumList = new List <int>(); int svnAddKeyCount = compareResult.SvnAddKeyInfo.Count; // 记录要删除的个数 int tempDeleteCount = 0; for (int i = 0; i < svnAddKeyCount; ++i) { CommitDifferentKeyInfo oneSvnAddKeyInfo = compareResult.SvnAddKeyInfo[i]; if (oneSvnAddKeyInfo.ResolveConflictWay == ResolveConflictWays.UseLocal) { deleteLineNumList.Add(oneSvnAddKeyInfo.ExcelLineNum - tempDeleteCount); ++tempDeleteCount; } } int deleteLineNumCount = deleteLineNumList.Count; for (int i = 0; i < deleteLineNumCount; ++i) { int lineNum = deleteLineNumList[i]; dataWorksheet.get_Range(string.Concat("A", lineNum)).EntireRow.Delete(); cloneSvnKeys.RemoveAt(lineNum - AppValues.EXCEL_DATA_START_INDEX); } // 最后向该最新SVN表中添加用户指定新增的Key行 // 新增Key行插入到最新SVN表中的位置按此方式确定:本地表中新增Key(比如叫key1)在哪一个Key(比如叫key2)之后(要求Key2也必须也存在于最新SVN表中),就在最新SVN表key2的下一行插入key1。如果本地表key1为首行或者以上的行没有任何key也存在于最新SVN表中,则将key1直接置于最新SVN表首行 int localAddKeyCount = compareResult.LocalAddKeyInfo.Count; for (int i = 0; i < localAddKeyCount; ++i) { CommitDifferentKeyInfo oneLocalAddKeyInfo = compareResult.LocalAddKeyInfo[i]; if (oneLocalAddKeyInfo.ResolveConflictWay == ResolveConflictWays.UseLocal) { string addKey = oneLocalAddKeyInfo.Key; // 找到该Key在本地表中的行号,然后向上寻找首个在最新SVN表也存在的Key,将Key行插入到最新SVN表中那个Key之后的新建行中 int keyDataIndexInLocalFile = localExcelInfo.KeyToDataIndex[addKey]; // 上一个SVN表存在的key名以及在SVN表中数据索引位置 string lastKey = null; int lastKeyDataIndex = -1; for (int j = keyDataIndexInLocalFile - 1; j > -1; --j) { if (lastKey != null) { break; } string tempLastKey = localExcelInfo.Keys[j]; if (tempLastKey != null) { int svnKeyCount = cloneSvnKeys.Count; for (int temp = 0; temp < svnKeyCount; ++temp) { if (tempLastKey.Equals(cloneSvnKeys[temp])) { lastKey = tempLastKey; lastKeyDataIndex = temp; break; } } } } // 未找到新增Key行之前的Key(该Key必须也存在于最新SVN表中),将此新增Key行直接置于最新SVN表首行 if (lastKey == null) { // 在首行数据之前再插入一个新行,注意Insert方法会在指定行的上面插入新行 dataWorksheet.get_Range(string.Concat("A", AppValues.EXCEL_DATA_START_INDEX)).EntireRow.Insert(); // 填写Key名以及主语言译文 dataWorksheet.Cells[AppValues.EXCEL_DATA_START_INDEX, 1] = addKey; dataWorksheet.Cells[AppValues.EXCEL_DATA_START_INDEX, defaultLanguageColumnNumInSvnFile] = oneLocalAddKeyInfo.DefaultLanguageValue; cloneSvnKeys.Insert(0, addKey); } else { int lineNumInSvnFile = lastKeyDataIndex + AppValues.EXCEL_DATA_START_INDEX; dataWorksheet.get_Range(string.Concat("A", lineNumInSvnFile + 1)).EntireRow.Insert(); dataWorksheet.Cells[lineNumInSvnFile + 1, 1] = addKey; dataWorksheet.Cells[lineNumInSvnFile + 1, defaultLanguageColumnNumInSvnFile] = oneLocalAddKeyInfo.DefaultLanguageValue; cloneSvnKeys.Insert(lastKeyDataIndex + 1, addKey); } } } // 保存Excel dataWorksheet.SaveAs(svnCopySavePath); workbook.SaveAs(svnCopySavePath); // 关闭Excel workbook.Close(false); application.Workbooks.Close(); application.Quit(); Utils.KillExcelProcess(application); errorString = null; return(svnCopySavePath); }
/// <summary> /// 对比即将提交的本地母表与SVN中母表返回对比结果 /// </summary> public static CommitCompareResult CompareCommitExcelFile(CommitExcelInfo localFile, CommitExcelInfo svnFile) { CommitCompareResult compareResult = new CommitCompareResult(); compareResult.LocalFileRevision = localFile.Revision; compareResult.SvnFileRevision = svnFile.Revision; // 遍历本地表的Key找到本地表独有的Key以及与SVN主语言译文不同的Key信息 int localFileKeyCount = localFile.Keys.Count; for (int i = 0; i < localFileKeyCount; ++i) { string localFileKey = localFile.Keys[i]; if (localFileKey == null) { continue; } if (svnFile.KeyToDataIndex.ContainsKey(localFileKey)) { // 比较主语言译文是否相同 string localFileData = localFile.GetDataByKey(localFileKey); string svnFileData = svnFile.GetDataByKey(localFileKey); if (!localFileData.Equals(svnFileData)) { CommitDifferentDefaultLanguageInfo oneDiffInfo = new CommitDifferentDefaultLanguageInfo(); oneDiffInfo.Key = localFileKey; oneDiffInfo.LocalFileDefaultLanguageValue = localFileData; oneDiffInfo.SvnFileDefaultLanguageValue = svnFileData; oneDiffInfo.LocalFileLineNum = localFile.KeyToDataIndex[localFileKey] + AppValues.EXCEL_DATA_START_INDEX; oneDiffInfo.SvnFileLineNum = svnFile.KeyToDataIndex[localFileKey] + AppValues.EXCEL_DATA_START_INDEX; compareResult.DiffInfo.Add(oneDiffInfo); } } else { // 本地母表有但SVN中无的Key CommitDifferentKeyInfo oneLocalAddKeyInfo = new CommitDifferentKeyInfo(); oneLocalAddKeyInfo.Key = localFileKey; oneLocalAddKeyInfo.ExcelLineNum = localFile.KeyToDataIndex[localFileKey] + AppValues.EXCEL_DATA_START_INDEX; oneLocalAddKeyInfo.DefaultLanguageValue = localFile.GetDataByKey(localFileKey); compareResult.LocalAddKeyInfo.Add(oneLocalAddKeyInfo); } } // 遍历SVN中母表的Key找到SVN中母表独有的Key int svnFileKeyCount = svnFile.Keys.Count; for (int i = 0; i < svnFileKeyCount; ++i) { string svnFileKey = svnFile.Keys[i]; if (svnFileKey == null) { continue; } if (!localFile.KeyToDataIndex.ContainsKey(svnFileKey)) { CommitDifferentKeyInfo oneSvnAddKeyInfo = new CommitDifferentKeyInfo(); oneSvnAddKeyInfo.Key = svnFileKey; oneSvnAddKeyInfo.ExcelLineNum = svnFile.KeyToDataIndex[svnFileKey] + AppValues.EXCEL_DATA_START_INDEX; oneSvnAddKeyInfo.DefaultLanguageValue = svnFile.GetDataByKey(svnFileKey); compareResult.SvnAddKeyInfo.Add(oneSvnAddKeyInfo); } } return(compareResult); }
public static CommitExcelInfo AnalyzeCommitExcelFile(string filePath, string commentLineStartChar, long revision, out string errorString) { CommitExcelInfo commitExcelInfo = new CommitExcelInfo(); commitExcelInfo.Revision = revision; DataSet dataSet = XlsxReader.ReadXlsxFileByOleDb(filePath, out errorString); if (errorString != null) { return(null); } System.Data.DataTable dataTable = dataSet.Tables[0]; int rowCount = dataTable.Rows.Count; int columnCount = dataTable.Columns.Count; if (rowCount < 2) { errorString = "Excel表格格式非法,必须在前两行声明语种描述和名称"; return(null); } if (columnCount < 2) { errorString = "Excel表格格式非法,列自左向右应分别声明Key、主语言"; return(null); } // 从表格第2列开始寻找主语言列 bool hasDefaultLanguage = false; // 记录已读取的Key列值,不允许出现非空的重复Key(key:key值,value:从1开始计的行号) Dictionary <string, int> keyDict = new Dictionary <string, int>(); // 记录重复Key所在行的信息(key:重复的Key名,value:此Key所在行列表,行号从1开始计) Dictionary <string, List <int> > repeatedKeyInfo = new Dictionary <string, List <int> >(); // 记录主语言未进行翻译的行索引(从0开始计) List <int> notTranslatedRowIndex = new List <int>(); for (int i = 1; i < columnCount; ++i) { string languageName = dataTable.Rows[AppValues.EXCEL_NAME_ROW_INDEX - 1][i].ToString().Trim(); if (!string.IsNullOrEmpty(languageName)) { // 解析Key列和主语言列 for (int dataIndex = AppValues.EXCEL_DATA_START_INDEX - 1; dataIndex < rowCount; ++dataIndex) { string keyString = dataTable.Rows[dataIndex][0].ToString().Trim(); // 空行或注释行 if (string.IsNullOrEmpty(keyString) || (commentLineStartChar != null && keyString.StartsWith(commentLineStartChar))) { commitExcelInfo.Keys.Add(null); commitExcelInfo.Data.Add(null); } else { // 如果Key列值出现重复错误进行记录 if (keyDict.ContainsKey(keyString)) { if (repeatedKeyInfo.ContainsKey(keyString)) { List <int> repeatedKeyLineNums = repeatedKeyInfo[keyString]; repeatedKeyLineNums.Add(dataIndex + 1); } else { List <int> repeatedKeyLineNums = new List <int>(); repeatedKeyLineNums.Add(keyDict[keyString]); repeatedKeyLineNums.Add(dataIndex + 1); repeatedKeyInfo.Add(keyString, repeatedKeyLineNums); } } else { commitExcelInfo.Keys.Add(keyString); keyDict.Add(keyString, dataIndex + 1); commitExcelInfo.KeyToDataIndex.Add(keyString, dataIndex - AppValues.EXCEL_NAME_ROW_INDEX); // 检查主语言必须含有翻译 string translatedString = dataTable.Rows[dataIndex][i].ToString(); if (string.IsNullOrEmpty(translatedString)) { notTranslatedRowIndex.Add(dataIndex); commitExcelInfo.Data.Add(null); } else { commitExcelInfo.Data.Add(translatedString); } } } } commitExcelInfo.DataColumnIndex = i + 1; hasDefaultLanguage = true; break; } } if (hasDefaultLanguage == false) { errorString = "Excel表格格式非法,未找到主语言列"; return(null); } StringBuilder errorStringBuilder = new StringBuilder(); if (repeatedKeyInfo.Count > 0) { errorStringBuilder.AppendLine("以下行Key重复:"); foreach (var item in repeatedKeyInfo) { string key = item.Key; List <int> repeatedKeyLineNums = item.Value; errorStringBuilder.AppendFormat("名为\"{0}\"的Key在以下行中重复出现:{1}", key, Utils.CombineString <int>(repeatedKeyLineNums, ",")).AppendLine(); } } if (notTranslatedRowIndex.Count > 0) { errorStringBuilder.AppendLine("以下行中主语言未填写对应文字:"); for (int i = 0; i < notTranslatedRowIndex.Count; ++i) { int rowIndex = notTranslatedRowIndex[i]; string key = commitExcelInfo.Keys[rowIndex - AppValues.EXCEL_DATA_START_INDEX - 1]; errorStringBuilder.AppendFormat("第{0}行(Key名为\"{1}\")", rowIndex + 1, key).AppendLine(); } } errorString = errorStringBuilder.ToString(); if (string.IsNullOrEmpty(errorString)) { errorString = null; return(commitExcelInfo); } else { return(null); } }
// 点击“提交到SVN”按钮 private void btnCommit_Click(object sender, EventArgs e) { FileState fileState = Utils.GetFileState(AppValues.LocalExcelFilePath); if (fileState == FileState.Inexist) { MessageBox.Show("本地表已不存在,请勿在使用本工具时对母表进行操作", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } if (fileState == FileState.IsOpen) { MessageBox.Show("本地表正被其他软件使用,请关闭后再重试", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // 判断本地表是否相较SVN最新版本发生变动,如果本地就是SVN中最新版本且未进行改动则无需提交 SvnException svnException = null; SvnStatusEventArgs localFileState = OperateSvnHelper.GetLocalFileState(AppValues.LocalExcelFilePath, out svnException); if (svnException == null) { SvnInfoEventArgs svnFileInfo = OperateSvnHelper.GetSvnFileInfo(AppValues.SvnExcelFilePath, out svnException); if (svnException == null) { // 本地表的版本号 long localFileRevision = localFileState.LastChangeRevision; // SVN中的母表的版本号 long svnFileRevision = svnFileInfo.LastChangeRevision; if (localFileState.LocalContentStatus == SvnStatus.Normal) { if (localFileRevision == svnFileRevision) { MessageBox.Show("本地母表与SVN最新版本完全一致,无需进行提交操作", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } else if (MessageBox.Show("本地母表不是SVN最新版本,但与同版本SVN表完全一致\n\n确定要在此情况下进行提交操作吗?", "警告", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.No) { return; } } // 本地表与SVN最新版本不同,则要下载一份SVN中最新版本与本地表进行对比,在用户手工选择需要提交哪些改动后将合并后的新表进行提交操作 string svnCopySavePath = Utils.CombinePath(AppValues.PROGRAM_FOLDER_PATH, string.Format("SVN最新母表副本 {0:yyyy年MM月dd日 HH时mm分ss秒} 对应SVN版本号{1}.xlsx", DateTime.Now, svnFileInfo.LastChangeRevision)); Exception exportException; bool result = OperateSvnHelper.ExportSvnFileToLocal(AppValues.SvnExcelFilePath, svnCopySavePath, svnFileInfo.LastChangeRevision, out exportException); if (exportException != null) { MessageBox.Show(string.Concat("下载SVN中最新母表存到本地失败,错误原因为:", svnException.Message), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } else if (result == false) { MessageBox.Show("下载SVN中最新母表存到本地失败", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // 解析本地母表 string errorString = null; CommitExcelInfo localExcelInfo = CommitExcelFileHelper.AnalyzeCommitExcelFile(AppValues.LocalExcelFilePath, AppValues.CommentLineStartChar, localFileRevision, out errorString); if (errorString != null) { MessageBox.Show(string.Concat("本地母表存在以下错误,请修正后重试\n\n", errorString), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // 解析下载到本地的SVN最新母表的副本 CommitExcelInfo svnExcelInfo = CommitExcelFileHelper.AnalyzeCommitExcelFile(svnCopySavePath, AppValues.CommentLineStartChar, svnFileRevision, out errorString); if (errorString != null) { MessageBox.Show(string.Concat("SVN母表存在以下错误,请修正后重试\n\n", errorString), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // 对比本地母表与SVN中的母表 CommitCompareResult compareResult = CommitExcelFileHelper.CompareCommitExcelFile(localExcelInfo, svnExcelInfo); if (compareResult.IsHasDiff() == false) { MessageBox.Show("经对比发现本地母表与SVN中内容完全相同,无需进行提交操作\n请注意本功能仅会对比本地母表与SVN中母表的Key及主语言译文变动,不对各语种进行比较", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } else { // 弹出对比结果界面,让用户选择需要合并到SVN中母表的变动 ResolveConflictWhenCommitForm resolveForm = new ResolveConflictWhenCommitForm(compareResult, localExcelInfo, svnExcelInfo); resolveForm.ShowDialog(this); } } else { MessageBox.Show(string.Concat("无法获取SVN中母表信息,错误原因为:", svnException.Message), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } else { MessageBox.Show(string.Concat("无法获取本地表状态,错误原因为:", svnException.Message), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } }