Форум программистов, компьютерный форум, киберфорум
Visual Basic
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.75/16: Рейтинг темы: голосов - 16, средняя оценка - 4.75
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18030 / 7733 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16

Как узнать объект ярлыка в 64-битной ОС

19.03.2014, 02:42. Показов 3471. Ответов 30

Студворк — интернет-сервис помощи студентам
Имею ярлык к Internet Explorer. Браузер находится в папке C:\program files
При выполнении кода:
Visual Basic
1
msgbox CreateObject("WScript.Shell").CreateShortcut(Link).TargetPath
получаю путь C:\program files (x86)

Воспользовался файловой переадресацией = не помогает.

Кликните здесь для просмотра всего текста

Visual Basic
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
Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long
Private Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Long
Private Declare Function GetCurrentProcess Lib "kernel32" () As Long
Private Declare Function IsWow64Process Lib "kernel32" (ByVal hProc As Long, bWow64Process As Boolean) As Long
Private Declare Function GetSystemWow64Directory Lib "kernel32.dll" Alias "GetSystemWow64DirectoryA" (ByVal lpBuffer As String, ByVal uSize As Long) As Long
Private Declare Function Wow64DisableWow64FsRedirection Lib "kernel32" (ByRef oldvalue As Long) As Boolean
Private Declare Function Wow64RevertWow64FsRedirection Lib "kernel32" (ByVal oldvalue As Long) As Boolean
 
Option Explicit
 
Private Sub main()
    Dim lWow64RedirectReturn As Long: lWow64RedirectReturn = 0
    Dim ret As Boolean
    
    Dim is64 As Boolean: is64 = Is64bitOS
    Debug.Print "Is OS 64-bit? " & is64
    
    If is64 Then ret = Wow64DisableWow64FsRedirection(lWow64RedirectReturn)
    Debug.Print "API = " & ret
    CheckRedirection
    GetLinkTarget
 
    If is64 Then ret = Wow64RevertWow64FsRedirection(lWow64RedirectReturn)
    Debug.Print "API = " & ret
    CheckRedirection
    GetLinkTarget
End Sub
 
Public Function Is64bitOS() As Boolean
    Dim bWow64Process As Boolean
    Dim handle As Long: handle = GetProcAddress(GetModuleHandle("kernel32"), "IsWow64Process") ' if IsWow64Process function exists
    If handle > 0 Then IsWow64Process GetCurrentProcess(), bWow64Process ' Is running under Wow64
    Is64bitOS = bWow64Process
End Function
 
Sub CheckRedirection()
    Dim exe: exe = Environ("SystemRoot") & "\system32\msg.exe"
    Debug.Print "Redirect = " & (Dir$(exe, vbReadOnly Or vbSystem Or vbHidden) <> vbNullString)
End Sub
 
Sub GetLinkTarget()
    Dim Link: Link = "C:\Users\Alex\Desktop\IE.lnk"
    Dim oLink: Set oLink = CreateObject("WScript.Shell").CreateShortcut(Link)
    Debug.Print oLink.TargetPath
    'Debug.Print oLink.WorkingDirectory
End Sub


1) Какие будут советы?
2) Может есть где спецификация самого формата данных?
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
19.03.2014, 02:42
Ответы с готовыми решениями:

Как узнать, подвержена ли 64-битной переадресации указанная ветвь реестра?
Как это узнать программно? Кроме, как прямым сравнением со списком из базы знаний. И можно ли узнать новую цель (подраздел) после...

CMD/BAT: Узнать параметры ярлыка
Приветствую! Нужно узнать параметр (т.е. зачастую это &quot;C:\LOLKEK\app.exe -browser&quot;) ярлыков на рабочем столе (всех). Т.е. просто...

Как узнать существует ли объект ?
Родился новый вопрос: как узнать существует ли объект ??? тоесть есть ли в сесии Session('anArr'). в VB есть isObject, а как на...

