Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.64/170: Рейтинг темы: голосов - 170, средняя оценка - 4.64
3 / 3 / 0
Регистрация: 23.03.2009
Сообщений: 38
1

Как запретить одновременный запуск нескольких копий программы

23.03.2009, 22:10. Показов 32901. Ответов 18
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
да, без использования записи в реестре...
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
23.03.2009, 22:10
Ответы с готовыми решениями:

запретить одновременный запуск нескольких копий приложения
Задача такая: 1) запретить одновременный запуск нескольких копий приложения 2) если приложение...

Одновременный запуск только 5 копий программы
Помню как все одно время набил оскомину вопрос, как же запретить повторный запуск программы. А мне...

Одновременный запуск нескольких приложений
@echo off chcp 1251 1>nul start "patcher_cf" "D:\ИГРЫ\Cross Fire\patcher_cf exitВот одно из них ...

Одновременный запуск нескольких сессий на сервере
Всем привет. Чисто эстетическая задачка. Есть html форма в которой выбираются источники для...

18
37 / 32 / 4
Регистрация: 23.01.2009
Сообщений: 141
24.03.2009, 00:03 2
Следует унаследовать класс, которому вы передаёте управление из Main, от Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase(перед этим добавив ссылку на Microsoft.VisualBasic.dll ) и в конструкторе указать IsSingleInstance=true.
На WPF точно работает, на WinForms в принципе тоже должно работать
0
1923 / 428 / 41
Регистрация: 12.07.2007
Сообщений: 2,062
24.03.2009, 03:38 3
Будет и на WinForms работать. Можно также реализовать с помощью паттерна Одиночка. Можно проверять по имени в уже запущенных процессах.
0
3 / 3 / 0
Регистрация: 23.03.2009
Сообщений: 38
24.03.2009, 08:05  [ТС] 4
а можно пример привести на С#... А то на словах я не очень соображаю...
0
2 / 2 / 0
Регистрация: 23.03.2009
Сообщений: 9
24.03.2009, 11:09 5
Цитата Сообщение от Green Посмотреть сообщение
Можно проверять по имени в уже запущенных процессах.
Имя процесса пользователь может изменить. Лучше по имени класса.
Но гдето читал что это тоже не самый лучший способ, могут возникнуть ситуации когда он не сработает. К сожалению подробностей не помню.
0
37 / 35 / 7
Регистрация: 18.04.2009
Сообщений: 376
20.04.2009, 21:41 6
Я тоже не очень хорошо понял. Приведите пожалуйста пример.

Добавлено через 46 минут 31 секунду
Нашёл такой код.

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
using System.Threading;
using System.Windows.Forms;
public class MyForm : Form
{
  private const string AppMutexName = "SingleApp";
  public static void Main()
  {
    using (Mutex mutex = new Mutex(false, AppMutexName))
    {
      bool Running = !mutex.WaitOne(0, false);
      if(!Running)
      {
        Application.Run(new MyForm());
      }
      else
      {
        // App already launched.
        MessageBox.Show("Im luanched!");
      }
    }
  }
}
2
3 / 3 / 0
Регистрация: 23.03.2009
Сообщений: 38
20.05.2010, 00:15  [ТС] 7
да, закрываю тему и даю свой метод:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
   static class Program
   {      
       [DllImport("user32.dll")]
       [return: MarshalAs(UnmanagedType.Bool)]
       static extern bool SetForegroundWindow(IntPtr hWnd);
 
      /// 
      /// Главная точка входа для приложения.
      /// 
      [STAThread]
      static void Main()
      {                    
         bool createdNew = true;
         using (Mutex mutex = new Mutex(true, "MyApplicationName", out createdNew))
         {
             if (createdNew)
             {
                 Application.EnableVisualStyles();
                 Application.SetCompatibleTextRenderingDefault(false);
                 Application.Run(new Form_Main());
             }
             else
             {
                 Process current = Process.GetCurrentProcess();
                
                foreach (Process process in Process.GetProcessesByName(current.ProcessName))
                 {
                     if (process.Id != current.Id)
                     {
                         SetForegroundWindow(process.MainWindowHandle);
                         break;
                     }
                 }
             }
         }
 
      }
   }
