powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Запрет запуска второй копии приложения
25 сообщений из 28, страница 1 из 2
Запрет запуска второй копии приложения
    #32468060
Фотография vladgrig
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как запретить запускать копию приложения (написанного на VB.NET), если один раз приложение уже запущено и работает? Если можно, с примером...
...
Рейтинг: 0 / 0
Запрет запуска второй копии приложения
    #32468074
Фотография greenapple
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
http://www.ai.uga.edu/~mc/SingleInstance.html
...
Рейтинг: 0 / 0
Запрет запуска второй копии приложения
    #32468081
Фотография vladgrig
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пример классный, только нельзя его для меня интерпретировать на VB.NET plz. Во-первых аглицкий язык не мой родной (ну это ещё куда не шло), а во вторых C# - это точно не моё :((((
...
Рейтинг: 0 / 0
Запрет запуска второй копии приложения
    #32468100
Фотография greenapple
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
'Глобальная статическая переменная
    Shared mMutex As System.Threading.Mutex

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        Dim IsMutexCreatedSuccess As Boolean

        'Пытаемся создать собственный (для запущенного потока) блок взаимного исключения c именем  "qwerty" 
        Dim mMutex As New System.Threading.Mutex(True,  "qwerty" , IsMutexCreatedSuccess)

        'Если создание не получилось, т.е. такой объект в ОС уже есть, убиваем текущий процесс
        If IsMutexCreatedSuccess = False Then
            System.Diagnostics.Process.GetCurrentProcess.Kill()
        Else
            'Сохраняем наш мьютекс от активности сборщика мусора
            GC.KeepAlive(mMutex)
            'Далее нормальная загрузка
            '
            '
        End If

    End Sub
...
Рейтинг: 0 / 0
Запрет запуска второй копии приложения
    #32468103
Фотография greenapple
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сорри, неверно я наклавиатурил

mMutex = New System.Threading.Mutex(True, "qwerty", IsMutexCreatedSuccess)
...
Рейтинг: 0 / 0
Запрет запуска второй копии приложения
    #32468120
Фотография vladgrig
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да метод интересный и что главное, вроде работает ) Кстати декларировать ничего вне процедур не надо можно и так

Dim mMutex As New System.Threading.Mutex(True, "qwerty", IsMutexCreatedSuccess)

Без shared.

Спасибки.

Если кто знает ещё метод, пришлите, попробую.

Кстати, интересно отчего у людей такой интерес к C#?????
...
Рейтинг: 0 / 0
Запрет запуска второй копии приложения
    #32468151
Фотография vladgrig
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load

Dim k As Integer
Dim m As Process = Process.GetCurrentProcess()

Dim mm() As Process = Process.GetProcessesByName(m.ProcessName, "machine_name")
Dim p As Process

For Each p In mm
If p.MainModule.ModuleName = m.MainModule.ModuleName Then
k += 1
End If
Next
If k > 1 Then System.Diagnostics.Process.GetCurrentProcess.Kill()

End Sub


Во как!!! Остаётся тока програмно узнать имя машины???? (Может кто подскажет как???) :((( А количество копий можно задать параметром k>1 одна копия, k>2 две и т.д.
Вариант greenapple работает, но не всегда срабатывает почему-то, и всё равно ему огромное спасибо - это он меня натолкнул на мысль...
Извиняюсь что код опубликован не по правилам форума. На своём сайте http://kotishka.homeip.net обязательно положу этот листинг красиво оформленным...
...
Рейтинг: 0 / 0
Запрет запуска второй копии приложения
    #32469750
MeBy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Узнать имя машины можно так:

Переменная = Environment.MachineName
...
Рейтинг: 0 / 0
Запрет запуска второй копии приложения
    #32469775
Фотография greenapple
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
собственно по ссылке все написано, про переменные, и про скорость выполнения. На мой взгляд, если существующий процесс не нужен для каких-то целей, то лучше и правильнее более простой и быстрый метод.
По поводу не всегда работает, это может быть связано в частности с областью видимости ссылки на мьютекс.
Я не уверен в правильности вызова GC.KeepAlive(mMutex) в этом месте. Если кто-то знает, подскажите, плз.
...
Рейтинг: 0 / 0
Запрет запуска второй копии приложения
    #32469850
Фотография vladgrig
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не хотел я никого обидеть. Greenapple - в частности тебя. И пример мой, конечно пример с твоей ссылки, тока доработаный в VB.NET. Просто твой метод дейсвительно не всегда срабатывал :(((( А этот метод работает железно (пусть люди и то и то попробуют) - им выбирать. А может и другой, более рациональный метод предложат. Я бы с удовольствием рассмотрел и что-то другое. Меня теперь другой вопрос мучает. Если приложение повесить в трей и кто то нажмёт (не заметив его там) на запуск приложения второй раз - КАК ПРИЛОЖЕНИЕ ПОДНЯТЬ ИЗ ТРЕЯ????
...
Рейтинг: 0 / 0
Запрет запуска второй копии приложения
    #32470057
Flare
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
    Private Sub form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'Проверка, чтобы приложение не запускалось дважды, выполняется при загрузке программы (form1)
        If (UBound(Diagnostics.Process.GetProcessesByName(Diagnostics.Process.GetCurrentProcess.ProcessName)) >  0 ) Then
            MsgBox( "Программа уже запущена" , MsgBoxStyle.Exclamation,  "Программа" )
            End
        End If
    End Sub


Смысл в общем ясен?

А по второму вопросу - сырцы, поставляемые со средой разработки смотреть иногда не мешает для ознакомления.
...Visual Studio .NET/VB7/VB Samples/WinForms-SysTraySample/
Вот там и гляди и наступит тебе счастие :)
...
Рейтинг: 0 / 0
Запрет запуска второй копии приложения
    #32470441
Фотография vladgrig
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот, чувствуется рука мастера :)) Весь мой код уложил в одну строку... А насчёт сырцов - счастье тому у кого версия не палёная VS.NET В моей нет сырцов (к сожалению). Да и тему ты наверное не понял. Просто из трея поднять не проблема... Проблема поднять процессом, который мы потом убиваем
и кто то нажмёт (не заметив его там) на запуск приложения второй раз
...
Рейтинг: 0 / 0
Запрет запуска второй копии приложения
    #32470511
Фотография vladgrig
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Так и есть, во втором вопросе ты не разобрался. Я тут денежек не пожалел - купил нормальную VS.NET нашёл samples(system tray) Из bin стока солнышек поназапускалось в tray... А вот как чтоб это солнышко постоянно одно было - вот фишка???
...
Рейтинг: 0 / 0
Запрет запуска второй копии приложения
    #32471352
Нашёл как-то на www.gotdotnet.ru и перевёл на VB.NET
некоторые моменты наверное можно улучшить...

Код: plaintext
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.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
Imports System
Imports System.Threading
Imports System.Diagnostics
Imports System.Runtime.InteropServices

Public Class CheckOneInstance
	Shared mutex As Mutex

	Public Shared Function IsInstanceExist(ByVal activateFirstInstance As Boolean) As Boolean
		Dim currentProcess As Process = Process.GetCurrentProcess()
		Dim createdNew As Boolean
		'Имя Mutex'a состоит из имени исполняемого файла + строковая константа
		Dim mutexName As String = currentProcess.MainModule.ModuleName +  " One Instance Mutex Name" 
		mutex = New Mutex(False, mutexName, createdNew)

		If False = createdNew Then
			If False = activateFirstInstance Then Return True

			''получаем имя нашего процесса (название файла без расширения '.exe') 
			Dim processName As String = currentProcess.MainModule.ModuleName
			processName = processName.Substring( 0 , processName.IndexOf( ".exe" ))
			''перебираем все процессы с искомым именем 
			For Each process As Process In process.GetProcessesByName(processName)
				''текущий экземпляр нас не интересует 
				If process.Id <> currentProcess.Id Then
					''могут быть разные приложения с одинаковым именем 
					''исполняемого файла. Проверяем что-бы это был 'наш' файл 
					If process.MainModule.FileName = currentProcess.MainModule.FileName Then
						Dim hWnd As IntPtr

						If process.MainWindowHandle.Equals(IntPtr.Zero) Then
							''По каким-то причинам(например у окна ShowInTaskBar = false)
							''MainWindowHandle равен  0 . Попытаемся найти окно при помощи
							''Win32 API функций
							hWnd = FindWindowEngine.Find(process.Id)
							If hWnd.Equals(IntPtr.Zero) Then Exit For ''Окно так и неудалось найти, выходим.
						Else
							hWnd = process.MainWindowHandle
							''Активизируем окно приложения 
							If True = IsIconic(hWnd) Then
								ShowWindow(hWnd, SW_RESTORE)
							Else
								SetForegroundWindow(hWnd)
								Exit For
							End If
						End If
					End If
				End If
			Next

			Return True
		End If

		Return False
	End Function

	<DllImport( "User32.dll" )> _
	Public Shared Function SetForegroundWindow(ByVal hWnd As IntPtr) As Boolean
	End Function

	<DllImport( "User32.dll" )> _
	Public Shared Function IsIconic(ByVal hWnd As IntPtr) As Boolean
	End Function

	<DllImport( "User32.dll" )> _
	Public Shared Function ShowWindow(ByVal hWnd As IntPtr, ByVal nCmdShow As Int32) As Boolean
	End Function

	Const SW_RESTORE As Int32 =  9 
End Class

''Этот класс предоставляет метод для поиска среди окон 'верхнего уровня'
''окна созданного указанным процессом
Public Class FindWindowEngine

	''Создавать экземпляры этого класса нет смысла
	Public Sub New()
		MyBase.New()
	End Sub
	Shared hWndFirstInstance As IntPtr

	Public Shared Function Find(ByVal processID As Int32) As IntPtr
		Dim enumProc As EnumWindowsProcDelegate = New EnumWindowsProcDelegate(AddressOf EnumWindowsProc)
		''Перебираем все окна 'верхнего' уровня
		EnumWindows(enumProc, IntPtr.op_Explicit(processID))
		Return hWndFirstInstance
	End Function

	Shared Function EnumWindowsProc(ByVal hWnd As IntPtr, ByVal lParam As IntPtr) As Boolean
		Dim processIDFinded As Int32
		''Получаем ID процесса, создавшего данный hWnd 
		GetWindowThreadProcessId(hWnd, processIDFinded)
		If processIDFinded = lParam.ToInt32() Then
			''Нашли искомый процесс
			''сохраняем hWnd и прекращаем перебор окон
			hWndFirstInstance = hWnd
			Return False
		End If
		''продолжаем перебор окон
		Return True
	End Function

	''Делегат для функции EnumWindows
	Delegate Function EnumWindowsProcDelegate(ByVal hWnd As IntPtr, ByVal lParam As IntPtr) As Boolean

	<DllImport( "User32.dll" )> _
	Public Shared Function EnumWindows(ByVal lpEnumFunc As EnumWindowsProcDelegate, ByVal lParam As IntPtr) As Boolean
	End Function

	<DllImport( "User32.dll" )> _
	Public Shared Function GetWindowThreadProcessId(ByVal hWnd As IntPtr, ByRef pdwProcessId As Int32) As Int32
	End Function
End Class
...
Рейтинг: 0 / 0
Запрет запуска второй копии приложения
    #32471360
Фотография vladgrig
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Странные Вы, Господа - это наверное потому, что от рождения такие умные ( перевёл с одного языка на другой ). А мне действительно интересно всё это узнать (и листинг этот длинный по случаю найденный и ЛЮБЕЗНО переведённый попробую). А главное тема то действительно интересная - ВОН как количество просмотров растёт. Людям нужно простые вещи выяснить, а Вы как тихоокеанские лайнеры снисхождение делаете... Выясняете какой язык лучше VB или C#, а помочь нам неразумным в ТЯГОСТЬ. За ответы всем БОЛЬШОЕ тихоокеанское СПАСИБО. Но не надейтесь, что я на этом остановлюсь - возникнут вопросы ОБЯЗАТЕЛЬНО потревожу Вашу водную стихию ))
С уважением vladgrig
...
Рейтинг: 0 / 0
Запрет запуска второй копии приложения
    #32471723
vladgrig
Странные Вы, Господа - это наверное потому, что от рождения такие умные (перевёл с одного языка на другой). А мне действительно интересно всё это узнать (и листинг этот длинный по случаю найденный и ЛЮБЕЗНО переведённый попробую). А главное тема то действительно интересная - ВОН как количество просмотров растёт. Людям нужно простые вещи выяснить, а Вы как тихоокеанские лайнеры снисхождение делаете... Выясняете какой язык лучше VB или C#, а помочь нам неразумным в ТЯГОСТЬ. За ответы всем БОЛЬШОЕ тихоокеанское СПАСИБО. Но не надейтесь, что я на этом остановлюсь - возникнут вопросы ОБЯЗАТЕЛЬНО потревожу Вашу водную стихию ))
С уважением vladgrig

1. Это верно умные от рождения потом глупеем...
2. Найден был не по случаю а в результате поиска и переведён не из любезности а для себя поскольку интересовался темой
3. Коментарии автора остались в первозданном виде вроде всё должно быть понятно на крайний случай (самый крайний) есть MSDN
4. Думаю что тот язык лучше тот в котором Вы лучше себя чувствуете
5. За спасибо Вам чуть менее большое балтийское пожалуйста
...
Рейтинг: 0 / 0
Запрет запуска второй копии приложения
    #32471837
Фотография vladgrig
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хорошо, не будем препираться (дело от этого не выйграет). Я не скрываю что только начинаю учёбу VB (возникла необходимость по работе, да и самому интересно стало). С приведёнными Вами классами я как начинающий вроде разобрался, (благо книга была под рукой) создал dll, монтирую её в проект, CheckOneInstance.IsInstanceExist - это понятно, а остальное нельзя по подробней plz. Думаю всем таким же как я будет крайне интересно прочесть.
...
Рейтинг: 0 / 0
Запрет запуска второй копии приложения
    #32472040
Фотография greenapple
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 желаю знать почему

Спасибо, очень полезный пример. Надо бы добавить GC.KeepAlive, раз Jon Skeet советует

2 vladgrig
надо стремиться к знанию и C# и VB.NET, это достижимо
...
Рейтинг: 0 / 0
Запрет запуска второй копии приложения
    #32472229
Фотография vladgrig
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim a As New CheckOneInstance
        If a.IsInstanceExist(True) Then
            Me.Close()
        End If
End Sub

greenaple, хоть Вы накрапайте, правильно ли я понял функцию созданного класса??? И по остальным его функциям маленький экскурс... plz (обещаю, что буду учить и C#)...
...
Рейтинг: 0 / 0
Запрет запуска второй копии приложения
    #32472560
Фотография greenapple
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нет, не правильно, но прогресс есть :):

Dim a As New CheckOneInstance
это писать не нужно, члены shared, инстанс не нужен

функция проверяет, есть ли экземпляр приложения, а фактически проверяет, захвачен ли мьютекс с определенным именем в операционной системе, или нет.
Если он захвачен, то она завершается с результатом False (самая последняя строка в ней)
Если нет, то проверяется, нужно ли активировать (показывать) окно (If False = activateFirstInstance Then Return True), если нет - просто выход с параметром True.
Если да, то на основе текущего процесса действуем с окном.
Класс FindWindowEngine нужен для поиска окон.


Вот это:
<DllImport("User32.dll")> _

это добавление вызовов API-функций из User32.dll, библиотеки для интерфейса пользователя


Кстати, пока писал, совет созрел:
''Создавать экземпляры этого класса нет смысла
Public Sub New()
MyBase.New()
End Sub

можно написать просто

Private Sub New()
MyBase.New()
End Sub
...
Рейтинг: 0 / 0
Запрет запуска второй копии приложения
    #32472564
Фотография greenapple
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
да, получив из этой функции True результат

System.Diagnostics.Process.GetCurrentProcess.Kill()
...
Рейтинг: 0 / 0
Запрет запуска второй копии приложения
    #32472751
vlsdgrig
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Да уж, еле-еле душа в теле... Спасибки за науку... Поучительно...

Код: plaintext
1.
2.
3.
4.
5.
6.
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load

        If CheckOneInstance.IsInstanceExist(True) Then
            System.Diagnostics.Process.GetCurrentProcess.Kill()
        End If

End Sub

Я надеюсь так - ПРАВИЛЬНО.
Главное, что этот метод поднимает минимизированное окно первого процесса (возможно нехотя дали ответ и на второй интересующий меня вопрос)
Для меня эта тема является закрытой.
Всем СПАСИБО (большое и человеческое)
P.S. До встречи на следующих дебатах ;)
...
Рейтинг: 0 / 0
Запрет запуска второй копии приложения
    #32475146
закралась пара ошибок...
вместо
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
If process.MainWindowHandle.Equals(IntPtr.Zero) Then
	''По каким-то причинам(например у окна ShowInTaskBar = false)
	''MainWindowHandle равен  0 . Попытаемся найти окно при помощи
	''Win32 API функций
	hWnd = FindWindowEngine.Find(process.Id)
	If hWnd.Equals(IntPtr.Zero) Then Exit For ''Окно так и неудалось найти, выходим.
Else
	hWnd = process.MainWindowHandle
	''Активизируем окно приложения 
	If True = IsIconic(hWnd) Then
		ShowWindow(hWnd, SW_RESTORE)
	Else
		SetForegroundWindow(hWnd)
		Exit For
	End If
End If

должно быть
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
If process.MainWindowHandle.Equals(IntPtr.Zero) Then
	''По каким-то причинам(например у окна ShowInTaskBar = false)
	''MainWindowHandle равен  0 . Попытаемся найти окно при помощи
	''Win32 API функций

	hWnd = FindWindowEngine.Find(process.Id)
	If hWnd.Equals(IntPtr.Zero) Then Exit For ''Окно так и неудалось найти, выходим.
Else
	hWnd = process.MainWindowHandle
End If

''Активизируем окно приложения 
If True = IsIconic(hWnd) Then
	ShowWindow(hWnd, SW_RESTORE)
Else
	SetForegroundWindow(hWnd)
End If

Exit For
...
Рейтинг: 0 / 0
Запрет запуска второй копии приложения
    #32475171
а использовать наверное будет лучше так
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
Public Class myMainForm : Inherits System.Windows.Forms.Form
	Public Shared Sub Main()
		If True = CheckOneInstance.IsInstanceExist(True) Then Return

		Application.Run(New myMainForm)
	End Sub
''
''
''
End Class


2 greenapple
GC.KeepAlive в данном примере мне представляется не нужным
...
Рейтинг: 0 / 0
Запрет запуска второй копии приложения
    #32475555
Фотография vladgrig
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хорошо, разговоры продолжаются (можно я ещё вопрос задам?)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
Private Sub Form1_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Resize
        If Me.WindowState = FormWindowState.Minimized Then
            ShowInTaskbar = False
            NotifyIcon.Visible = True
        End If
End Sub

Private Sub NotifyIcon_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles NotifyIcon.Click
        Me.WindowState = FormWindowState.Normal
        ShowInTaskbar = True
        NotifyIcon.Visible = False
End Sub

Этот пример я нашёл на dotnet.ru . Попробовал с Вашим классом - не поднимает форму :(((
Если есть возможность может и это можно решить (где то, например, в ваш класс решение вставить)???
И тогда, на мой взгляд, класс будет - ПРОСТО КЛАСС (я не язвлю, а выражаю собственный восторг от всего сердца)
P.S. Приложение в системтрай - это не необходимость (для меня), посему вопрос - теоретический. Заранее извиняюсь, если я этой функции не заметил в Вашем классе (если так, то опишите как её найти и использовать, plz)
...
Рейтинг: 0 / 0
25 сообщений из 28, страница 1 из 2
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Запрет запуска второй копии приложения
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]