30
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18030 / 7733 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
29.03.2014, 21:05  [ТС]
Студворк — интернет-сервис помощи студентам
Кстати, откуда такая инфа?
Цитата Сообщение от The trick Посмотреть сообщение
Переадресация работает только на System32/SysWOW64
0
Модератор
10046 / 3892 / 883
Регистрация: 22.02.2013
Сообщений: 5,844
Записей в блоге: 79
29.03.2014, 22:15
Цитата Сообщение от Dragokas Посмотреть сообщение
Кстати, откуда такая инфа?
http://msdn.microsoft.com/en-u... s.85).aspx
0
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18030 / 7733 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
30.03.2014, 02:45  [ТС]
Видел. Да, действительно, пишут только о System32/SysWow64.
Вопрос только, является ли преадресация Program Files -> Program Files(x86) частью этого механизма (но ее не упомянули в статье) или проблема с определением ярлыка - это особый частный случай. (я склоняюсь ко второму)

Цитата Сообщение от The trick Посмотреть сообщение
Цитата Сообщение от Dragokas
Вопрос на засыпку: почему тогда на команду Kill не действует правило переадресации "Program Files" -> "Program Files (x86)" ?
Kill для удаления файла вызывает API DeleteFileA из kernel32, Shell32 использует PIDL для идентификации,и возможно (пока не смотрел) меняет еще на этапе загрузки.
"DeleteFileA из kernel32" - За браком знаний в контексте данной темы это мне ни о чем не говорит, к сожалению.

Вот факт - из 32-битного процесса:

Kill "c:\windows\system32\file.txt"
удаляет файл в папке syswow64

kill "c:\program files\file.txt"
этот самый файл и удаляет. Переадресации нет.

P.S. Скомпилировал код C++ от Peter Thoemmes для выдергивания пути из ярлыка согласно спецификации.
Еще пригодится для будущих экспериментов.
Вложения
Тип файла: zip ReadLnkFile.zip (102.6 Кб, 5 просмотров)
0
Модератор
10046 / 3892 / 883
Регистрация: 22.02.2013
Сообщений: 5,844
Записей в блоге: 79
30.03.2014, 09:27
Цитата Сообщение от Dragokas Посмотреть сообщение
является ли преадресация Program Files -> Program Files(x86) частью этого механизм
Нет же я написал. Это "проделки" Shell32.
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
31.03.2014, 22:18
Лучший ответ Сообщение было отмечено The trick как решение

Решение

Насколько мне известно, файловые WOW64-редиректы работают только
для системных папок.

Для Program Files действует другой механизм.

Во-первых, у WOW64-процессов системная переменная ProgramFiles указывает на
"C:\Program Files (x86)".

Во-вторых, системные функции получения стандартных путей типа SHGetFolderPath
для WOW64-процессов тоже возвращают 32-битную "Program Files (x86)".

В-третьих, если WOW64-процесс пишет в реестр строковое значение,
содержащее путь к одной из системных папок, в том числе и "Program Files",
он автоматически преобразуется системой к 32-битному варианту.
За это уже отвечает registry redirector.

Но в остальном нет никаких препятствий, чтобы 32-битный exe поставить и
запускать из 64-битной "нативной" папки "Program Files", то же самое,
по идее, должно действовать и для ярлыков.

Хотя если 32-битная программа захочет "узнать", где находится "Program Files",
система неизбежно "подсунет" ей "Program Files (x86)".

Вот таким скриптом я создаю ярлык на запуск 64-битного Internet Explorer, и
не имеет значения, ни из-под какого процесса этот ярлык создается и запускается
(32 или 64 бита) - во всех случаях наблюдаю запуск именно 64-битной версии IE,
никаких редиректов в "Program Files (x86)" нету:
Visual Basic
1
2
3
4
5
6
set WshShell = WScript.CreateObject("WScript.Shell")
set Link = WshShell.CreateShortcut("C:\Scripts\ShortcutToIe64.lnk")
Link.TargetPath = "C:\Program Files\Internet Explorer\iexplore.exe"
Link.Save()
 