2
70 / 69 / 10
Регистрация: 14.06.2009
Сообщений: 310
Записей в блоге: 1
21.05.2010, 09:12 8
C#
1
2
3
4
5
6
7
8
9
10
11
12
static void Main() 
        {           
            if(System.Diagnostics.Process.GetProcessesByName(Application.ProductName).Length > 1)
            {
                MessageBox.Show("Приложение уже запущено");
                return;
            }
            else
            {
                Application.Run(new Form1());
            }
        }
вот поменьше код но тоже работает )
5
37 / 35 / 7
Регистрация: 18.04.2009
Сообщений: 376
10.04.2012, 02:54 9
Цитата Сообщение от vadyxa Посмотреть сообщение
foreach (Process process in Process.GetProcessesByName(current.ProcessName)) { if (process.Id != current.Id) { SetForegroundWindow(process.MainWindowHandle); break; } }
а почему в условии !=, а не == ?
И будет ли этот код работать в Windows 7
0
6048 / 3457 / 335
Регистрация: 14.06.2009
Сообщений: 8,136
Записей в блоге: 2
10.04.2012, 10:10 10
для запрета одновменного запуска я использую этот класс
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;
using System.Runtime.InteropServices;
using System.IO;
 
namespace RunOnlyOne
{
    public static class RunOnlyOneClass
    {
        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool SetForegroundWindow(IntPtr hWnd);
 
        [DllImport("user32.dll", SetLastError = true)]
        internal static extern int ShowWindow(int hwnd, int nCmdShow);
 
        //[DllImport("user32.dll", SetLastError = true)]
        //internal static extern int GetWindow(int hwnd, int nCmdShow);
 
        static Mutex _syncObject;        
        static readonly string AppPath = Path.GetFileNameWithoutExtension(Application.ExecutablePath);
 
        /// <summary>
        /// Находит запущенную копию приложения и разворачивает окно
        /// </summary>
        /// <param name="UniqueValue">уникальное значение для каждой программы (можно имя)</param>
        /// <returns>true - если приложение было запущено</returns>
        public static bool ChekRunProgramm(string UniqueValue)
        {
            bool applicationRun = false;             
            _syncObject = new Mutex(true, UniqueValue, out applicationRun);
            if (!applicationRun)
            {//восстановить/развернуть окно                              
                try
                {
                    Process[] procs = Process.GetProcessesByName(AppPath);
 
                    foreach (Process proc in procs)
                        if (proc.Id != Process.GetCurrentProcess().Id)
                        {
                            ShowWindow((int)proc.MainWindowHandle, 1);//нормально развернутое
                            //ShowWindow((int)proc.MainWindowHandle, 3);//максимально развернутое
                            SetForegroundWindow(proc.MainWindowHandle);                            
                            
                            break;
                        }
                }
                catch { return false; }                
            }
            return !applicationRun;
        }
    }
}
вызывается так
C#
1
2
3
4
5
6
7
8
9
[STAThread]
        static void Main()
        {
            if (RunOnlyOneClass.ChekRunProgramm("Test")) return;
            
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());            
        }
