C# 检测在c中使用openas_rundll打开的选定程序#
在c#中的openas_rundll的帮助下,我正在使用openfile对话框打开一个文件 现在我想检测用于打开文件的程序。我想追踪这个过程C# 检测在c中使用openas_rundll打开的选定程序#,c#,winapi,shellexecute,C#,Winapi,Shellexecute,在c#中的openas_rundll的帮助下,我正在使用openfile对话框打开一个文件 现在我想检测用于打开文件的程序。我想追踪这个过程 我的目标是在用户关闭程序时删除该文件。您可以通过查找父进程id来捕捉实际应用程序关闭的时刻。如果您找到了它,您可以等待它关闭,只要它是可接受的。感谢: public void StartProcessAndWathTillTerminated(字符串tempFilePath) { //向用户显示应用程序选择对话框 Process rundll32=Proc
我的目标是在用户关闭程序时删除该文件。您可以通过查找父进程id来捕捉实际应用程序关闭的时刻。如果您找到了它,您可以等待它关闭,只要它是可接受的。感谢:
public void StartProcessAndWathTillTerminated(字符串tempFilePath)
{
//向用户显示应用程序选择对话框
Process rundll32=Process.Start(“rundll32.exe”,string.Format(“shell32.dll,OpenAs_RunDLL{0}”,tempFilePath));
int rundll32id=rundll32.Id;
//等待对话框关闭
当(!rundll32.hasExit)退出时
{
系统.线程.线程.睡眠(50);
}
//获取父id为的所有正在运行的进程
Dictionary allprocparents=GetAllProcessParentPids();
int-openedapid=0;
//通过所有进程循环
foreach(allprocparents中的var allprocparent)
{
//找到由rundll32.exe实例启动的子进程
if(allprocparent.Value==rundll32id)
{
openedapid=allprocparent.Key;
打破
}
}
//检查我们是否确实发现了任何流程。在两种情况下找不到:
//1)在我们查找过程中,过程关闭得太快
//2)用户单击“取消”,未打开任何应用程序
//还有可能chesen应用程序已经在运行
//案例新实例将由rundll32.exe在很短的一段时间内打开
//将文件路径传递到正在运行的实例所需的时间。无论如何,这种情况属于情况1)。
//如果无法显式查找进程,则可以尝试通过文件锁查找它(如果存在):
//我在这里使用的代码片段来自https://stackoverflow.com/a/1263609/880156,
//它假定此文件上可能有多个锁。
//我只是先走一步。
if(openedAppId==0)
{
Process handleExe=新流程();
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();
string matchPattern=@”(?只是一个简单的帮助器类,它为您提供了一种方法,可以使用windows的OpenWithDialog打开文件,并使用WMI监视启动的进程,以识别choosen应用程序
对于WMI,添加System.Management.dll作为参考
注意:它无法识别windows照片查看器
-这是一个dllhost.exe
针对您的情况的示例呼叫:
using (OpenFileDialog ofd = new OpenFileDialog())
{
ofd.Filter = "All files(*.*)|*.*";
if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
using (Win.OpenWithDialogHelper helper = new Win.OpenWithDialogHelper())
{
helper.OpenFileAndWaitForExit(ofd.FileName);
File.Delete(helper.Filepath);
}
}
}
班级:
namespace Win
{
using System.Management;
using System.Threading;
using System.Diagnostics;
using System.IO;
public class OpenWithDialogHelper : IDisposable
{
#region members
private Process openWithProcess;
private ManagementEventWatcher monitor;
public string Filepath { get; set; }
public Process AppProcess { get; private set; }
#endregion
#region .ctor
public OpenWithDialogHelper()
{
}
public OpenWithDialogHelper(string filepath)
{
this.Filepath = filepath;
}
#endregion
#region methods
public void OpenFileAndWaitForExit(int milliseconds = 0)
{
OpenFileAndWaitForExit(this.Filepath, milliseconds);
}
public void OpenFileAndWaitForExit(string filepath, int milliseconds = 0)
{
this.Filepath = filepath;
this.openWithProcess = new Process();
this.openWithProcess.StartInfo.FileName = "rundll32.exe";
this.openWithProcess.StartInfo.Arguments = String.Format("shell32.dll,OpenAs_RunDLL \"{0}\"", filepath);
this.openWithProcess.Start();
//using WMI, remarks to add System.Management.dll as reference!
this.monitor = new ManagementEventWatcher(new WqlEventQuery("SELECT * FROM Win32_ProcessStartTrace"));
this.monitor.EventArrived += new EventArrivedEventHandler(start_EventArrived);
this.monitor.Start();
this.openWithProcess.WaitForExit();
//catching the app process...
//it can't catched when the process was closed too soon
//or the user clicked Cancel and no application was opened
Thread.Sleep(1000);
int i = 0;
//wait max 5 secs...
while (this.AppProcess == null && i < 3000)
{
Thread.Sleep(100); i++;
}
if (this.AppProcess != null)
{
if (milliseconds > 0)
this.AppProcess.WaitForExit(milliseconds);
else
this.AppProcess.WaitForExit();
}
}
public void Dispose()
{
if (this.monitor != null)
{
this.monitor.EventArrived -= new EventArrivedEventHandler(start_EventArrived);
this.monitor.Dispose();
}
if(this.openWithProcess != null)
this.openWithProcess.Dispose();
if (this.AppProcess != null)
this.AppProcess.Dispose();
}
#endregion
#region events
private void start_EventArrived(object sender, EventArrivedEventArgs e)
{
int parentProcessID = Convert.ToInt32(e.NewEvent.Properties["ParentProcessID"].Value);
//The ParentProcessID of the started process must be the OpenAs_RunDLL process
//NOTICE: It doesn't recognice windows photo viewer
// - which is a dllhost.exe that doesn't have the ParentProcessID
if (parentProcessID == this.openWithProcess.Id)
{
this.AppProcess = Process.GetProcessById(Convert.ToInt32(
e.NewEvent.Properties["ProcessID"].Value));
if (!this.AppProcess.HasExited)
{
this.AppProcess.EnableRaisingEvents = true;
}
}
}
#endregion
}
}
{
使用制度管理;
使用系统线程;
使用系统诊断;
使用System.IO;
公共类OpenWithDialogHelper:IDisposable
{
#区域成员
私有进程openWithProcess;
私人管理事件观察者监视器;
公共字符串文件路径{get;set;}
公共进程AppProcess{get;private set;}
#端区
#地区.行政长官
公共OpenWithDialogHelper()
{
}
公共OpenWithDialogHelper(字符串文件路径)
{
this.Filepath=Filepath;
}
#端区
#区域方法
public void OpenFileAndWaitForExit(整数毫秒=0)
{
OpenFileAndWaitForExit(this.Filepath,毫秒);
}
public void OpenFileAndWaitForExit(字符串filepath,int毫秒=0)
{
this.Filepath=Filepath;
this.openWithProcess=新流程();
this.openWithProcess.StartInfo.FileName=“rundll32.exe”;
this.openWithProcess.StartInfo.Arguments=String.Format(“shell32.dll,OpenAs_RunDLL\{0}\”,filepath);
此参数为.openWithProcess.Start();
//使用WMI,备注添加System.Management.dll作为参考!
this.monitor=新的ManagementEventWatcher(新的WqlEventQuery(“从Win32_ProcessStartTrace中选择*);
this.monitor.EventArrived+=新的eventArrivedVenthandler(start\u EventArrived);
这个是.monitor.Start();
此函数为.openWithProcess.WaitForExit();
//正在捕获应用程序进程。。。
//当进程关闭得太早时,无法捕获它
//或者用户单击“取消”,但未打开任何应用程序
睡眠(1000);
int i=0;
//最多等待5秒。。。
while(this.AppProcess==null&&i<3000)
{
睡眠(100);i++;
}
if(this.AppProcess!=null)
{
如果(毫秒>0)
this.AppProcess.WaitForExit(毫秒);
其他的
this.AppProcess.WaitForExit();
}
}
公共空间处置()
{
如果(this.monitor!=null)
{
this.monitor.eventArrivedVenthandler-=新事件到达(start\u EventArrived);
this.monitor.Dispose();
}
if(this.openWithProcess!=null)
此参数为.openWithProcess.Dispose();
if(this.AppProcess!=null)
this.AppProcess.Dispose();
}
#端区
#地区活动
私有void start\u EventArrived(对象发送方,EventArrivedEventArgs e)
{
int parentProcessID=Convert.ToInt32(例如,NewEvent.Properties[“parentProcessID”].Value);
//已启动进程的ParentProcessID必须是OpenAs_RunDLL进程
//注意:它无法识别windows照片查看器
using (OpenFileDialog ofd = new OpenFileDialog())
{
ofd.Filter = "All files(*.*)|*.*";
if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
using (Win.OpenWithDialogHelper helper = new Win.OpenWithDialogHelper())
{
helper.OpenFileAndWaitForExit(ofd.FileName);
File.Delete(helper.Filepath);
}
}
}
namespace Win
{
using System.Management;
using System.Threading;
using System.Diagnostics;
using System.IO;
public class OpenWithDialogHelper : IDisposable
{
#region members
private Process openWithProcess;
private ManagementEventWatcher monitor;
public string Filepath { get; set; }
public Process AppProcess { get; private set; }
#endregion
#region .ctor
public OpenWithDialogHelper()
{
}
public OpenWithDialogHelper(string filepath)
{
this.Filepath = filepath;
}
#endregion
#region methods
public void OpenFileAndWaitForExit(int milliseconds = 0)
{
OpenFileAndWaitForExit(this.Filepath, milliseconds);
}
public void OpenFileAndWaitForExit(string filepath, int milliseconds = 0)
{
this.Filepath = filepath;
this.openWithProcess = new Process();
this.openWithProcess.StartInfo.FileName = "rundll32.exe";
this.openWithProcess.StartInfo.Arguments = String.Format("shell32.dll,OpenAs_RunDLL \"{0}\"", filepath);
this.openWithProcess.Start();
//using WMI, remarks to add System.Management.dll as reference!
this.monitor = new ManagementEventWatcher(new WqlEventQuery("SELECT * FROM Win32_ProcessStartTrace"));
this.monitor.EventArrived += new EventArrivedEventHandler(start_EventArrived);
this.monitor.Start();
this.openWithProcess.WaitForExit();
//catching the app process...
//it can't catched when the process was closed too soon
//or the user clicked Cancel and no application was opened
Thread.Sleep(1000);
int i = 0;
//wait max 5 secs...
while (this.AppProcess == null && i < 3000)
{
Thread.Sleep(100); i++;
}
if (this.AppProcess != null)
{
if (milliseconds > 0)
this.AppProcess.WaitForExit(milliseconds);
else
this.AppProcess.WaitForExit();
}
}
public void Dispose()
{
if (this.monitor != null)
{
this.monitor.EventArrived -= new EventArrivedEventHandler(start_EventArrived);
this.monitor.Dispose();
}
if(this.openWithProcess != null)
this.openWithProcess.Dispose();
if (this.AppProcess != null)
this.AppProcess.Dispose();
}
#endregion
#region events
private void start_EventArrived(object sender, EventArrivedEventArgs e)
{
int parentProcessID = Convert.ToInt32(e.NewEvent.Properties["ParentProcessID"].Value);
//The ParentProcessID of the started process must be the OpenAs_RunDLL process
//NOTICE: It doesn't recognice windows photo viewer
// - which is a dllhost.exe that doesn't have the ParentProcessID
if (parentProcessID == this.openWithProcess.Id)
{
this.AppProcess = Process.GetProcessById(Convert.ToInt32(
e.NewEvent.Properties["ProcessID"].Value));
if (!this.AppProcess.HasExited)
{
this.AppProcess.EnableRaisingEvents = true;
}
}
}
#endregion
}
}