从shell执行的文件中获取进程ID?

时间:2010-06-27 23:40:59

标签: c# compact-framework process

我正在使用.net 2.0紧凑型框架制作手持PDA的程序,我有一个我不感到自豪的部分,我希望有一个更优雅的解决方案。 基本上问题是在这种情况下使用我的文件Windows Media Player的另一个过程。我通过将文件位置传递给Process.Start来启动该过程,但似乎返回的进程是短暂的并且它正在产生另一个进程?所以我试着查看如何获取子进程信息,但是遇到了一些问题(我认为由于某种原因没有返回任何进程)。

所以我目前正在做这个狡猾的修复

            string processName = item.Text;
            Process proc = Process.Start(processName, null);
            if (!proc.Start())
                MessageBox.Show("Failed to start process", "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1);
            else
            {
                IntPtr newWindow = IntPtr.Zero;
                TimeSpan limit = TimeSpan.FromSeconds(3);
                DateTime start = DateTime.Now;
                DateTime now = start;

                // do while the following:
                // window is not null
                // window is not ourself
                // under 3 seconds
                do
                {
                    newWindow = Win32.GetForegroundWindow();
                    now = DateTime.Now;

                    // taking too long
                    if (now - start > limit)
                        break;
                }
                while (newWindow == IntPtr.Zero || newWindow == this.Handle);

                if (newWindow != IntPtr.Zero && newWindow != this.Handle)
                {
                    uint processID = 0;
                    if (Win32.GetWindowThreadProcessId(newWindow, out processID) != 0)
                    {
                        //const int stringSize = 1024;
                        //StringBuilder sb = new StringBuilder(1024);
                        //Win32.GetWindowText(newWindow, sb, stringSize);
                        m_processes.Add(new ProcessIDWithName(processID, processName));
                    }
                }
            }

正如你所看到的,我不喜欢它并且它不可靠但它现在确实有效(我需要一个解决方案,无论它是否坏)。 为什么我需要进程ID?因为Windows媒体播放器正在保持文件打开,我无法移动/删除文件,因此我需要在此之前终止该过程。我可以用FindWindow做一个类似的修复,但我想的更通用,因为它可能不是在Windows媒体播放器中打开的媒体文件。

所以基本上我想要一个更好的解决方案,如果可能的话!

另外如果你想知道为什么我没有使用秒表,因为它似乎不存在于.net 2.0 cf中,我也不需要那么精确。

2 个答案:

答案 0 :(得分:1)

这里有很多问题。

  1. 为什么不执行媒体播放器本身而不是搜索目标文件的名称?
  2. 你怎么知道媒体何时播放才能关闭文件?
  3. 为什么不使用toolhelp API简单地枚举进程而不是古怪的GetForegroundWindow / GetWindowsThreadProcessId shenanigans?
  4. 你为什么不只是使用Media Player ActiveX control而不是这个kludge,所以你实际上可以控制事物?
  5. 如果您打算为任何文件制作此通用文件(例如,不仅仅是媒体,但可能类似于Word查看器等)那么您真的不走运,需要重新考虑您正在尝试做的任何事情(你没有告诉我们你想要实现的目标,只是你决定如何实现它。应用程序通常不会在WinMo中关闭,它们通常只会失去最小化的焦点,因此您并不真正知道用户何时“完成”该文件。

    与该文件关联的应用程序可能已在运行,因此自行终止该应用程序是一件不友好的事情。

    目标应用程序真的不是为了在完成任何特定文件时给你回调。

答案 1 :(得分:0)

我没有使用PDA编程的经验,你可以尝试使用Job对象(参见http://msdn.microsoft.com/en-us/library/ms684847.aspx#job_object_functions)。关于CreateJobObject,您可以创建一份新工作。然后,您创建一个暂停的进程,并使用AssignProcessToJobObject将新进程分配给作业对象。然后你可以恢复这个过程。

作业对象的优点是,您可以完全控制作业的所有子进程。您可以使用TerminateJobObject终止所有进程。如果您创建了一个I / O完成端口来等待直接启动进程的结束,并且所有它的子进程或监视所创建的所有子进程等等。如果您需要,我可以发布一些代码示例链接的代码示例。