Что нового

Запустить программу, не зная пути к файлу

Сообщения
142
Репутация
-3
Нужно запустить программу, которая не идет по умолчанию с Windows и не у всех на компьютере есть. Известно имя файла program.exe, однако, так как путь к нему и названия папой могут быть пользовательскими, указать его напрямую нельзя. Известно также, что при установке программа следит (запись в реестре, ярлыки).

Что и как использовать для того, чтобы реализовать:
1. Проверку "установлена ли программа".
2. Запуск программы.
 

Torotin

Новичок
Сообщения
10
Репутация
2
Правильно ли я понимаю, что программа проходит пользовательский процесс инсталляции ПО через Windows Installer и т.п.?

Отправлено с моего SM-N950F через Tapatalk
 
Автор
Э
Сообщения
142
Репутация
-3
Torotin сказал(а):
Правильно ли я понимаю, что программа проходит пользовательский процесс инсталляции ПО через Windows Installer и т.п.?
Программа либо уже установлена или не установлена. Как я уже записал, ярлыки и записи в реестре установщиком создаются.

Можно, конечно, заставить пользователя указать на каталог и файл. Однако, хочется избавить пользователя от лишних действий. Я еще вижу вариант - в реестре найти. Иных коротких путей я не знаю.
Хотя, вот ещё. Процесс может быть уже запущен. Как-то можно выдернуть оттуда путь к файлу?
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
все есть на форуме. и поиск по реестру и по запущенному процессу
 

Torotin

Новичок
Сообщения
10
Репутация
2
ЭйчЭйч сказал(а):
Как я уже записал, ярлыки и записи в реестре установщиком создаются.

Для стандартно установленных программ, которые прописывают себя в реестре я использую представленную ниже конструкцию.
Немного кривовато, но для моих целей этого хватает.
Посмотрите, может Вам чем-то поможет.

