当前位置: 首页 > 编程语言 > C#

Application.Quit()方法无法清除进程共享

时间:2023-04-10 22:02:23 C#

Application.Quit()方法无法清除进程Google搜索返回了很多关于此的帖子,但其中提到的解决方案我都不清楚。所以,我想我会尝试自己。在这段代码之后:PowerPoint.ApplicationpowerPoint=newMicrosoft.Office.Interop.PowerPoint.Application();powerPoint.Visible=Office.MsoTriState.msoTrue;Microsoft.Office.Interop.PowerPoint.Presentationppt=null;在此处输入代码我可以发出ppt.Quit();命令和Powerpoint将关闭,没有任何进程在运行。但是,如果我在这段代码之后执行此操作:ppt=powerPoint.Presentations.Open(localCopyOfPPT,Microsoft.Office.Core.MsoTriState.msoCTrue,Microsoft.Office.Core.MsoTriState.msoTriStateMixed,Microsoft.Office.Core.MsoTriState.msoTrue);ppt.关闭();powerPoint.Quit();然后,Quit()将不起作用。打开演示文稿会阻止Quit()工作,即使我随后关闭它,它也会出现。有人对如何让应用程序正确退出有任何想法吗?以下知识库文章可能会帮助您找到问题的根源。http://support.microsoft.com/kb/317109您可能需要在ppt实例上显式调用System.Runtime.InteropServices.Marshal.ReleaseComObject。powerPoint.Presentations.Open(..)注意Presentations对象的使用。COM使用基于引用计数的手动内存管理,每个COM接口都有一个AddRef()和一个Release()方法。获取对象时,AddRef调用是自动的。完成后,您必须调用Release()方法。在此处使用Presentations对象添加对Presentations对象的引用。这反过来又添加了对内部应用程序对象的引用。这与.NET框架中的内存管理非常不兼容。它是自动的,垃圾收集器会处理它。对于COM对象也是如此,互操作包装器有一个终结器,当它发现COM对象上没有剩余的.NET引用时,它会减少引用计数。也许您会明白它的走向:在释放所有对象引用之前,PowerPoint无法退出。在垃圾收集器运行并且终结器线程完成之前,这不会发生。您对Quit()方法的调用不会使垃圾收集器运行。只有GC.Collect()+GC.WaitForPendingFinalizers可以做到这一点。您也可以采用手动方法。它需要Marshal.ReleaseComObject()。这很难做到,请注意您没有对存储在代码中任何位置的Presentations对象的引用。您必须完全重写您的代码以跟踪这些引用,以便您可以对它们调用ReleaseComObject()。我怎么推荐都不为过。如果您确实希望PowerPoint退出,更好的方法是确保所有引用都为空并调用GC.Collect()和GC.WFPF。我也不能推荐这个。它最终会退出。不用担心。替代你的问题。找到进程并在完成工作后将其删除。代码:Process[]processes=Process.GetProcessesByName("powerpnt");for(inti=0;iNamespace:System.Diagnostics我在工作中遇到了同样的问题......你试试下面的代码它正在运行PowerPoint。ApplicationpowerPoint=newMicrosoft.Office.Interop.PowerPoint.Application();//powerPoint.Visible=Office.MsoTriState.msoTrue;Microsoft.Office.Interop.PowerPoint.Presentationppt=null;尝试{ppt=powerPoint.Presentations.Open(localCopyOfPPT,Microsoft.Office.Core.MsoTriState.msoCTrue,Microsoft.Office.Core.MsoTriState.msoTriStateMixed,Microsoft.Office.Core.MsoTriState.msoFalse);ppt.Close();Marshal.FinalReleaseComObject(ppt);}catch(){}最后{powerPoint.Quit();Marshal.FinalReleaseComObject(powerPoint);GC.Collect();}尝试以下操作。GC.收集();GC.WaitForPendingFinalizers();您可能也必须以这种方式使用它GC.Collect();GC.WaitForPendingFinalizers();GC.收集();GC.WaitForPendingFinalizers();此页面的最后一点http://code.msdn.microsoft.com/office/CSAutomatePowerPoint-b312d416如果您打开了多个PowerPoint实例,您可以使用这些-这是我在关闭PowerPoint应用程序时发现的最简单的方法,这些应用程序在要求退出时无法清除。这就是我最后的死亡/关闭PowerPoint(由已打开的文档路径指定)的方式//////关闭打开的PowerPoint文档//////文档路径///保存对文档的更改publicvoidPowerPointCloseOpenDocument(字符串路径,布尔值saveChanges=true){ppApp=getPowerPointApp(path);PowerPoint.Presentationpp=null;if(!String.IsNullOrEmpty(path)){foreach(PowerPoint.PresentationpinppApp.Presentations){if(p.FullName.Equals(path,StringComparison.CurrentCultureIgnoreCase)){try{pp=p;}赶上(异常){}休息;}}}if(saveChanges){if(pp!=null){pp.Save();}}if(pp!=null){Marshal.FinalReleaseComObject(pp);}if(null!=ppApp){Marshal.FinalReleaseComObject(ppApp);}varprocs=FileUtil.WhoIsLocking(路径);if(procs!=null){foreach(varprocinprocs){proc.Kill();}}GC.Collect();GC.WaitForPendingFinalizers();GC.收集();GC.WaitForPendingFinalizers();}privatePowerPoint.ApplicationgetPowerPointApp(Stringpath=""){try{PowerPoint.Applicati在ppapp=null上;尝试{if(!String.IsNullOrEmpty(path)){ppapp=((PowerPoint.Presentation)System.Runtime.InteropServices.Marshal.BindToMoniker(path)).Application;}}catch(Exception){}if(ppapp==null){try{ppapp=(PowerPoint.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("PowerPoint.Application");}catch(Exception){ppapp=newPowerPoint.Application();ppapp.Visible=Microsoft.Office.Core.MsoTriState.msoTrue;}}if(ppapp!=null){ppapp.DisplayAlerts=Microsoft.Office.Interop.PowerPoint.PpAlertLevel.ppAlertsNone;}尝试{ppapp.Activate();}赶上(异常){}返回ppapp;}catch(Exception){return(PowerPoint.Application)Activator.CreateInstance(Type.GetTypeFromProgID("PowerPoint.Application"));}}FileUtil类,为您提供当前锁定文档的进程列表以上是C#学习教程:Application.Quit()方法无法清除进程共享的所有内容。如果对大家有用,需要详细了解C#学习教程,希望大家多多关注---staticpublicclassFileUtil{[StructLayout(LayoutKind.Sequential)]structRM_UNIQUE_PROCESS{publicintdwProcessId;公共System.Runtime.InteropServices.ComTypes.FILETIMEProcessStartTime;}constintRmRebootReasonNone=0;constintCCH_RM_MAX_APP_NAME=255;常量整数CCH_RM_MAX_SVC_NAME=63;枚举RM_APP_TYPE{RmUnknownApp=0,RmMainWindow=1,RmOtherWindow=2,RmService=3,RmExplorer=4,RmConsole=5,RmCritical=1000}[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Unicode)]structRM_PROCESS_INFO{publicRM_UNIQUE_PROCESS_PROCESS_INFO{公共RM_UNIQUE_PROCESSAssess进程;[.ByValTStr,SizeConst=CCH_RM_MAX_APP_NAME+1)]publicstringstrAppName;[MarshalAs(UnmanagedType.ByValTStr,SizeConst=CCH_RM_MAX_SVC_NAME+1)]publicstringstrServiceShortName;公共RM_AsAPP_TYPE应用程序类型;agedType.Bool)]publicboolbRestartable;}[DllImport("rstrtmgr.dll",CharSet=CharSet.Unicode)]staticexternintRmRegisterResources(uintpSessionHandle,UInt32nFiles,string[]rgsFilenames,UInt32nApplications,[In]RM_UNIQUE_PROCESS[]rgApplications,UInt32nServices,字符串[]rgsServiceNames);[DllImport("rstrtmgr.dll",CharSet=CharSet.Auto)]staticexternintRmStartSession(outuintpSessionHandle,intdwSessionFlags,stringstrSessionKey);[DllImport("rstrtmgr.dll")]staticexternintRmEndSession(uintpSessionHandle);[DllImport("rstrtmgr.dll")]staticexternintRmGetList(uintdwSessionHandle,outuintpnProcInfoNeeded,refuintpnProcInfo,[In,Out]RM_PROCESS_INFO[]rgAffectedApps,refuintlpdwRebootReasons);//////找出哪些进程锁定了指定的文件。//////文件的路径。///锁定文件的进程///另请参阅:///http://msdn.microsoft.com/en-us/library/windows/desktop/aa373661(v=vs.85).aspx///http://wyupdate.googlecode.com/svn-history/r401/trunk/frmFilesInUse.cs(查看时代码没有版权)//////staticpublicListWhoIsLocking(stringpath){句柄;字符串键=Guid.NewGuid().ToString();列出进程=newList();intres=RmStartSession(outhandle,0,key);if(res!=0)thrownewException("无法开始重新启动会话。无法确定文件柜。");尝试{constintERROR_MORE_DATA=234;uintpnProcInfoNeeded=0,pnProcInfo=0,lpdwRebootReasons=RmRebootReasonNone;字符串[]资源=新字符串[]{路径};//只检查一个资源。res=RmRegisterResources(handle,(uint)resources.Length,resources,0,null,0,null);if(res!=0)thrownewException("无法注册资源。");//注意:这里有一个竞争条件——第一次调用RmGetList()返回//进程总数。但是,当我们再次调用RmGetList()以获取//这个数字可能的实际进程时增加了。res=RmGetList(句柄,输出pnProcInfoNeeded,refpnProcInfo,null,reflpdwRebootReasons);if(res==ERROR_MORE_DATA){//创建一个数组来存储处理结果RM_PROCESS_INFO[]processInfo=newRMFO[PROnedProcpnProcInfo=pnProcInfoNeeded;//获取列表res=RmGetList(handle,outpnProcInfoNeeded,refpnProcInfo,processInfo,reflpdwRebootReasons);if(res==0){processes=newList((int)pnProcInfo);//枚举所有结果,加入//待返回列表for(inti=0;i本文摘自网络,不代表立场,如涉及侵权,请点击右边联系管理员删除,如需转载请注明出处: