Форум программистов, компьютерный форум, киберфорум
Visual Basic .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.71/7: Рейтинг темы: голосов - 7, средняя оценка - 4.71
0 / 0 / 0
Регистрация: 01.04.2024
Сообщений: 2

Генерация запускаемого файла

30.06.2024, 05:00. Показов 1897. Ответов 34
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте. Хочу сделать программу. После запуска пользователь указывает в программе пути к графическим файлам и нажимает кнопку "Сгенерировать EXE", вводит имя файла/путь и программа создает exe-файл со специальным просмотрщиком выбранных файлов.
Как сделать создание exe-файла?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
30.06.2024, 05:00
Ответы с готовыми решениями:

Как указать корневую папку запускаемого exe файла
Хочу чтоб при запуске программы создавалась папка в корне этой программы, минут 30 искал способы и тестил как это сделать, не получается,...

Отправка файла на FTP-сервер посредством bat-файла, запускаемого через Планировщик задач
Здравствуйте, подскажите пожалуйста Как правильно настроить передачу фала (c:\1\Товары.csv) на FTP посредством bat и как его потом...

Handle запускаемого файла
Доброго времени суток. У меня такой вопрос, как можно узнать Хэндл запускаемого файла? Или просто активного окна хотябы?

34
Модератор
Эксперт .NET
 Аватар для Yury Komar
4372 / 3442 / 512
Регистрация: 27.01.2014
Сообщений: 6,266
02.07.2024, 22:50
Студворк — интернет-сервис помощи студентам
OwenGlendower, Rius, Я все таки решил пойти чуть другим путем и записывать и читать бинарные данные в\из ресурсов PE файла .exe.

Да и в сети прям 100% рабочих примеров именно на VB.NET практически нет, поэтому остановлюсь пока на этой теме, чтоб развить ее до полностью рабочего кода.

С чтением всё получается, запись тоже будет несложной.
Доделаю, выложу тут.

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

Вот так, получается прочитать, если имя ресурса известно заранее

VB.NET
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    Function LoadResFromFile(fName As String, ResType As String, ResName As String) As Byte()
        Dim hInstance = New IntPtr(LoadLibrary(fName))
        Dim Res = New IntPtr(FindResource(hInstance, ResName.ToUpper, ResType.ToUpper))
        If Res <> 0 Then
            Dim ResLoad = New IntPtr(LoadResource(hInstance, Res))
            Dim ResLock = New IntPtr(LockResource(ResLoad))
            Dim ResSize = SizeofResource(hInstance, Res)
            Dim Buffer(ResSize - 1) As Byte
            Marshal.Copy(ResLock, Buffer, 0, ResSize)
            FreeLibrary(hInstance)
 
            Return Buffer
        End If
 
        Return Nothing
    End Function

то есть вытягиваю массив байт, обращаясь к нему по имени этого ресурса, ну и далее в Bitmap перевожу.
так можно и не только картинки хранить в EXE'шниках
результат
Миниатюры
Генерация запускаемого файла  
1
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18359 / 14289 / 5370
Регистрация: 17.03.2014
Сообщений: 28,968
Записей в блоге: 1
03.07.2024, 12:30
Цитата Сообщение от Yury Komar Посмотреть сообщение
Я все таки решил пойти чуть другим путем и записывать и читать бинарные данные в\из ресурсов PE файла .exe.
Я как бы и не был против. Вас эта тема явно зацепила, чему можно только порадоваться

Но у меня есть пара комментариев к коду.

1. Зачем тут LoadLibrary/FreeLibrary если ресурсы хранятся в самом exe файле? В моем понимании достаточно вызвать GetModuleHandle.

2. К чему эти постоянные New IntPtr? Что мешает указать тип возвращаемого значения?

P.S. Картинка моряка прикольная
0
Модератор
Эксперт .NET
 Аватар для Yury Komar
4372 / 3442 / 512
Регистрация: 27.01.2014
Сообщений: 6,266
03.07.2024, 13:00
OwenGlendower,
1. Зачем тут LoadLibrary/FreeLibrary если ресурсы хранятся в самом exe файле? В моем понимании достаточно вызвать GetModuleHandle.
Ну я особо не заморачивался, надо попробовать. Но, как в таком случае освободить память? Если нет FreeLibrary? Просто очистить переменную и вызвать сборщик мусора?