msgbox Link.TargetPath
Добавлено через 8 минут
Dragokas, кстати, откуда в исходном коде, приведенном в
первом сообщении темы, берется Program Files ? Не нашел.
Может, он уже "приходит" туда в 32-битном обличии (x86) ?
2
Модератор
10046 / 3892 / 883
Регистрация: 22.02.2013
Сообщений: 5,844
Записей в блоге: 79
31.03.2014, 22:36
На "обычные" API переадресация не работает с Program Files (CreateFile, FindFirstFile, GetFileAttributes и т.п.), работает только с функциями SHELL, так в MSDN и написано. Например написав в VB
Visual Basic
1
Open "C:\Program Files\tmp" For Bianry...
файл создастся именно там.
Dragokas, ты писал парсер, проверь чем отличается (изнутри) ярлык созданный через Explorer и через скрипт Убежденного (если он у тебя отрабатывает).
0
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18030 / 7733 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
31.03.2014, 23:43  [ТС]
Убежденный, превосходное наблюдение.
Ярлык создается примерно в 2х раза меньшего размера, при этом папка Program Files считывается из него без "переадресации" в отличие от ярлыка нативно созданного через explorer.
Создавал таким кодом под x32 процессом

Visual Basic
1
2
3
4
5
6
7
set oShell = CreateObject("WScript.Shell")
set oLink = oShell.CreateShortcut("C:\users\alex\desktop\ie_vbs.lnk")
oLink.TargetPath = "C:\Program Files\Internet Explorer\iexplore.exe"
oLink.WorkingDirectory = "C:\Program Files\Internet Explorer"
oLink.Save
 
msgbox oLink.TargetPath


Есть различия в 1 байте (смещение 16), а также всех байтов, начиная с 2DF (ярлыки приаттачил).
Пробую соотнести со спецификацией.
________________________
смещение 14 (4 байта) - LinkFlags, задающий наличие секций.
9B 00 00 00 (vbs) - отсутствует секция "EnableTargetMetadata".
9B 00 08 00 (explorer)

Да, похоже виноват алгоритм обработки KnownFolder.

Заодно еще один парсер нашел - shellify.
Вложения
Тип файла: zip Links.zip (1.4 Кб, 4 просмотров)
1
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18030 / 7733 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
01.04.2014, 00:45  [ТС]
А вот похоже и сам код, который Microsoft использует в ОС
для получения пути для указанного Known Folder GUID: CppShellKnownFolders
В нем используется функция SHGetKnownFolderPath.

Скомпилировал под x32 и x64 кому интересно.
x32 версия всегда выдает Program Files (x86).
Похоже тупо подставляет нужное значение переменной в зависимости от разрядности процесса, как и описано здесь.
Вложения
Тип файла: zip CppShellKnownFolders_compiled(x32,x64).zip (230.5 Кб, 7 просмотров)
0
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18030 / 7733 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
08.06.2015, 12:46  [ТС]
Чтобы дать теме логическое завершение, скажу, что ярлыки, создаваемые Explorer,
цель которых пролегает через специальные папки, создаются с добавлением Extra Data Block.

Когда система начинает разбор пути и видит наличие одной из секций:
- 2.5.6. KnownFolderDataBlock
- 2.5.9. SpecialFolderDataBlock
то формирование пути происходит с участием раскрытия переменной окружения, указанной в этих секциях (что приводит к получению другого значения под WOW64).

Чтобы однозначно идентифицировать реальный путь, можно, к примеру прочитать SpecialFolderDataBlock и по номеру CSIDL узнать:
'38 = %ProgramFiles%
'42 = %ProgramFiles(x86)%
Другие значения: CSIDL - http://code.snapstream.com/api... CSIDL.html
Аналогичная ситуация с переменной %CommonProgramFiles%.

Касаемо KnownFolderDataBlock, ее GUID можно также проверить по этому списку: https://msdn.microsoft.com/en-... s.85).aspx
Например,
{6D809377-6AF0-444b-8957-A3773F02200E} - ProgramFilesX64
{7C5A40EF-A0FB-4BFC-874A-C0F2E0B9FA8E} - ProgramFilesX86

Парсинг этих секций можно провести примерно так:
Кликните здесь для просмотра всего текста

Visual Basic
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
    ' ===== 2.5. Extra Data Block ======
    
    Dim BlockSize As Long
    Dim BlockSignature As Long
    Dim KnownFolderID As UUID
    Dim KnownFolderIDListOffset As Long
    Dim SpecialFolderID As Long
    Dim SpecialFolderIDListOffset As Long
    Dim OtherStr As String
    Dim lr As Long
    
    If NextOffset + 1 < LOF(ff) Then    ' not EOF
        Get #ff, NextOffset + 1&, BlockSize
        
        Do While BlockSize >= 4     ' not TerminalBlock
        
            Get #ff, NextOffset + 4& + 1&, BlockSignature
            
            Debug.Print Hex(BlockSignature)
            
            Select Case BlockSignature
            
                'Case &HA0000002 '2.5.1. ConsoleDataBlock
                'Case &HA0000004 '2.5.2. ConsoleFEDataBlock
                'Case &HA0000006 '2.5.3. DarwinDataBlock
                'Case &HA0000001 '2.5.4. EnvironmentVariableDataBlock
                'Case &HA0000007 '2.5.5. IconEnvironmentDataBlock
            
                Case &HA000000B  '2.5.6. KnownFolderDataBlock
                    Get #ff, NextOffset + 8& + 1&, KnownFolderID
                    Get #ff, NextOffset + 8& + 16& + 1&, KnownFolderIDListOffset    'offset in link target ID List
                    Dim KnownFolderID_str As String
                    KnownFolderID_str = String$(39&, Chr$(0&))
                    lr = StringFromGUID2(KnownFolderID, StrPtr(KnownFolderID_str), Len(KnownFolderID_str))
                    KnownFolderID_str = Left$(KnownFolderID_str, 38)
                    Debug.Print KnownFolderID_str
                    
                    '7c5a40ef-a0fb-4bfc-874a-c0f2e0b9fa8e = ProgramFilesX86
                    'KnownFolderIDs - [url]http://msdn.microsoft.com/en-us/library/windows/desktop/dd378457(v=vs.85).aspx[/url]
                
                'Case &HA0000009 '2.5.7. PropertyStoreDataBlock
                'Case &HA0000008 '2.5.8. ShimDataBlock
                
                Case &HA0000005  '2.5.9. SpecialFolderDataBlock
                    Get #ff, NextOffset + 8& + 1&, SpecialFolderID
                    Get #ff, NextOffset + 8& + 12& + 1&, SpecialFolderIDListOffset  'offset in link target ID List
                    
                    'CSIDL - [url]http://code.snapstream.com/api/bm11/SnapStream.Util.CSIDL.html[/url]
                    '38 = %ProgramFiles%
                    '42 = %ProgramFiles(x86)%
                
                'Case &HA0000003 '2.5.10. TrackerDataBlock
                'Case &HA000000C '2.5.11. VistaAndAboveIDListDataBlock
                
                Case Else
                    OtherStr = String$(BlockSize - 8&, Chr$(0&))
                    Get #ff, NextOffset + 8& + 1&, OtherStr
                
            End Select
            
            NextOffset = NextOffset + BlockSize
        
            If NextOffset + 1 >= LOF(ff) Then Exit Do
            
            Get #ff, NextOffset + 1&, BlockSize
            
        Loop
        
    End If
2
08.06.2015, 13:53

Не по теме:

Dragokas, не перестаешь удивлять своими знаниями и
навыками ресерча, браво !
:good:

0
08.06.2015, 20:58  [ТС]

Не по теме:


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

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

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
08.06.2015, 20:58
Помогаю со студенческими работами здесь

Как узнать объект события?
Доброго времени суток. На фрейме несколько таблиц созданных в цикле. Все редактируемые. Как программно узнать какую из них я редактирую?...

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

'Какой размер имеет переменная типа int в 32 битной и в 64 битной OC?
Объектно-ориентированное программирование в С++ Р. Лафоре.

Как узнать, открыт ли объект SELECT?
Как узнать, открыт ли объект SELECT, представленный в виде ComboBox?

Как узнать находится ли объект в фокусе
Создаю компонент. Как мне внутри компонента понять, что он находится в фокусе? if focused=true не пашет. Значение всегда false


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

Или воспользуйтесь поиском по форуму:
31
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru