草庐IT

c# - 向 Windows 进程(不是它的主窗口)发送消息

coder 2023-11-10 原文

我有一个应用程序,它在后续启动时检测是否有同名进程正在运行,如果是,则激活正在运行的应用程序窗口,然后退出。

问题是主窗口可能会被隐藏(只有一个通知区域图标可见),因此我没有窗口句柄。

在启动时,前一个实例的 MainWindowHandle 属性为 0,因此我无法发送 ShowWindowPostMessage

有什么方法可以发送一条消息,让正在运行的应用程序拦截该消息,从而允许它显示其主窗口?

该应用程序是用 C# 编写的,下面是我用来实现此目的的代码。

[STAThread]
static void Main()
{
    bool createdNew = true;
    using (Mutex mutex = new Mutex(true, "MyMutexName", out createdNew))
    {
        if (createdNew)
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MainForm());
        }
        else
        {
            Process current = Process.GetCurrentProcess();
            foreach (Process process in Process.GetProcessesByName(current.ProcessName))
            {
                if (process.Id != current.Id)
                {
                    Interop.WINDOWINFO pwi = new Interop.WINDOWINFO();
                    IntPtr handle = process.MainWindowHandle;
                    var isVisible = Interop.GetWindowInfo(handle, ref pwi);
                    if (!isVisible)
                    {
                        MessageBox.Show(Constants.APP_NAME + " is already running, check the notification area (near the clock).", 
                                        Constants.APP_NAME, MessageBoxButtons.OK, MessageBoxIcon.Information);//temporary message, until I find the solution
                        //Interop.ShowWindow(handle, Interop.WindowShowStyle.ShowNormal);
                        //Interop.PostMessage(handle, Interop.WM_CUSTOM_ACTIVATEAPP, IntPtr.Zero, IntPtr.Zero);
                    }
                    else
                        Interop.SetForegroundWindow(handle);//this works when the window is visible
                        break;
                    }
                }
            }
        }
    }
}

最佳答案

这是我的做法:

using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
public partial class MainForm : Form
{
    #region Dll Imports
    private const int HWND_BROADCAST = 0xFFFF;

    private static readonly int WM_MY_MSG = RegisterWindowMessage( "WM_MY_MSG" );

    [DllImport( "user32" )]
    private static extern bool PostMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam);

    [DllImport( "user32" )]
    private static extern int RegisterWindowMessage(string message);
    #endregion Dll Imports
    static Mutex _single = new Mutex(true, "{4EABFF23-A35E-F0AB-3189-C81203BCAFF1}");
    [STAThread]
    static void Main()
    {
        // See if an instance is already running...
        if (_single.WaitOne(TimeSpan.Zero, true)) {
            // No...start up normally.
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            try {
                Application.Run(new MainForm());
            } catch (Exception ex) {
                // handle exception accordingly
            } finally {
                _single.ReleaseMutex();
            }
        } else {
            // Yes...Bring existing instance to top and activate it.
            PostMessage(
                (IntPtr) HWND_BROADCAST,
                WM_MY_MSG,
                new IntPtr(0xCDCD),
                new IntPtr(0xEFEF));
        }
    }

    protected override void WndProc(ref Message m)
    {
        if (m.Msg == WM_MY_MSG) {
            if ((m.WParam.ToInt32() == 0xCDCD) && (m.LParam.ToInt32() == 0xEFEF)) {
                if (WindowState == FormWindowState.Minimized) {
                    WindowState = FormWindowState.Normal;
                }
                // Bring window to front.
                bool temp = TopMost;
                TopMost = true;
                TopMost = temp;
                // Set focus to the window.
                Activate();
            }
        } else {
            base.WndProc(ref m);
        }
    }
}

我希望我已经正确转录了这个。我不得不遗漏很多其他的东西,但我想我得到了必要的东西。我所拥有的一切都对我有用。如果您遇到问题,请告诉我,我会看看我遗漏了什么。

关于c# - 向 Windows 进程(不是它的主窗口)发送消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1777668/

有关c# - 向 Windows 进程(不是它的主窗口)发送消息的更多相关文章

  1. ruby - 在 Ruby 程序执行时阻止 Windows 7 PC 进入休眠状态 - 2

    我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0

  2. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  3. ruby - 通过 ruby​​ 进程共享变量 - 2

    我正在编写一个gem,我必须在其中fork两个启动两个webrick服务器的进程。我想通过基类的类方法启动这个服务器,因为应该只有这两个服务器在运行,而不是多个。在运行时,我想调用这两个服务器上的一些方法来更改变量。我的问题是,我无法通过基类的类方法访问fork的实例变量。此外,我不能在我的基类中使用线程,因为在幕后我正在使用另一个不是线程安全的库。所以我必须将每个服务器派生到它自己的进程。我用类变量试过了,比如@@server。但是当我试图通过基类访问这个变量时,它是nil。我读到在Ruby中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是

  4. ruby-on-rails - 如何在 Rails View 上显示错误消息? - 2

    我是rails的新手,想在form字段上应用验证。myviewsnew.html.erb.....模拟.rbclassSimulation{:in=>1..25,:message=>'Therowmustbebetween1and25'}end模拟Controller.rbclassSimulationsController我想检查模型类中row字段的整数范围,如果不在范围内则返回错误信息。我可以检查上面代码的范围,但无法返回错误消息提前致谢 最佳答案 关键是您使用的是模型表单,一种显示ActiveRecord模型实例属性的表单。c

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

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

  6. ruby - 在 Windows 机器上使用 Ruby 进行开发是否会适得其反? - 2

    这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby​​-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub

  7. jquery - 我的 jquery AJAX POST 请求无需发送 Authenticity Token (Rails) - 2

    rails中是否有任何规定允许站点的所有AJAXPOST请求在没有authenticity_token的情况下通过?我有一个调用Controller方法的JqueryPOSTajax调用,但我没有在其中放置任何真实性代码,但调用成功。我的ApplicationController确实有'request_forgery_protection'并且我已经改变了config.action_controller.consider_all_requests_local在我的environments/development.rb中为false我还搜索了我的代码以确保我没有重载ajaxSend来发送

  8. 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

  9. ruby - 使用 Ruby 通过 Outlook 发送消息的最简单方法是什么? - 2

    我的工作要求我为某些测试自动生成电子邮件。我一直在四处寻找,但未能找到可以快速实现的合理解决方案。它需要在outlook而不是其他邮件服务器中,因为我们有一些奇怪的身份验证规则,我们需要保存草稿而不是仅仅发送邮件的选项。显然win32ole可以做到这一点,但我找不到任何相当简单的例子。 最佳答案 假设存储了Outlook凭据并且您设置为自动登录到Outlook,WIN32OLE可以很好地完成此操作:require'win32ole'outlook=WIN32OLE.new('Outlook.Application')message=

  10. Ruby - 如何将消息长度表示为 2 个二进制字节 - 2

    我正在使用Ruby,我正在与一个网络端点通信,该端点在发送消息本身之前需要格式化“header”。header中的第一个字段必须是消息长度,它被定义为网络字节顺序中的2二进制字节消息长度。比如我的消息长度是1024。如何将1024表示为二进制双字节? 最佳答案 Ruby(以及Perl和Python等)中字节整理的标准工具是pack和unpack。ruby的packisinArray.您的长度应该是两个字节长,并且按网络字节顺序排列,这听起来像是n格式说明符的工作:n|Integer|16-bitunsigned,network(bi

随机推荐