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

C# 检测在c中使用openas_rundll打开的选定程序#,c#,winapi,shellexecute,C#,Winapi,Shellexecute,在c#中的openas_rundll的帮助下,我正在使用openfile对话框打开一个文件 现在我想检测用于打开文件的程序。我想追踪这个过程 我的目标是在用户关闭程序时删除该文件。您可以通过查找父进程id来捕捉实际应用程序关闭的时刻。如果您找到了它,您可以等待它关闭,只要它是可接受的。感谢: public void StartProcessAndWathTillTerminated(字符串tempFilePath) { //向用户显示应用程序选择对话框 Process rundll32=Proc

在c#中的openas_rundll的帮助下,我正在使用openfile对话框打开一个文件

现在我想检测用于打开文件的程序。我想追踪这个过程


我的目标是在用户关闭程序时删除该文件。

您可以通过查找父进程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
    }
}