草庐IT

c# - 条件 Process.Start 到给定 Process 的实例数

coder 2024-06-20 原文

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

这是像往常一样实现的,用

Process.Start("explorer.exe");

但是,我需要将同时处理的资源管理器数量限制为一个实例,而不是用户通过单击按钮启动的实例数。

所以通常的方法是计算给定进程“explorer.exe”实际运行的实例数量,如果超过一个,则阻止 Process.Start()。

问题是我卡在了计数函数中。这是我写的:

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;
    }
  }
}

然后我这样调用函数:

 if(countProcess("explorer")) {
     // Do nothing.
 } else {
     Process p = Process.Start("explorer.exe");    
 }

但是在构建和执行之后,应用程序在打开给定进程时卡住了。实际上,Visual Studio 不会提供任何调试反馈。

如何重构此功能以使其 1) 可操作,2) 高效。

最佳答案

为什么CountProcess方法中有while循环?它应该很简单。

 if(Process.GetProcessByName("explorer").Length == 0) 
 {
    Process.Start("explorer.exe");
 }

===更新===

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

如果这不是 explorer.exe - 此代码应该有效:

    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(如果你没有关闭它)

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

The reason that WaitForSingleObject returns immediately is that Explorer is a single-instance program (well, limited-instance)

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

Open explorer window and wait for it to close

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

=== 更新 2 ====

下面的解决方案有效 - 但有一些限制(您必须添加 com 引用:“Microsoft Internet Controls”)它允许打开一个资源管理器窗口 - 然后检查是否具有与基础相同的“开始文件夹路径”的窗口已经打开(注意代码中两个不同地方的斜杠和反斜杠的区别)

    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 ====

经过一些思考 - 我设法找到了可行的解决方案:

    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;
        }
    }

关于c# - 条件 Process.Start 到给定 Process 的实例数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45442681/

有关c# - 条件 Process.Start 到给定 Process 的实例数的更多相关文章

  1. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  2. ruby - 在 Ruby 中有条件地定义函数 - 2

    我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin

  3. ruby - 定义方法参数的条件 - 2

    我有一个只接受一个参数的方法:defmy_method(number)end如果使用number调用方法,我该如何引发错误??通常,我如何定义方法参数的条件?比如我想在调用的时候报错:my_method(1) 最佳答案 您可以添加guard在函数的开头,如果参数无效则引发异常。例如:defmy_method(number)failArgumentError,"Inputshouldbegreaterthanorequalto2"ifnumbereputse.messageend#=>Inputshouldbegreaterthano

  4. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  5. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  6. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  7. ruby-on-rails - 使用包含多个关联和单独的条件 - 2

    我的Gallery模型中有以下查询:media_items.includes(:photo,:video).rank(:position_in_gallery)我的图库模型有_许多媒体项,每个都有一个照片或视频关联。到目前为止,一切正常。它返回所有media_items包括它们的photo或video关联,由media_item的position_in_gallery属性排序。但是我现在需要将此查询返回的照片限制为仅具有is_processing属性的照片,即nil。是否可以进行相同的查询,但条件是返回的照片等同于:.where(photo:'photo.is_processingIS

  8. ruby-on-rails - 在 haml View 中重构条件 - 2

    除了可访问性标准不鼓励使用这一事实指向当前页面的链接,我应该怎么做重构以下View代码?#navigation%ul.tabbed-ifcurrent_page?(new_profile_path)%li{:class=>"current_page_item"}=link_tot("new_profile"),new_profile_path-else%li=link_tot("new_profile"),new_profile_path-ifcurrent_page?(profiles_path)%li{:class=>"current_page_item"}=link_tot("p

  9. ruby-on-rails - 在具有 ActiveRecord 条件的相关模型中按字段排序 - 2

    我正在尝试按Rails相关模型中的字段进行排序。我研究的所有解决方案都没有解决如果相关模型被另一个参数过滤?元素模型classItem相关模型:classPriority我正在使用where子句检索项目:@items=Item.where('company_id=?andapproved=?',@company.id,true).all我需要按相关表格中的“位置”列进行排序。问题在于,在优先级模型中,一个项目可能会被多家公司列出。因此,这些职位取决于他们拥有的company_id。当我显示项目时,它是针对一个公司的,按公司内的职位排序。完成此任务的正确方法是什么?感谢您的帮助。PS-我

  10. ruby - 如果满足给定条件,则结束 ruby​​ 程序 - 2

    基本上,我只是试图在满足特定条件时停止程序运行其余行。unlessraw_information.firstputs"Noresultswerereturnedforthatquery"breakend然而,在程序运行之前我得到了这个错误:Invalidbreakcompileerror(SyntaxError)执行此操作的正确方法是什么? 最佳答案 abort("Noresultswerereturnedforthatquery")unlesscondition或unlessconditionabort("Noresultswer

随机推荐