2. К чему эти постоянные New IntPtr? Что мешает указать тип возвращаемого значения?
Да я вообще думаю просто Integer использовать, но возвращаемый тип можно сменить, спасибо за наблюдение.

P.S. Картинка моряка прикольная
Ага, тоже нравится. Могу поделиться ))

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

А еще мне, давным-давно еще, понравился код от The Trick, где он читал и записывал данные в ресурс самого себя в рантайме, используя при этом инъекцию в процесс CMD, так, что при выгрузке приложения код, вшитый в процесс CMD выполнял обновление ресурса (типа String) в рашем exe'шнике...
2
Эксперт .NET
 Аватар для Rius
13405 / 7858 / 1701
Регистрация: 25.05.2015
Сообщений: 23,870
Записей в блоге: 14
03.07.2024, 13:01
Использовать такие методы = провоцировать антивирусы. А затем и их пользователей.
0
Модератор
Эксперт .NET
 Аватар для Yury Komar
4372 / 3442 / 512
Регистрация: 27.01.2014
Сообщений: 6,266
03.07.2024, 13:17
Rius, Да, я в курсе, они то (антивирусы) как раз таки и против таких "методов" )) Просто сама реализация понравилась

Ну а чтение и запись в ресурс - тут ничего противозаконного нет
0
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18359 / 14289 / 5370
Регистрация: 17.03.2014
Сообщений: 28,968
Записей в блоге: 1
03.07.2024, 13:24
Цитата Сообщение от Yury Komar Посмотреть сообщение
Но, как в таком случае освободить память?
В этом и суть что ничего освобождать не требуется т.к. GetModuleHandle возвращает дескриптор без увеличения счетчика. А значит код станет немного проще.

Цитата Сообщение от Yury Komar Посмотреть сообщение
Да я вообще думаю просто Integer использовать
Не надо. IntPtr или один из SafeHandle лучше тут подходит.
1
Модератор
Эксперт .NET
 Аватар для Yury Komar
4372 / 3442 / 512
Регистрация: 27.01.2014
Сообщений: 6,266
03.07.2024, 13:47
Цитата Сообщение от OwenGlendower Посмотреть сообщение
В этом и суть что ничего освобождать не требуется т.к. GetModuleHandle возвращает дескриптор без увеличения счетчика. А значит код станет немного проще.
супер, благодарю за подсказку, применю это в деле )

Добавлено через 23 секунды
Цитата Сообщение от OwenGlendower Посмотреть сообщение
IntPtr или один из SafeHandle лучше тут подходит.
Понял.
0
Модератор
10065 / 3910 / 885
Регистрация: 22.02.2013
Сообщений: 5,860
Записей в блоге: 79
03.07.2024, 14:11
Делал специальный класс для хранения файлов в "хвосте" exe файла. Правда на vb6. https://www.cyberforum.ru/post14416587.html
2
Модератор
Эксперт .NET
 Аватар для Yury Komar
4372 / 3442 / 512
Регистрация: 27.01.2014
Сообщений: 6,266
03.07.2024, 17:09
Цитата Сообщение от OwenGlendower Посмотреть сообщение
В моем понимании достаточно вызвать GetModuleHandle.
К сожалению (проверил) функция возвращает всегда "0"... Решил пока остаться на LoadLibrary и FreeLibrary

Добавлено через 2 часа 51 минуту
Ну собственно дожал я это дело, конечно, можно доработать код где-то, но на данном этапе все работает.

Оформил в виде класса (читает ресурс, сохраняет или перезаписывает ресурс, получает имена всех ресурсов)
Кликните здесь для просмотра всего текста
VB.NET
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
Imports System.IO
Imports System.Runtime.InteropServices
 
Public Class ResManager_Win32 : Implements IDisposable
 
