Application.Run(宏)运行s 在调试中成功,但当我 运行 来自不同路径文件夹 [WPF 应用程序] 的 .exe 文件时失败
Application.Run(macro) runs successfully in Debug but fails when I run the .exe file from different path folder [WPF application]
我遇到了一个特殊的问题,我一开始就没有想到这是一个难以解决的错误。
我为 WPF 应用程序创建了一个 excel 按钮,单击该按钮时会执行以下操作:
方法一
//using the OfficeOpenXmland EPPlus packages
public void CreateCopyReportServerNameDB(string sourceFile)
{
ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial;
FileInfo existingFile = new FileInfo(sourceFile);
using (ExcelPackage package = new ExcelPackage(existingFile))
{
ExcelWorksheet worksheet = package.Workbook.Worksheets["Cover"];
worksheet.Cells[7, 4].Value = ConnectionDetailsList[0].ToString();
worksheet.Cells[8, 4].Value = ConnectionDetailsList[1].ToString();
package.SaveAs(new FileInfo($@"{path}{"file_Report.xlsm"}"));
package.Dispose();
}
}
方法二:执行宏
public int ExecuteExcelMacro(string sourceFile) //string sourceFile //String.Format("{0}DQTool_Report.xlsm", path)
{
var destinationFile = @"file_Report";
Excel.Application ExcelApp = new Excel.Application
{
DisplayAlerts = false,
Visible = false
};
Excel.Workbook ExcelWorkBook;
ExcelWorkBook = ExcelApp.Workbooks.Open(sourceFile);
string macro = "ThisWorkbook.Run_Code";
try
{
ExcelApp.Run(macro);
Debug.WriteLine("Macro: " + macro + " executed successfully");
ExcelApp.DisplayAlerts = false;
ExcelApp.Visible = false;
ExcelWorkBook.SaveAs($@"{path}{destinationFile}", Excel.XlFileFormat.xlOpenXMLWorkbook, Type.Missing);
GC.Collect();
GC.WaitForPendingFinalizers();
ExcelWorkBook.Close(0);
if (ExcelWorkBook != null) { Marshal.ReleaseComObject(ExcelWorkBook); }
ExcelApp.Quit();
if (ExcelApp != null) { Marshal.ReleaseComObject(ExcelApp); }
return 1;
}
catch (Exception ex)
{
Debug.WriteLine("Macro not run");
//I repeat the Garbage Collector because if the macro fails to execute the excel workbooks remains open.
GC.Collect();
GC.WaitForPendingFinalizers();
ExcelWorkBook.Close(0);
if (ExcelWorkBook != null) { Marshal.ReleaseComObject(ExcelWorkBook); }
ExcelApp.Quit();
if (ExcelApp != null) { Marshal.ReleaseComObject(ExcelApp); }
MessageBox.Show(ex.ToString());
return 0;
}
}
然后我将方法1和方法2结合在一个按钮下点击如下:
public string path = AppDomain.CurrentDomain.BaseDirectory; //The folder where the .exe file is executed.
private void PreviewExcelReportButton_Click(object sender, RoutedEventArgs e)
{
try
{
Mouse.OverrideCursor = Cursors.Wait;
//Method 1: Create copy of standard report file
CreateCopyReportServerNameDB($@"{path}file.xlsm");
//Method 2: Run macro
if (ExecuteExcelMacro($@"{path}file_Report.xlsm") == 0)
return;
Debug.WriteLine("End");
}
catch (Exception)
{
MessageBox.Show(ex.ToString(), "Error", MessageBoxButton.OK, MessageBoxImage.Error);
return;
}
finally
{
Mouse.OverrideCursor = null;
}
}
即使当我调试应用程序时按钮运行完全成功[调试器在桌面文件夹中运行(也在下图中显示)],但当我将包含所有 dll 文件和 .exe 文件的应用程序文件夹移动到 C:\
中的文件夹位置。当特定按钮无法执行excel文件的宏时,会产生以下错误:
提前感谢您对此事发表任何评论或想法,我很乐意与您分享任何其他信息。
此致。
我找到了问题的答案。
当从 .exe 应用程序以编程方式打开 Excel 文件时,Excel 会自动禁用所有宏。所以为了超越这个我使用了下面的命令:
Excel.Application ExcelApp = new Excel.Application
{
DisplayAlerts = false,
Visible = false,
AutomationSecurity = Microsoft.Office.Core.MsoAutomationSecurity.msoAutomationSecurityLow
};
有关 MsoAutomationSecurity 的更多信息 here
我遇到了一个特殊的问题,我一开始就没有想到这是一个难以解决的错误。
我为 WPF 应用程序创建了一个 excel 按钮,单击该按钮时会执行以下操作:
方法一
//using the OfficeOpenXmland EPPlus packages
public void CreateCopyReportServerNameDB(string sourceFile)
{
ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial;
FileInfo existingFile = new FileInfo(sourceFile);
using (ExcelPackage package = new ExcelPackage(existingFile))
{
ExcelWorksheet worksheet = package.Workbook.Worksheets["Cover"];
worksheet.Cells[7, 4].Value = ConnectionDetailsList[0].ToString();
worksheet.Cells[8, 4].Value = ConnectionDetailsList[1].ToString();
package.SaveAs(new FileInfo($@"{path}{"file_Report.xlsm"}"));
package.Dispose();
}
}
方法二:执行宏
public int ExecuteExcelMacro(string sourceFile) //string sourceFile //String.Format("{0}DQTool_Report.xlsm", path)
{
var destinationFile = @"file_Report";
Excel.Application ExcelApp = new Excel.Application
{
DisplayAlerts = false,
Visible = false
};
Excel.Workbook ExcelWorkBook;
ExcelWorkBook = ExcelApp.Workbooks.Open(sourceFile);
string macro = "ThisWorkbook.Run_Code";
try
{
ExcelApp.Run(macro);
Debug.WriteLine("Macro: " + macro + " executed successfully");
ExcelApp.DisplayAlerts = false;
ExcelApp.Visible = false;
ExcelWorkBook.SaveAs($@"{path}{destinationFile}", Excel.XlFileFormat.xlOpenXMLWorkbook, Type.Missing);
GC.Collect();
GC.WaitForPendingFinalizers();
ExcelWorkBook.Close(0);
if (ExcelWorkBook != null) { Marshal.ReleaseComObject(ExcelWorkBook); }
ExcelApp.Quit();
if (ExcelApp != null) { Marshal.ReleaseComObject(ExcelApp); }
return 1;
}
catch (Exception ex)
{
Debug.WriteLine("Macro not run");
//I repeat the Garbage Collector because if the macro fails to execute the excel workbooks remains open.
GC.Collect();
GC.WaitForPendingFinalizers();
ExcelWorkBook.Close(0);
if (ExcelWorkBook != null) { Marshal.ReleaseComObject(ExcelWorkBook); }
ExcelApp.Quit();
if (ExcelApp != null) { Marshal.ReleaseComObject(ExcelApp); }
MessageBox.Show(ex.ToString());
return 0;
}
}
然后我将方法1和方法2结合在一个按钮下点击如下:
public string path = AppDomain.CurrentDomain.BaseDirectory; //The folder where the .exe file is executed.
private void PreviewExcelReportButton_Click(object sender, RoutedEventArgs e)
{
try
{
Mouse.OverrideCursor = Cursors.Wait;
//Method 1: Create copy of standard report file
CreateCopyReportServerNameDB($@"{path}file.xlsm");
//Method 2: Run macro
if (ExecuteExcelMacro($@"{path}file_Report.xlsm") == 0)
return;
Debug.WriteLine("End");
}
catch (Exception)
{
MessageBox.Show(ex.ToString(), "Error", MessageBoxButton.OK, MessageBoxImage.Error);
return;
}
finally
{
Mouse.OverrideCursor = null;
}
}
即使当我调试应用程序时按钮运行完全成功[调试器在桌面文件夹中运行(也在下图中显示)],但当我将包含所有 dll 文件和 .exe 文件的应用程序文件夹移动到 C:\
中的文件夹位置。当特定按钮无法执行excel文件的宏时,会产生以下错误:
提前感谢您对此事发表任何评论或想法,我很乐意与您分享任何其他信息。
此致。
我找到了问题的答案。
当从 .exe 应用程序以编程方式打开 Excel 文件时,Excel 会自动禁用所有宏。所以为了超越这个我使用了下面的命令:
Excel.Application ExcelApp = new Excel.Application
{
DisplayAlerts = false,
Visible = false,
AutomationSecurity = Microsoft.Office.Core.MsoAutomationSecurity.msoAutomationSecurityLow
};
有关 MsoAutomationSecurity 的更多信息 here