Что нового

[Данные, строки] Получить строку из ресурса с помощью_WinAPI_LoadString

erlik

Продвинутый
Сообщения
317
Репутация
84
Собственно проблем с большинством ресурсов нет, но затык приключился вот с этой строкой '@%SystemRoot%\explorer.exe,-7023'. Она должна сконвертироваться в строку
'Выполнить...' Но возвращается пустая строка.
Ниже код, который я использую для получения строки из ресурсов dll и exe:
Код:
#include <WinAPIEx.au3>
#include <WinAPI.au3>
#include <APIConstants.au3>

;Local $sDescription ='@%SystemRoot%\System32\display.dll,-4'
;Local $sDescription = '@%ProgramFiles%\Windows Sidebar\sidebar.exe,-11100'
;Local $sDescription = '@%systemroot%\system32\themecpl.dll,-10'
Local $sDescription ='@%SystemRoot%\explorer.exe,-7023'
; Должна  вернуться строка 'Выполнить...'
If StringInStr($sDescription,'@') Then
    Local $aString,$sPath,$sModule,$hModule
		$aString   = StringSplit($sDescription,',',2)                   ; разбиваем строку на путь и номер ресурса
		$sPath     = StringMid($aString[0],2,-1)                        ; удаляем символ @ из строки
		$iStringId = StringRegExpReplace($aString[1],'^(-?)','',1)      ; удаляем знак -(минус) перед цифрами так как иначе _WinAPI_LoadString ничего не возвращает
		$sPath     = _WinAPI_ExpandEnvironmentStrings($sPath)           ; конвертируем возможные переменные окружения в пути
		$sModule   =_WinAPI_PathFindFileName($sPath)                    ; извлекаем имя файла из пути 
		$hModule   = _WinAPI_OpenProcess(_Iif($__WINVER< 0x0600, 0x00000410, 0x00001010), 0, ProcessExists($sModule))
			If Not $hModule Then
				$hModule =_WinAPI_LoadLibraryEx($sPath, $LOAD_LIBRARY_AS_DATAFILE)
					If Not $hModule Then
						DllOpen($sPath)
						ConsoleWrite('DllOpen|' & $sModule & @CRLF)
						$hModule=_WinAPI_GetModuleHandle($sPath)
						If Not $hModule Then $hModule=_WinAPI_GetModuleHandle($sModule)
					EndIf
			EndIf
		$sDescription=_WinAPI_LoadString($hModule, $iStringId)
		If $sDescription = '' Then $sDescription=_WinAPI_LoadString($hModule, $aString[1])      ; на всякий случай - хотя все равно не работает
		_WinAPI_FreeLibrary($hModule)
        ConsoleWrite("Module=" & $sModule & "|Handle="&  $hModule&"|Строка=" & $sDescription &"|Index raw=" & $aString[1] & "|Index Clear=" & $iStringId & @CRLF)
EndIf


То что он работает можете проверить раскомментировав любую другую строку. Но с той, что указал - нет. При этом сама строка правильная - система, считывая ее из реестра, строку извлекает и отображает в контекстном меню. В чем тут может быть проблема - дескриптор explorer'а получается, а строка не извлекается...?
--------------------------------
Извиняюсь - номер -7023, а не -7022. Эксперементировал да забыл обратно вернуть. Никакой вариант, впрочем, все равно не работает.
 

ivsatel

Продвинутый
Сообщения
319
Репутация
84
erlik

Код:
#include <Misc.au3>
#include <WinAPIEx.au3>
#include <WinAPI.au3>
#include <APIConstants.au3>

;Local $sDescription ='@%SystemRoot%\System32\display.dll,-4'
;Local $sDescription = '@%ProgramFiles%\Windows Sidebar\sidebar.exe,-11100'
;Local $sDescription = '@%systemroot%\system32\themecpl.dll,-10'
Local $sDescription = '@%SystemRoot%\explorer.exe,-7023'
; Должна  вернуться строка 'Выполнить...'
If StringInStr($sDescription, '@') Then
	Local $aString, $sPath, $sModule, $hModule
	$aString = StringSplit($sDescription, ',', 2) ; разбиваем строку на путь и номер ресурса
	$sPath = StringMid($aString[0], 2, -1) ; удаляем символ @ из строки
	$iStringId = StringRegExpReplace($aString[1], '^(-?)', '',1) ; удаляем знак -(минус) перед цифрами так как иначе _WinAPI_LoadString ничего не возвращает
	$sPath = _WinAPI_ExpandEnvironmentStrings($sPath) ; конвертируем возможные переменные окружения в пути
	$sModule = _WinAPI_PathFindFileName($sPath) ; извлекаем имя файла из пути
	$hModule = _WinAPI_OpenProcess(_Iif($__WINVER < 0x0600, 0x00000410, 0x00001010), 0, WinGetProcess($sModule), True)
	If Not $hModule Then
		$hModule = _WinAPI_LoadLibraryEx($sPath, $LOAD_LIBRARY_AS_DATAFILE)
		If Not $hModule Then
			DllOpen($sPath)
			ConsoleWrite('DllOpen|' & $sModule & @CRLF)
			$hModule = _WinAPI_GetModuleHandle($sPath)
			If Not $hModule Then $hModule = _WinAPI_GetModuleHandle($sModule)
		EndIf
	EndIf
	$sDescription = _WinAPI_LoadString($hModule, $iStringId)
	ConsoleWrite(' 1 = '&$sDescription&@LF)
	If $sDescription = '' Then $sDescription = _WinAPI_LoadString($hModule, $aString[1]) ; на всякий случай - хотя все равно не работает
	_WinAPI_FreeLibrary($hModule)
	ConsoleWrite("Module=" & $sModule & "|Handle=" & $hModule & "|Строка=" & $sDescription & "|Index raw=" & $aString[1] & "|Index Clear=" & $iStringId & @CRLF)
EndIf
 
Автор
E

erlik

Продвинутый
Сообщения
317
Репутация
84
ivsatel
Гениально :ok:
Даже в голову не пришло получить идентификатор эксплорера этой функций - WinGetProcess.
Возможно тут дело в том, что у меня для каждого окна свой процесс explorer'а запускается (так винда настроена), а ProcessExists возвращала идентификатор первого по списку - ну, в общем, не того получается эксплорера. Возьмем это на заметку.
Проблема решена. Большое спасибо :smile:
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Зачем так все усложнять?

Код:
_WinAPI_LoadIndirectString('@%SystemRoot%\explorer.exe,-7023')
 
Автор
E

erlik

Продвинутый
Сообщения
317
Репутация
84
Yashied
Спасибо. WinAPIEx.au3 отличная библиотека, но за два года ее использования всю 1000 функций пока не освоил (плохое знание английского сказывается), поэтому даже не знал, что есть готовая функция для такого случая.
 
Верх