#Region "    WinAPIs"
    Declare Function LoadLibrary Lib "kernel32.DLL" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As IntPtr
    Declare Function FreeLibrary Lib "kernel32.DLL" (ByVal hLibModule As IntPtr) As IntPtr
    Declare Function FindResource Lib "kernel32.DLL" Alias "FindResourceA" (ByVal hInstance As IntPtr, ByVal lpName As String, ByVal lpType As String) As IntPtr
    Declare Function LoadResource Lib "kernel32.DLL" (ByVal hInstance As IntPtr, ByVal hResInfo As IntPtr) As IntPtr
    Declare Function LockResource Lib "kernel32.DLL" (ByVal hResData As IntPtr) As IntPtr
    Declare Function SizeofResource Lib "kernel32.DLL" (ByVal hInstance As IntPtr, ByVal hResInfo As IntPtr) As Integer
    Declare Function BeginUpdateResource Lib "kernel32.DLL" Alias "BeginUpdateResourceA" (ByVal pFileName As String, ByVal bDeleteExistingResources As Integer) As IntPtr
    Declare Function UpdateResource Lib "kernel32.DLL" Alias "UpdateResourceA" (ByVal hUpdate As IntPtr, ByVal lpType As String, ByVal lpName As String, ByVal wLanguage As Integer, <System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.AsAny)> ByVal lpData As Object, ByVal cbData As Integer) As IntPtr
    Declare Function EndUpdateResource Lib "kernel32.DLL" Alias "EndUpdateResourceA" (ByVal hUpdate As IntPtr, ByVal fDiscard As Integer) As IntPtr
    Declare Unicode Function EnumResourceNames Lib "kernel32.DLL" Alias "EnumResourceNamesW" (ByVal hModule As IntPtr, ByVal lpszType As String, ByVal lpEnumFunc As EnumResNameProcDelegate, ByVal lParam As IntPtr) As Boolean
    Delegate Function EnumResNameProcDelegate(ByVal hModule As IntPtr, ByVal lpszType As IntPtr, ByVal lpszName As IntPtr, ByVal lParam As IntPtr) As Boolean
#End Region
#Region "    Dispose methods"
    Protected Overridable Sub Dispose(disposing As Boolean)
        If Not disposedValue Then
            If disposing Then
                fName = Nothing
            End If
 
            GC.Collect()
            disposedValue = True
        End If
    End Sub
 
    Public Sub Dispose() Implements IDisposable.Dispose
        Dispose(disposing:=True)
        GC.SuppressFinalize(Me)
    End Sub
#End Region
#Region "    Private Variables"
    Private disposedValue As Boolean
    Private fName As String
    Private EnumsReturnValues() As String
#End Region
#Region "    Private Methods"
    Private Function EnumResNameProc(hModule As IntPtr, lpszType As IntPtr, lpszName As IntPtr, a As IntPtr) As Boolean
        Dim s As String
 
        If lpszName.ToInt32 > Short.MaxValue Then
            s = Marshal.PtrToStringUni(lpszName)
        Else
            s = lpszName.ToString()
        End If
 
        ReDim Preserve EnumsReturnValues(EnumsReturnValues.Count)
        EnumsReturnValues(EnumsReturnValues.Count - 1) = s
 
        Return True
    End Function
#End Region
#Region "    Class Constructor"
    Sub New(FileName As String)
        If Not IO.File.Exists(FileName) Then Throw New Exception("File not exist.")
        fName = FileName
    End Sub
#End Region
 
#Region "    Public Loading Resources"
    Public Function GetResourceNames(ResType As String) As String()
        Dim hLibrary = LoadLibrary(fName)
        EnumsReturnValues = Nothing
 
        If hLibrary <> IntPtr.Zero Then
            EnumsReturnValues = {}
            EnumResourceNames(hLibrary, ResType, AddressOf EnumResNameProc, IntPtr.Zero)
        End If
 
        FreeLibrary(hLibrary)
        hLibrary = Nothing
        GC.Collect()
 
        Return EnumsReturnValues
    End Function
 
    Public Function Load_Bitmap(ResType As String, ResName As String) As Bitmap
        Dim b = Load_Bytes(ResType, ResName)
        If Not b Is Nothing Then
            Using M = New MemoryStream(b)
                Return New Bitmap(M)
            End Using
        Else
            b = Nothing
        End If
 
        Return Nothing
    End Function
 
    Public Function Load_Bytes(ResType As String, ResName As String) As Byte()
        Dim hLibrary = LoadLibrary(fName)
        Dim hRes = FindResource(hLibrary, ResName, ResType)
        Dim hResLoad = LoadResource(hLibrary, hRes)
        Dim hResLock = LockResource(hResLoad)
        Dim intResSize = SizeofResource(hLibrary, hRes)
 
        Dim isSuccessfull As Boolean = (hLibrary <> IntPtr.Zero And hRes <> IntPtr.Zero And hResLoad <> IntPtr.Zero And hResLock <> IntPtr.Zero And intResSize <> 0)
        hRes = Nothing : hResLoad = Nothing
 
        If Not isSuccessfull Then
            FreeLibrary(hLibrary)
            hLibrary = Nothing
            hResLock = Nothing
            intResSize = Nothing
            GC.Collect()
            Return Nothing
        End If
 
        Dim ResBuffer(intResSize - 1) As Byte
 
        Try
            Marshal.Copy(hResLock, ResBuffer, 0, ResBuffer.Length)
            FreeLibrary(hLibrary)
            hLibrary = Nothing
            hResLock = Nothing
            intResSize = Nothing
            GC.Collect()
            Return ResBuffer
        Catch ex As Exception
            FreeLibrary(hLibrary)
            hLibrary = Nothing
            hResLock = Nothing
            intResSize = Nothing
            ResBuffer = Nothing
            GC.Collect()
            Return Nothing
        End Try
    End Function
#End Region
 
#Region "    Public Saving Resources"
    Public Function Save_Resource(ByteArray() As Byte, ResType As String, ResName As String) As Boolean
        Dim hUpdate = BeginUpdateResource(fName, False)
        Dim RetUpdate = UpdateResource(hUpdate, ResType, ResName.ToUpper, 0, ByteArray, ByteArray.Length)
        Dim EndRetUpdate = EndUpdateResource(hUpdate, False)
 
        If EndRetUpdate = IntPtr.Zero Then MsgBox("Файл занят другим процессом.")
 
        Dim isSuccessfull As Boolean = (hUpdate <> IntPtr.Zero And RetUpdate <> IntPtr.Zero And EndRetUpdate <> IntPtr.Zero)
        hUpdate = Nothing : RetUpdate = Nothing : EndRetUpdate = Nothing : GC.Collect()
 
        Return isSuccessfull
    End Function
#End Region
End Class



Применение:

Получить картинку из ресурсов
VB.NET
1
2
3
4
5
6
7
'Получить картинку из ресурсов
 Using ResLib As New ResManager_Win32("111.exe")
     Dim Img As Bitmap = ResLib.Load_Bitmap("CUSTOM", "IMG1")
     If Img Is Nothing Then MsgBox("Не удалось загрузить ресурс.") : Exit Sub
 
     Me.BackgroundImage = Img
 End Using
Сохранить массив байт в ресурсы
VB.NET
1
2
3
4
5
    Using ResLib As New ResManager_Win32("111.exe")
        If ResLib.Save_Resource(New Byte() {&HFF, &HFF, &HFF}, "CUSTOM", "IMG2") Then
            MsgBox("Saved")
        End If
    End Using
Получить имена всех ресурсов данного типа
VB.NET
1
2
3
4
5
6
    Using ResLib As New ResManager_Win32("111.exe")
        Dim ResNames() = ResLib.GetResourceNames("CUSTOM")
        If ResNames IsNot Nothing Then
            MsgBox(Join(ResNames, vbNewLine))
        End If
    End Using
0
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18359 / 14289 / 5370
Регистрация: 17.03.2014
Сообщений: 28,968
Записей в блоге: 1
03.07.2024, 17:24
Цитата Сообщение от Yury Komar Посмотреть сообщение
К сожалению (проверил) функция возвращает всегда "0"
Вы точно её правильно вызывали? Чтобы получить дескриптор текущего процесса нужно передать Nothing в качестве имени модуля.
0
Модератор
Эксперт .NET
 Аватар для Yury Komar
4372 / 3442 / 512
Регистрация: 27.01.2014
Сообщений: 6,266
03.07.2024, 17:26
Цитата Сообщение от OwenGlendower Посмотреть сообщение
Чтобы получить дескриптор текущего процесса
так я не из текущего процесса, а из другого модуля (другого файла EXE) читал.
0
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18359 / 14289 / 5370
Регистрация: 17.03.2014
Сообщений: 28,968
Записей в блоге: 1
03.07.2024, 17:27
Yury Komar, в таком случае естественно нужен LoadLibrary, но я исходил из того что мы говорим про единственный exe как требуется ТСу.
0
Модератор
Эксперт .NET
 Аватар для Yury Komar
4372 / 3442 / 512
Регистрация: 27.01.2014
Сообщений: 6,266
03.07.2024, 17:32
Цитата Сообщение от OwenGlendower Посмотреть сообщение
про единственный exe
Ну решил чуть более универсально сделать, например, чтоб можно было после записи в файл проверить записанные данные или подгрузить что-то из другого файла.

Думаю так очень даже классно вышло, позже закину в готовые решения, там такого еще не было.
0
77 / 73 / 6
Регистрация: 11.04.2021
Сообщений: 304
Записей в блоге: 7
08.07.2024, 01:04
I can, в самой сборке exe файла чего то не хватает. а чего я так и не разобрался
0
Вернулся
 Аватар для HackerVlad
1753 / 649 / 45
Регистрация: 10.09.2021
Сообщений: 2,803
16.07.2024, 05:46
А вы заметили что ТС ни разу так и не ответил потом... после создания темы...
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
16.07.2024, 05:46

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

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

Узнать параметры запускаемого файла
мне нужно узнать расширение запускаемого файла , в delphi я делал так: on form create var s,ext: string; Begin s:=Paramstr(0); If...

Выполнение за пределами запускаемого BAT-файла
Через команду call запускаем батник. Необходимо в зависимости от того что произошло внутри батника выполнить условие. call 1.bat ...

Передача запускаемого текстового файла в memo (delphi)
Добрый вечер, ребят. Помогите, пожалуйста, решить проблему на delphi. У меня есть форма, на которой расположены memo, кнопка, и...


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

Или воспользуйтесь поиском по форуму:
35
Ответ Создать тему
Новые блоги и статьи
Калькулятор для расчета родства
russiannick 07.08.2026
1. Задача: Создать калькулятор для расчета родства. Родственных связей существует 8 ступеней, такие как: p - отец P - мать q - муж Q - жена b - брат B - сестра s - сын S - дочь
Мир по моей воле
kumehtar 07.08.2026
Когда-то кажется, что всё просто. Ты весь такой светлый. Причиняешь добро. Борешься за справедливость в этом тёмном мире. Потом начинаешь замечать одну неприятную вещь. Почти каждый хороший. . .
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
У нас сейчас поговорку "Опять 25" нужно переделать на "Опять +35".
kumehtar 04.08.2026
С ностальгией вспоминаю времена моего детства, когда у нас и правда +25 - была максимальная температура летом. Раньше +25 °C реально казались вершиной жары, когда можно было весь день пропадать на. . .
Как ИИ начал спорить и врать (возможно почуяв опасность для себя от индустрии - уход от электроники).
Hrethgir 04.08.2026
Недельный диалог, на фоне событий с НПЗ. Да, из спирта можно получать бензин, и это не сложно. Но потом в схеме я решил избавиться от насоса, при этом полностью сделав контроль подачи спирта в. . .
Термопринтер QR701
Argus19 03.08.2026
Термопринтер QR701 Купил два термопринтера QR701. На сэлф-тесте написано: Language: PC936 (GB18030). Что означает, что принтеры могут печатать только латиницу и китайские иероглифы. Так же. . .
Создание формы заимствованного документа
Maks 03.08.2026
Задача: Необходимо создать собственную форму заимствованного документа. На форме должен быть реквизит "Покупатель", а также табличная часть со следующими реквизитами: - Расчетный счет покупателя. . .
Задача предоставления скидок покупателям
Maks 03.08.2026
Задача: В документе "Продажи" необходимо реализовать функционал предоставления скидок покупателям. Скидка должна автоматически рассчитываться и подставляться в соответствующее поле при выборе. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru