Перенести уже открытое приложение winform на передний план без API?

Привет,

Скажем, у нас есть приложение WinForm (app1), работающее в фоновом режиме, теперь другое приложение (app2) (самое верхнее активное приложение) запускает startProcess с app1.

Теперь мне нужно app1, чтобы использовать существующий экземпляр и довести его до самого верхнего приложения (не только внутри приложения app1).

Я нашел это: http://sanity-free.org/143/csharp_dotnet_single_instance_application.html

Правда ли, что без API это невозможно? Я посмотрел на принестиToFront, Activate и Focus, но все это, похоже, действует только внутри приложения, а не между приложениями?


person Banshee    schedule 11.05.2012    source источник


Ответы (2)


Я не знаю, что вы имеете в виду «без API» и почему это важно.

Однако самый простой способ - через WindowsFormsApplicationBase. Он дает вам все необходимое с помощью всего нескольких строк кода.

Вам нужно добавить ссылку на сборку Microsoft.VisualBasic, но ее можно использовать через C #.

Сделайте этот класс:

public class SingleInstanceApplication : WindowsFormsApplicationBase
{
    private SingleInstanceApplication()
    {
        IsSingleInstance = true;
    }

    public static void Run(Form form)
    {
        var app = new SingleInstanceApplication
        {
            MainForm = form
        };

        app.StartupNextInstance += (s, e) => e.BringToForeground = true;

        app.Run(Environment.GetCommandLineArgs());
    }
}

И в вашем Program.cs измените строку запуска, чтобы использовать ее:

//Application.Run(new Form1());
SingleInstanceApplication.Run(new Form1());
person John Arlen    schedule 11.05.2012
comment
API в каком-то смысле кажется слишком дорогим, а ссылка, которую я предоставил, действительно использует API, насколько я могу судить? Как может WindowsFormsApplicationBase сделать возможным вывод app1 на передний план для всех приложений Windows? - person Banshee; 11.05.2012

Вам действительно нужна какая-то связь между двумя приложениями. В статье ссылка на опубликованные вами сообщения осуществляется через сообщения WinApi. Также вы можете сделать это через сокеты или через файлы и FileWatcher.

UPD1: Код для имитации сворачивания с сообщением симуляции таймера из другого приложения и максимизации этого сообщения:

public partial class Form1 : Form
{
    private Timer _timer = null;

    public Form1()
    {
        InitializeComponent();

        this.Load += OnFormLoad;
    }

    private void OnFormLoad(object sender, EventArgs e)
    {
        Button btn = new Button();
        btn.Text = "Hide and top most on timer";
        btn.Width = 200;
        btn.Click += OnButtonClick;

        this.Controls.Add(btn);
    }

    private void OnButtonClick(object sender, EventArgs e)
    {
        //minimize app to task bar
        WindowState = FormWindowState.Minimized;

        //timer to simulate message from another app
        _timer = new Timer();
        //time after wich form will be maximize
        _timer.Interval = 2000;
        _timer.Tick += new EventHandler(OnTimerTick);
        _timer.Start();
    }

    private void OnTimerTick(object sender, EventArgs e)
    {
        _timer.Stop();

        //message from another app came - we should 
        WindowState = FormWindowState.Normal;
        TopMost = true;
    }
}
person igofed    schedule 11.05.2012
comment
Я пробовал это с WCF namedPipes, и он отлично работает, проблема в том, как вывести app1 на передний план без API? - person Banshee; 11.05.2012
comment
Просто установите WindowState = FormWindowState.Normal в своей форме, и вы получите то, что хотите. - person igofed; 11.05.2012
comment
Не могли бы вы представить простой пример проекта по этому поводу? - person Banshee; 11.05.2012