通过C#启动的PowerPoint不会退出
嘿,我正在从一个C#WinForms应用程序自动化PowerPoint和Excel;我要做的是从PowerPoint中读取幻灯片并将其保存在Excel中,然后退出这两个应用程序。Excel成功退出,但PowerPoints不会退出。问题是当我第一次转换时它不会退出,但当我再次转换时它会退出 这是我的密码通过C#启动的PowerPoint不会退出,c#,com,powerpoint,C#,Com,Powerpoint,嘿,我正在从一个C#WinForms应用程序自动化PowerPoint和Excel;我要做的是从PowerPoint中读取幻灯片并将其保存在Excel中,然后退出这两个应用程序。Excel成功退出,但PowerPoints不会退出。问题是当我第一次转换时它不会退出,但当我再次转换时它会退出 这是我的密码 try { PowerPoint.Application ppApp; PowerPoint.Presentation ppPres; List<Company&g
try
{
PowerPoint.Application ppApp;
PowerPoint.Presentation ppPres;
List<Company> companies = new List<Company>();
ppApp = new PowerPoint.Application();
ppApp.Visible = Microsoft.Office.Core.MsoTriState.msoTrue;
ppApp.WindowState = Microsoft.Office.Interop.PowerPoint.PpWindowState.ppWindowMinimized;
ppPres = ppApp.Presentations.Open(fileTxtBox.Text,
Microsoft.Office.Core.MsoTriState.msoFalse,
Microsoft.Office.Core.MsoTriState.msoFalse,
Microsoft.Office.Core.MsoTriState.msoTrue);
int slides = ppPres.Slides.Count;
for (int slide = 1; slide <= slides; slide++)
{
int rows = 1;
PowerPoint.Cell cell;
int shape = 1;
for (; shape < ppPres.Slides[slide].Shapes.Count; shape++)
{
if (ppPres.Slides[slide].Shapes[shape].HasTable == Microsoft.Office.Core.MsoTriState.msoTrue)
{
cell = ppPres.Slides[slide].Shapes[shape].Table.Cell(1, 1);
if (cell.Shape.TextFrame.TextRange.Text.Trim().ToLower().Contains("realized"))
{
rows = ppPres.Slides[slide].Shapes[shape].Table.Rows.Count;
break;
}
}
}
Company comp = new Company(rows);
InitializeCompany(ref comp, ppPres.Slides[slide]);
companies.Add(comp);
}
SaveInExcel(companies);
ppPres.Close();
ppPres = null;
ppApp.Quit();
ppApp = null;
return;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
GC.Collect();
GC.WaitForPendingFinalizers();
}
试试看
{
ppApp应用程序;
PowerPoint.演示文稿ppPres;
上市公司=新上市公司();
ppApp=新的PowerPoint.Application();
ppApp.Visible=Microsoft.Office.Core.MsoTriState.msoTrue;
ppApp.WindowState=Microsoft.Office.Interop.PowerPoint.PpWindowState.ppWindowMinimized;
ppPres=ppApp.Presentations.Open(fileTxtBox.Text,
Microsoft.Office.Core.MsoTriState.msoFalse,
Microsoft.Office.Core.MsoTriState.msoFalse,
Microsoft.Office.Core.MsoTriState.msoTrue);
int slides=ppPres.slides.Count;
对于(int slide=1;slide看起来您正在使Power Point应用程序实例可见,但如果不可见,则可能存在您看不到的对话框-可能是保存更改对话框。如果应用程序运行时处于隐藏状态,则使其可见,以查看是否有任何此类对话框弹出,从而阻止Power Point关闭。为ppApp对象调用Quit()后,请尝试以下操作
System.Runtime.InteropServices.Marshal.ReleaseComObject(ppApp);
但是,没有承诺,它可能会起作用,或者可能什么都不起作用。正确关闭Office COM东西对我来说一直有点像巫毒。关闭Microsoft Office应用程序一开始可能看起来很棘手,但一旦确定了正确的操作顺序,实际上一点也不难
发布MS Office应用程序可以分两个阶段安全有效地完成:
(1) 首先释放命名变量中未包含引用的所有次要对象。可以通过调用和来执行此操作。请注意,如果使用Visual Studio Tools for Office(VSTO),则需要调用这对命令两次,以便成功释放COM对象。但是,您没有使用VSTO,因此只需调用一次即可
(2) 然后使用对每个变量的调用,通过命名变量显式释放所持有的对象
请记住显式释放COM组件所需的所有变量。如果您遗漏了其中一个,则您的MS Office应用程序将挂起。在您的代码中,您似乎有三个命名变量包含对PowerPoint应用程序的引用:ppApp
、ppPres
和cell
考虑到这一切,我认为您的清理应该如下所示,在命名空间内或代码文档顶部使用using System.Runtime.InteropServices
:
// using System.Runtime.InteropServices
// Cleanup:
GC.Collect();
GC.WaitForPendingFinalizers();
Marshal.ReleaseComObject(cell);
ppPres.Close();
Marshal.ReleaseComObject(ppPres);
ppApp.Quit();
Marshal.ReleaseComObject(ppApp);
试一试,我认为这应该适合您…(如果没有,您可能需要显示更多的代码。)有关更多信息,我将在此处详细解释如何正确发布Excel应用程序:
希望这有帮助,让我们知道它是如何进行的
--Mike这是一篇MSDN文章,描述了问题和解决方案
基本上需要重新编译(注意:GC.Collect()的两次迭代)
大家好。最近我发现从垃圾收集到退出和关闭对象对我来说没有任何效果。所以我想出了一个替代方案。我在工作完成后发现了正在运行的进程,然后通过代码终止了它
代码:
Process[] pros = Process.GetProcesses();
for (int i = 0; i < pros.Count(); i++)
{
if (pros[i].ProcessName.ToLower().Contains("powerpnt"))
{
pros[i].Kill();
}
}
Process[]pros=Process.getprocesss();
for(int i=0;i
这是我的工作
var app = new PowerPoint.Application();
PowerPoint.Presentations pres = app.Presentations;
PowerPoint.Presentation ActivePresentation = pres.Open(fileIn, MsoTriState.msoTrue, MsoTriState.msoTrue, MsoTriState.msoFalse);
(...)
ActivePresentation.SaveAs(fileOut, PowerPoint.PpSaveAsFileType.ppSaveAsDefault, MsoTriState.msoTrue);
ActivePresentation.Close();
app.Quit();
不,没有这样的事:(嘿,迈克,谢谢,但这不起作用。我想告诉你的一件事是,当我关闭自己的WinForm应用程序时,PowerPoint也会关闭。是的,当你关闭WinForm应用程序时,它会关闭是正常的,因为当运行时被拆除时,你未能释放的任何对象最终都会被释放。你可以尝试调用GC.Collect()和GC.WaitForPending()终结器两次。如果您没有使用VSTO,这应该无关紧要,但不会造成伤害。您需要考虑这里还有哪些其他变量…(请参阅下一条注释)。您需要考虑这里还有哪些其他变量,然后释放它们。例如:(1)任何地方有其他静态变量吗?(2)您的InitializeCompany(ref comp,ppPres.Slides[slide])调用的作用是什么?如果它在您的公司对象中存储对PowerPoint幻灯片的引用,则此调用将与companys.Add(comp)一起创建对PowerPoint引用的永久引用。必须通过调用Marshal.FinalReleaseComObject()来断开这些调用否则PowerPoint将挂起。我不知道是否发生了这种情况,但您需要释放所有PowerPoint引用。底线。将office代码与Winform类分开。不要直接从窗体的类调用它。否则COM对象会被卡在内存中,直到您杀死窗体。使用这些InteropService是非常困难的很有压力,但这个解决方案奏效了,所以谢谢你。有趣的是,多年后它仍然有同样的问题/困难。它对我也有效,但我不明白为什么这两个电话改变了我的生活。
var app = new PowerPoint.Application();
PowerPoint.Presentations pres = app.Presentations;
PowerPoint.Presentation ActivePresentation = pres.Open(fileIn, MsoTriState.msoTrue, MsoTriState.msoTrue, MsoTriState.msoFalse);
(...)
ActivePresentation.SaveAs(fileOut, PowerPoint.PpSaveAsFileType.ppSaveAsDefault, MsoTriState.msoTrue);
ActivePresentation.Close();
app.Quit();