首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将Process.Start条件设置为给定进程的实例数

将Process.Start条件设置为给定进程的实例数
EN

Stack Overflow用户
提问于 2017-08-01 16:06:22
回答 1查看 1.1K关注 0票数 1

在WPF C#应用程序中,用户可以从给定的菜单启动"explorer.exe“进程。

这与往常一样,与

代码语言:javascript
运行
复制
Process.Start("explorer.exe");

但是,我需要将同时处理的资源管理器数量限制在一个实例上,而不是以用户单击一个按钮开始的实例数量为单位。

因此,通常的方法是计算给定进程"explorer.exe“实际运行的实例数,如果有多个实例,则阻止Process.Start()。

问题是我被塞进了计数功能。以下是我所写的:

代码语言:javascript
运行
复制
static bool CountProcess(string name) {
   return false; // by defualt it returns false.
   int counter = 0;

   while(true) {
     counter = Process.GetProcessesByName(name).length; // get the quantity of processes for a given name.
    if(counter > 1) {
       return true;
       break;
    }
  }
}

然后,我调用该函数如下:

代码语言:javascript
运行
复制
 if(countProcess("explorer")) {
     // Do nothing.
 } else {
     Process p = Process.Start("explorer.exe");    
 }

然而,在构建和执行之后,应用程序在打开给定进程时会被塞回。实际上,Visual不提供任何调试反馈。

该功能如何重构为1)可操作的,2)高效的。

EN

Stack Overflow用户

回答已采纳

发布于 2017-08-01 16:16:48

为什么CountProcess方法中存在Why循环?应该很简单如果。

代码语言:javascript
运行
复制
 if(Process.GetProcessByName("explorer").Length == 0) 
 {
    Process.Start("explorer.exe");
 }

===更新===

好吧,我开始意识到你的问题是什么。

如果这不是explorer.exe -这段代码应该可以工作:

代码语言:javascript
运行
复制
    private static Process proc { get; set; }

    private void button1_Click(object sender, EventArgs e)
    {
        if (proc == null || proc.HasExited)
        {
            proc = Process.Start("explorer.exe");
        }
    }

它检查进程是否曾经创建过(如果第一次允许处理,如果不拒绝启动新进程),如果他第二次单击,进程不是空的,但它应该是proc.HasExited == false (如果您没有关闭它)。

但是,如果您运行此代码-可能启动新的资源管理器窗口将是可能的,因为这个新创建的进程将立即关闭。这是因为:

WaitForSingleObject立即返回的原因是资源管理器是一个单实例程序(嗯,有限实例)。

您可以尝试按此处建议的方式修改注册表:

Open explorer window and wait for it to close

但是,如果这是要安装在其他计算机上的客户端应用程序,我不会建议以编程方式更改某个注册表。

===更新2 ====

下面的解决方案是可行的--但有一些限制(必须添加com引用:“”),它允许打开一个资源管理器窗口,然后检查窗口是否与已经打开的“开始文件夹路径”相同(请注意代码中两个不同位置的斜杠和反斜杠差异)。

代码语言:javascript
运行
复制
    using SHDocVw;
    public bool ExistOpenedWindow()
    {
        ShellWindows _shellWindows = new SHDocVw.ShellWindows();
        string processType;

        foreach (InternetExplorer ie in _shellWindows)
        {
            //this parses the name of the process
            processType = Path.GetFileNameWithoutExtension(ie.FullName).ToLower();

            //this could also be used for IE windows with processType of "iexplore"
            if (processType.Equals("explorer") && ie.LocationURL.Contains("C:/"))
            {
                return true;
            }
        }
        return false;
    }

    private void button1_Click(object sender, EventArgs e)
    {

        if (proc == null || !ExistOpenedWindow())
        {
            proc = Process.Start("explorer.exe", @"C:\");
        }
    }

因此,如果您选择基路径(将作为参数发送给explorer.exe")为C:/,在再次单击按钮后,它将检查是否有任何资源管理器窗口包含此类路径(由您打开与否)。

比较这里:Start explorer.exe without creating a window C#

在这里:Is there a way to close a particular instance of explorer with C#?

===更新3 ====

经过一番思考,我终于找到了解决方案:

代码语言:javascript
运行
复制
    public bool ExistOpenedWindow()
    {
        var currentlyOpenedWindows = GetAllOpenedExplorerWindow();
        return currentlyOpenedWindows.Any(t => t.HWND == ActiveOpenedWindowHwnd);
    }

    public List<InternetExplorer> GetAllOpenedExplorerWindow()
    {
        List<InternetExplorer> windows = new List<InternetExplorer>();

        ShellWindows _shellWindows = new SHDocVw.ShellWindows();
        string processType;

        foreach (InternetExplorer ie in _shellWindows)
        {                
            //this parses the name of the process
            processType = Path.GetFileNameWithoutExtension(ie.FullName).ToLower();

            //this could also be used for IE windows with processType of "iexplore"
            if (processType.Equals("explorer"))
            {
                windows.Add(ie);
            }
        }
        return windows;
    }

    public static int ActiveOpenedWindowHwnd;        

    private void button1_Click(object sender, EventArgs e)
    {
        var currentlyOpenedWindows = GetAllOpenedExplorerWindow();
        if (ActiveOpenedWindowHwnd == 0 || !ExistOpenedWindow())
        {
            Process.Start("explorer.exe");
            ShellWindows windows;
            while ((windows = new SHDocVw.ShellWindows()).Count <= currentlyOpenedWindows.Count)
            {
                Thread.Sleep(50);
            }
            var currentlyOpenedWindowsNew = GetAllOpenedExplorerWindow();
            var openedWindow = currentlyOpenedWindowsNew.Except(currentlyOpenedWindows).Single();
            ActiveOpenedWindowHwnd = openedWindow.HWND;
        }
    }
票数 2
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45442681

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档