Код:
Func _ProgInfo($Program, $Action = "Version")

	Local $RegRoot, $RegKey, $ProgVer, $ProgName, $UninstallStrRead, $UninstallStr, $pNotInstall
	$RegRoot = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
	If $Action = "" Then $Action = "Version"

	For $i = 1 To 999
		$RegKey = RegEnumKey($RegRoot, $i)
		If @error Then ExitLoop
		$ProgName = RegRead($RegRoot & "\" & $RegKey, "DisplayName")
		If $Program = $ProgName Then
			ConsoleWrite("Find " & $Program & " OK")
			ExitLoop
		EndIf
	Next


	If $Program = $ProgName Then
		Switch $Action
			Case "Delete"
				$UninstallStrRead = RegRead($RegRoot & "\" & $RegKey, "UninstallString")
				$MsiExec = StringRegExp($UninstallStrRead, "(MsiExec.exe)(.*)")
				If $MsiExec <> 0 Then
					$UninstallStr = StringRegExpReplace($UninstallStrRead, "(.*)(/I)(.*)", "$1 /x $3 /passive")
					ConsoleWrite(@ComSpec & " /c " & $UninstallStr)
					RunWait(@ComSpec & " /c " & $UninstallStr, '', @SW_HIDE)
				Else
					ConsoleWrite(@ComSpec & " /c " & $UninstallStrRead)
					RunWait(@ComSpec & ' /c "' & $UninstallStrRead & '"', '', @SW_HIDE)
				EndIf
			Case "Version"
				$ProgVer = RegRead($RegRoot & "\" & $RegKey, "DisplayVersion")
				ConsoleWrite($ProgName & " version: " & $ProgVer)
				Return $ProgVer
		EndSwitch
	Else
		$pNotInstall = "NO installed"
		ConsoleWrite($Program & " " & $pNotInstall)
		Return $pNotInstall
	EndIf
EndFunc
 
Автор
Э
Сообщения
142
Репутация
-3
Крутая конструция, вытаскивает всё.

Я обошёлся:

Код:
$sSoftTitle = 'MySoft'
$sRegPath = 'HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\' & $sSoftName
$aPath = StringRegExp(RegRead($sRegPath, 'DisplayIcon'), '(.*?)u', 1)
If IsArray($aPath) Then
   $sPath = $aPath[0]
Else
; предложить иной путь
EndIf

Мне кажется, что я с регулярным накосячил. Возвращается путь C:\Folder0\Folder1\MySoft\uninstaller.exe, где uninstaller.exe мне нужно отбросить. Также меня смущает Wow6432Node, я думаю, что на Windows XP такого нет. То есть, метод накроется медным тазом.
 

Torotin

Новичок
Сообщения
10
Репутация
2
ЭйчЭйч сказал(а):
Мне кажется, что я с регулярным накосячил. Возвращается путь C:\Folder0\Folder1\MySoft\uninstaller.exe, где uninstaller.exe мне нужно отбросить.

Можно посмотреть в этой теме Деление пути к файлу на части

ЭйчЭйч сказал(а):
Также меня смущает Wow6432Node, я думаю, что на Windows XP такого нет. То есть, метод накроется медным тазом.

По умолчанию редактор реестра 64-разрядных версий Windows отображает 32-разрядные разделы в разделе
Код:
[HKEY_LOCAL_MACHINE\Software\WOW6432Node]
Можно попробовать пойти через уже существующие макросы и делать ветвление в зависимости от установленной ОС и её разрядности.

Код:
@OSArch	; Возвращает одно из следующих значений: "X86", "IA64", "X64" - это тип архитектуры запущенной операционной системы
@OSVersion	;Возвращает одно из следующих значений: "WIN_2008R2", "WIN_7", "WIN_8", "WIN_2008", "WIN_VISTA", "WIN_2003", "WIN_XP", "WIN_XPe", "WIN_2000"
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
Код:
#include <Array.au3>
Local $aArray = _CGW()
_ArrayDisplay($aArray)
Func _CGW()
	Local $all_key[3]
	$all_key[0] = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
	$all_key[1] = "HKEY_LOCAL_MACHINE64\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
	$all_key[2] = 'HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Uninstall'
	Local $aSA[1][2], $AppKey_all, $n = 0, $X = 1, $rn, $il
	For $i = 0 To 2
		Local $a = 1
		While 1
			$AppKey_all = RegEnumKey($all_key[$i], $a)
			If Not $AppKey_all Then ExitLoop
			$rn = StringStripWS(StringReplace(RegRead($all_key[$i] & "\" & $AppKey_all, "DisplayName"), " (remove only)", ""), 3)
			$il = StringStripWS(RegRead($all_key[$i] & "\" & $AppKey_all, "InstallLocation"), 3)
			If $rn <> '' And $il <> '' Then
				ReDim $aSA[$X][2]
				$aSA[$n][0] = $rn
				If StringRight($il, 1) = '\' Then $il = StringTrimRight($il, 1)
				$aSA[$n][1] = StringReplace($il, '"', '')
				$n += 1
				$X += 1
			EndIf
			$a += 1
		WEnd
	Next
	Return $aSA
EndFunc   ;==>_CGW
выдает в массив название программ и директория установки
найти в массиве методом сравнения по имени и запустить экзешник. если, конечно же, он лежит в корне)
 
Автор
Э
Сообщения
142
Репутация
-3
Torotin, я посмотрел ветку на Windows 7x64
Код:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
В ней можно найти что угодно, кроме той программы, что я ищу. Поэтому имей ввиду, что не универсальная вещь. Это для какой ОС вариант?

Да, можно ветвление сделать. Однако, на мой взгляд проще будет обработать ошибку и перейти к другому разделу.
 

Torotin

Новичок
Сообщения
10
Репутация
2
ЭйчЭйч сказал(а):
Torotin, я посмотрел ветку на Windows 7x64
Код:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
В ней можно найти что угодно, кроме той программы, что я ищу. Поэтому имей ввиду, что не универсальная вещь. Это для какой ОС вариант?

Да, можно ветвление сделать. Однако, на мой взгляд проще будет обработать ошибку и перейти к другому разделу.

Код писался для Win7Pro x86.
Скажу больше:
1) в исходных данных разговор о х64 ветке реестра не шёл.
2) всю необходимую информацию касаемо "подгонки" исходника под свои нужды были предоставлены и их можно найти здесь на форуме.

Отправлено с моего SM-N950F через Tapatalk
 
Автор
Э
Сообщения
142
Репутация
-3
Torotin, это не претензия к коду, а интерес. Подогнать - не вопрос.
 
Верх