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

检测在c#中使用openas_rundll打开的选定程序share

时间:2023-04-11 02:56:49 C#

检测在c#中使用openas_rundll打开的选定程序Process.Start("rundll32.exe",string.Format("shell32.dll,OpenAs_RunDLL"{0}"",tempFilePath));现在我想检测用于打开文件的程序。我想跟踪这个过程。我的目标是在用户关闭程序时删除文件。您可以尝试通过查找py父进程ID来捕捉实际应用程序关闭的时刻。如果找到它,请等待它关闭,只要它可以接受。感谢jeremy-murray为GetAllProcessParentPids方法:publicvoidStartProcessAndWathTillTerminated(stringtempFilePath){//向用户显示应用程序选择对话框Processrundll32=Process.Start("rundll32.exe",string.Format("shell32.dll,OpenAs_RunDLL{0}",临时文件路径));intrundll32id=rundll32.Id;//等到对话框关闭while(!rundll32.HasExited){System.Threading.Thread.Sleep(50);}//获取所有具有父id的正在运行的进程Dictionaryallprocparents=GetAllProcessParentPids();intopenedAppId=0;//遍历所有进程foreach(varallprocparentinallprocparents){//找到子进程,由我们的rundll32.exe实例启动if(allprocparent.Value==rundll32id){openedAppId=allprocparent.Key;休息;}}//检查我们是否真的找到了任何进程。它在两种情况下找不到://1)进程关闭得太快,而我们正在寻找它//2)用户单击取消并且没有打开应用程序//也有可能tchesen应用程序已经在运行。在这种情况下//rundll32.exe将在很短的时间内打开新实例//将文件路径传递给正在运行的实例所需的时间。无论如何,这种情况属于情况1)。//如果我们无法明确找到进程,我们可以尝试通过文件锁找到它,如果存在的话://我在这里使用来自https://stackoverflow.com/a/1263609的代码片段/880156,//假设此文件上可能有不止一个锁。//我先拿。if(openedAppId==0){ProcesshandleExe=newProcess();handleExe.StartInfo.FileName="handle.exe";handleExe.StartInfo.Arguments=tempFilePath;handleExe.StartInfo.UseShellExecute=false;handleExe.StartInfo.RedirectStandardOutput=true;handleExe.Start();handleExe.WaitForExit();字符串outputhandleExe=handleExe.StandardOutput.ReadToEnd();stringmatchPattern=@"(?GetAllProcessParentPids(){varchildPidToParentPid=newDictionary();varprocessCounters=new排序字典();varcategory=newPerformanceCounterCategory("进程");//由于基本系统总是有多个进程在运行,//不要在特殊情况下返回单个实例。varinstanceNames=category.GetInstanceNames();foreach(instanceNames中的字符串t){尝试{processCounters[t]=category.GetCounters(t);}catch(InvalidOperationException){//瞬态进程可能不再存在于//GetInstanceNames和查询计数器之间。}}foreach(varkvpinprocessCounters){intchildPid=-1;intparentPid=-1;foreach(varcounterinkvp.Value){if("IDProcess".CompareTo(counter.CounterName)==0){childPid=(int)(counter.NextValue());}elseif("CreatingProcessID".CompareTo(counter.CounterName)==0){parentPid=(int)(counter.NextValue());}}if(childPid!=-1&&parentPid!=-1){childPidToParentPid[childPid]=parentPid;}}返回childPidToParentPid;}更新由于许多原因,似乎没有100%成功保证的解决方案我认为找到由rundll32.exe启动的进程是所有其他进程中最可靠的。如果做不到这一点,您仍然可以使用其他方法来确定进程ID来完成它。据我所知,还有其他几种方法可以找到仍在使用的文件。例如,Winword.exe在同一目录中创建一些临时文件并在关机时删除它们。因此,如果您能捕捉到临时文件被删除的瞬间,那么您可能会认为该程序已关闭。其他程序可以通过设置锁来保持文件打开。如果是这样,您可以通过查找锁所有者找到该程序。我使用了这个答案https://stackoverflow.com/a/1263609/880156的解决方案,使用了外部程序handle.exe,所以看一下。我必须提到根本没有永久文件锁。这取决于程序架构。例如,如果您使用Firefox打开一个html文件,它会尽可能快地读取该文件并在不再次锁定该文件的情况下将其关闭。在这种情况下,即使您以某种方式找到了进程名称(例如“firefox.exe”),您也无法找到用户关闭带有您的文件的选项卡的时刻。如果我是你,我会实施这个仍然不是最优的解决方案,并在必要时稍后升级它。只是一个简单的帮助程序类,它为您提供了一种使用Windows的OpenWithDialog打开文件的方法,并使用WMI监视启动的进程以识别所选应用程序。对于WMI,添加System.Management.dll作为参考注意:它无法识别Windows照片查看器-这是针对您的案例的dllhost.exe示例调用:using(OpenFileDialogofd=newOpenFileDialog()){ofd.Filter="所有文件(*.*)|*.*";如果(ofd.ShowDialog()==System.Windows.Forms.DialogResult.OK){使用(Win.OpenWithDialogHelperhelper=newWin.OpenWithDialogHelper()){helper.OpenFileAndWaitForExit(ofd.FileName);File.Delete(helper.Filepath);}}}班级:以上为C#学习教程:检测在c#中用openas_rundll打开的选中程序共享的所有内容,如果对C#学习教程有用,需要了解更多,希望大家多多关注—命名空间Win{使用System.Management;使用系统线程;使用系统诊断;使用System.IO;publicclassOpenWithDialogHelper:IDisposable{#regionmembersprivateProcessopenWithProcess;私有ManagementEventWatcher监视器;公共字符串文件路径{得到;放;}publicProcessAppProcess{get;私有集;}#endregion#region.ctorpublicOpenWithDialogHelper(){}publicOpenWithDialogHelper(stringfilepath){=this.Filepath小路;}#endregion#region方法publicvoidOpenFileAndWaitForExit(intmilliseconds=0){OpenFileAndWaitForExit(this.Filepath,毫秒);}publicvoidOpenFileAndWaitForExit(stringfilepath,intmilliseconds=0){this.Filepath=filepath;this.openWithProcess=newProcess();this.openWithProcess.StartInfo.FileName="rundll32.exe";this.openWithProcess.StartInfo.Arguments=String.Format("shell32.dll,OpenAs_RunDLL"{0}"",filepath);this.openWithProcess.Start();//使用WMI,备注添加System.Management.dll作为参考!this.monitor=newManagementEventWatcher(newWqlEventQuery("SELECT*FROMWin32_ProcessStartTrace"));this.monitor.EventArrived+=newEventArrivedEventHandler(start_EventArrived);这个.monitor.Start();这个.openWithProcess.WaitForExit();//捕获应用程序进程...//当进程关闭太快时无法捕获//或者用户单击取消并且没有打开应用程序Thread.Sleep(1000);诠释我=0;//最多等待5秒...while(this.AppProcess==null&&i0)this.AppProcess.WaitForExit(milliseconds);否则this.AppProcess.WaitForExit();}}publicvoidDispose(){if(this.monitor!=null){this.monitor.EventArrived-=newEventArrivedEventHandler(start_EventArrived);这个.monitor.Dispose();}if(this.openWithProcess!=null)this.openWithProcess.Dispose();如果(this.AppProcess!=null)this.AppProcess.Dispose();}#endregion#regioneventsprivatevoidstart_EventArrived(objectsender,EventArrivedEventArgse){intparentProcessID=Convert.ToInt32(e.NewEvent.Properties["ParentProcessID"].Value);//启动进程的ParentProcessID必须是OpenAs_RunDLL进程//注意:它不识别Windows照片查看器//-这是一个没有ParentProcessID的dllhost.exeif(parentProcessID==this.openWithProcess.Id){this.AppProcess=Process.GetProcessById(Convert.ToInt32(e.NewEvent.Properties["ProcessID"].Value));如果(!this.AppProcess.HasExited){this.AppProcess.EnableRaisingEvents=true;}}}#endregion}}本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如有转载请注明出处: