如何杀死Excel
我在控制台应用程序X中有一个c#方法,这启动了一个进程;控制台应用程序Y(用相同的c#解决方案编写)。 App Y然后在Excel 2010工作簿中激发vba宏。如何杀死Excel
对于在wkbook VBA我已经添加了一些代码来强制运行时错误1004
WinForm的使用过程中的事件,使用表格定时器,杀死进程引发的测试目的。它正在按照程序进行工作,我只是试图让它做更多一点。 为什么当我杀死进程时,XL在发现错误的时候保持打开状态?我如何找到摆脱XL实例的方式,如果它仍然存在,何时杀死进程,然后将错误消息发回到我的winForm?
(PS下面的代码是很熟悉,但这个问题不是一式两份)
private int elapsedTime;
private Process p;
private System.Windows.Forms.Timer myTimer;
const int SLEEP_AMOUNT = 1000;//1s
const int MAXIMUM_EXECUTION_TIME = 5000;//5s
private void btRunReport_Click(object sender, EventArgs e) {
btRunReport.Enabled = false;
lbStatusUpdate.Text = "Processing..";
//instantiate a new process and set up an event for when it exits
p = new Process();
p.Exited += new EventHandler(MyProcessExited);
p.EnableRaisingEvents = true;
p.SynchronizingObject = this;
elapsedTime = 0;
this.RunReportScheduler();
//add in a forms timer so that the process can be killed after a certain amount of time
myTimer = new System.Windows.Forms.Timer();
myTimer.Interval = SLEEP_AMOUNT;
myTimer.Tick += new EventHandler(TimerTickEvent);
myTimer.Start();
}
private void RunReportScheduler() {
p.StartInfo.FileName = @"\\fileserve\department$\ReportScheduler_v3.exe";
p.StartInfo.Arguments = 2;
p.Start();
}
private void MyProcessExited(Object source, EventArgs e){
myTimer.Stop();
btRunReport.Enabled = true;
lbStatusUpdate.Text = "Start";
}
void TimerTickEvent(Object myObject, EventArgs myEventArgs) {
myTimer.Stop();
elapsedTime += SLEEP_AMOUNT;
if (elapsedTime > MAXIMUM_EXECUTION_TIME)
{p.Kill();}
else
{myTimer.Start();}
}
我离开的代码原有的位不变,但我已经用从安德鲁的帮助,但我的一个好朋友的主要帮助谁不幸的是,不注册到SO。 Excel似乎已经死了!另外,他编码的方式是,它返回一个指示器,告诉表单是否与excel有问题。同时也为我们提供了在每个Excel过程的最大运行时间内进行构建的选项。
他用以下SO answer,以帮助摆脱的Excel
1.In调度程序
- 移动计时器有
- 落实情况的Excel清洁代码存在VBA没有错误,在当最大执行时间达到了(使用Kill方法)
- 从调度器返回0到表单应用程序如果Excel正常结束或1,如果它被杀死 相反的情况下
2.In的形式应用从调度分析返回值在ProcessExited事件处理程序和启动按钮等
因此,新的调度:
using System;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;
using Excel = Microsoft.Office.Interop.Excel;
using System.Timers;
class Program
{
private const int SLEEP_AMOUNT = 1000;
private const int MAXIMUM_EXECUTION_TIME = 10000;
private Excel.Application excelApp =null;
private Excel.Workbook book =null;
private Timer myTimer;
private int elapsedTime;
private int exitCode=0;
[DllImport("user32.dll", SetLastError =true)]
static extern uint GetWindowThreadProcessId(IntPtr hWnd,out uint lpdwProcessId);
static int Main(string[] args)
{
Program myProgram = newProgram();
myProgram.RunExcelReporting(1);
return myProgram.exitCode;
}
void myTimer_Elapsed(object sender,ElapsedEventArgs e)
{
myTimer.Stop();
elapsedTime += SLEEP_AMOUNT;
if (elapsedTime > MAXIMUM_EXECUTION_TIME)
{
//error in vba or maximum time reached. abort excel and return 1 to the calling windows forms application
GC.Collect();
GC.WaitForPendingFinalizers();
if (book != null)
{
book.Close(false,Type.Missing, Type.Missing);
Marshal.FinalReleaseComObject(book);
book =null;
}
if (excelApp != null)
{
int hWnd = excelApp.Hwnd;
uint processID;
GetWindowThreadProcessId((IntPtr)hWnd,out processID);
if (processID != 0)
Process.GetProcessById((int)processID).Kill();
excelApp =null;
exitCode = 1;
}
}
else
{
myTimer.Start();
}
}
void RunExcelReporting(int x)
{
myTimer =new Timer(SLEEP_AMOUNT);
elapsedTime = 0;
myTimer.Elapsed +=new ElapsedEventHandler(myTimer_Elapsed);
myTimer.Start();
try{
excelApp =new Excel.Application();
excelApp.Visible =true;
book = excelApp.Workbooks.Open(@"c:\jsauto.xlsm");
excelApp.Run("ThisWorkbook.rr");
book.Close(false,Type.Missing, Type.Missing);
}
catch (Exception ex){
Console.WriteLine(ex.ToString());
}
finally
{
//no error in vba and maximum time is not reached. clear excel normally
GC.Collect();
GC.WaitForPendingFinalizers();
if (book != null)
{
try {
book.Close(false,Type.Missing, Type.Missing);
}
catch { }
Marshal.FinalReleaseComObject(book);
}
if (excelApp != null)
{
excelApp.Quit();
Marshal.FinalReleaseComObject(excelApp);
excelApp =null;
}
}
}
}
而新形式的应用:
public partial class Form1 : Form
{
SqlDataAdapter myAdapt = null;
DataSet mySet =null;
DataTable myTable =null;
public Form1()
{ InitializeComponent();}
privatevoid Form1_Load(object sender,EventArgs e){
InitializeGridView();
}
private Process myProcess;
private void btRunProcessAndRefresh_Click(object sender,EventArgs e)
{
myProcess =new Process();
myProcess.StartInfo.FileName [email protected]"c:\VS2010Projects\ConsoleApplication2\ConsoleApplication4\bin\Debug\ConsoleApplication4.exe";
myProcess.Exited +=new EventHandler(MyProcessExited);
myProcess.EnableRaisingEvents =true;
myProcess.SynchronizingObject =this;
btRunProcessAndRefresh.Enabled =false;
myProcess.Start();
}
privatevoid MyProcessExited(Object source,EventArgs e)
{
InitializeGridView();
btRunProcessAndRefresh.Enabled =true;
if (((Process)source).ExitCode == 1)
{
MessageBox.Show("Excel was aborted");
}
else
{
MessageBox.Show("Excel finished normally");
}
}
private void btnALWAYSWORKS_Click(object sender,EventArgs e) {
InitializeGridView();
}
privatevoid InitializeGridView() {
using (SqlConnection conn =new SqlConnection(@"Data Source=sqliom3;Integrated Security=SSPI;Initial Catalog=CCL"))
{
myAdapt =new SqlDataAdapter("SELECT convert(varchar(25),getdate(),120) CurrentDate", conn);
mySet =new DataSet();
myAdapt.Fill(mySet,"AvailableValues");
myTable = mySet.Tables["AvailableValues"];
this.dataGridViewControlTable.DataSource = myTable;
this.dataGridViewControlTable.AllowUserToOrderColumns =true;
this.dataGridViewControlTable.Refresh();
}
}
}
它可能与报告调度的问题,它不具有关闭Excel中的正确方法。
这是这样的方法:
private void releaseObject(object obj)
{
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
obj = null;
}
catch (Exception ex)
{
obj = null;
MessageBox.Show("Exception Occured while releasing object " + ex.ToString());
}
finally
{
GC.Collect();
}
}
感谢安德鲁 - 目前没有接近的代码,但我明天将开始玩这个。我的朋友也建议我上面介绍的代码是可以的,问题更可能与ReportScheduler_v3.exe和它处理xl的方式有关 – whytheq 2012-03-19 21:28:50
我读了标题,并认为这是另一个人恨微软。 – 2012-03-19 21:03:57
认为标题的变化可能有助于 – whytheq 2012-03-19 21:05:09