пока что немного забросил: немного не доделано разворачивание запущенной копии (не знаю как получить состояние окна, которое было до сворачивания)
8
1923 / 428 / 41
Регистрация: 12.07.2007
Сообщений: 2,062
10.04.2012, 11:16 11
Цитата Сообщение от nio Посмотреть сообщение
proc.MainWindowHandle
Если окно свернуто в трей, то по идее хэндл должен быть 0.
0
6048 / 3457 / 335
Регистрация: 14.06.2009
Сообщений: 8,136
Записей в блоге: 2
10.04.2012, 13:31 12
Цитата Сообщение от Green Посмотреть сообщение
Если окно свернуто в трей, то по идее хэндл должен быть 0.
это конечно да, но как узнать какое было состояние у окна до этого 0. Пример: пользователь работал с программой в режиме окна Maximized, свернул окно и забыл, что прога запущена, и пытается запустить приложение снова. Мой код развернет это окно в Normal - размер, а не так как было у пользователя до этого, т.е. задача сводится к тому, чтобы узнать, какое значение FormWindowState было у окна до сворачивания, и восстановить его.
0
37 / 35 / 7
Регистрация: 18.04.2009
Сообщений: 376
10.04.2012, 13:44 13
Цитата Сообщение от nio Посмотреть сообщение
немного не доделано разворачивание запущенной копии (не знаю как получить состояние окна, которое было до сворачивания)
В этом то и проблема, чтобы при повторном запуске окно разворачивать. Запрет запуска копии не проблема.
0
6048 / 3457 / 335
Регистрация: 14.06.2009
Сообщений: 8,136
Записей в блоге: 2
10.04.2012, 14:01 14
Цитата Сообщение от mutex Посмотреть сообщение
В этом то и проблема, чтобы при повторном запуске окно разворачивать.
показанный код разворачивает, но только в состояние Normal (или можно максимальное раскоментить).
Была такая мысль (пока что только теория): Приложение запускается, находит (уже показанным способом) запущенный экземпляр, отправляет ему какое-нить сообщение (типа "showyouself") и закрывается. Запущенный экземпляр, получив такое сообщение, отображает себя (при необходимости разворачивает до нужного размера). Собственно только в теории до сих пор, потому что никак не могу добраться до изучения межпроцессного взаимодействия, если у кого-то есть навыки в данной области, то должно быть не сложно.
1
1923 / 428 / 41
Регистрация: 12.07.2007
Сообщений: 2,062
11.04.2012, 04:35 15
Цитата Сообщение от nio Посмотреть сообщение
Была такая мысль (пока что только теория): Приложение запускается, находит (уже показанным способом) запущенный экземпляр, отправляет ему какое-нить сообщение (типа "showyouself") и закрывается.
Послать ему сообщение WM_ACTIVATEAPP
0
251 / 163 / 14
Регистрация: 10.03.2012
Сообщений: 544
11.04.2012, 19:01 16
Я вот тоже интересуюсь этим вопросом, как можно передать сообщение в уже запущенную копию своего приложения.
0
19 / 19 / 1
Регистрация: 28.02.2011
Сообщений: 72
11.04.2012, 20:16 17
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using System;
using System.Threading;
public static class Program {
public static void Main() {
Boolean createdNew;
// Try to create a kernel object with the specified name
using (new Semaphore(0, 1, "SomeUniqueStringIdentifyingMyApp", out createdNew)) {
if (createdNew) {
// This thread created the kernel object so no other instance of this
// application must be running. Run the rest of the application here...
} else {
// This thread opened an existing kernel object with the same string name;
// another instance of this application must be running now.
// There is nothing to do in here, let's just return from Main to terminate
// this second instance of the application.
}
}
}
}
Стибрино у Рихтера
1
37 / 35 / 7
Регистрация: 18.04.2009
Сообщений: 376
12.04.2012, 04:22 18
http://msdn.microsoft.com/ru-r... 00%29.aspx
для VB это оказывается можно сделать без особых заморочек.
В моей студии (VS 2010 Express) почему то этой опции я не нашел !!!
[censored] какая то !!!

Добавлено через 31 минуту
Вот еще решение.
http://developer.alexanderklim... stance.php
Причем оно как раз связанно с моим предыдущим постом.
Правда окно при развертывании к сожалению находиться в состоянии Normal.
0
2 / 2 / 1
Регистрация: 21.11.2015
Сообщений: 58
04.05.2016, 19:05 19
mutex, здравствуйте!
0
04.05.2016, 19:05
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
04.05.2016, 19:05
Помогаю со студенческими работами здесь

Запрет на запуск нескольких копий
Возможно ли сделать так, что может быть запущена только одна копия программы (копий несколько по...

Запуск нескольких копий приложения
Подскажите как сделать чтобы при запуске приложения,запускалось 4 собственные копии а при закрытии...

Запуск нескольких отдельных копий Edge
У меня стоит задача, авторизоваться на нескольких сайтах под разными логинами, одновременно и...

Чем чревато запуск нескольких копий агента на сервере?
Какие последствия могут быть если пользователь запустит (RunAgentOnServer) несколько копий агентов...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru