Статьи

Опыт создания программы-архива для CD.

Итак, представим себе ситуацию: Вы имеете возможность "гулять" по Интернету и скачивать интересующие Вас программы. Однако, наступает момент, когда возможности Вашего жесткого диска заканчиваются, или, проще говоря, диск переполнен. Вы начинаете лихорадочно удалять "все ненужное". И наступает момент, когда в категорию ненужное попадают инсталляционные пакеты. А что делать, если по каким-либо причинам необходимо переустановить программу? Снова идти в Интернет и скачивать? В общем, настала пора приобретать Пишущий CD-R/RW (англ.: CD-Recorder, или нем.: Brenner). Если Вы уже имеете его, значит - этот критический момент Вы уже прошли :-)

Следующий этап - это попытка разобраться: так что же все-таки на этом CD у меня записано? Вот здесь мы переходим к теме данной статьи: необходима запускающая программа, которая даст Вам информацию о расположенных на данном диске программах (инсталляционных пакетах), и, не роясь в папках, легко и просто установить их на свой (или другу) компьютер.

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

Ну что ж, теперь о структуре программы:

Здесь я специально дал картинку из VB, т.к. некоторые кнопки во время работы будут невидимые или заблокированные. Кроме того, программа будет писаться универсальная т.е. для любого набора инсталляционных пакетов. В этом случае нам потребуется получать информацию из внешнего источника. Не надо "изобретать велосипед" - воспользуемся давно проверенными методами, а именно INI-файлами.

Ниже, в таблице, представлены все элементы управления, расположенные на форме:
Тип Name Caption Index Enabled Visible
Меню  mnuGeneral #   True True
Подменю  mnuSub # 0 True True
Список  lstProgramm     True True
Лейбл  lblGeneral Mik's Collection   True True
Лейбл  lblDescription Подборка программ   True True
Кнопка  cmdClipboard [Картинка]   False True
Текстовое поле  txtClipboard     False True
Кнопка  cmdInstall Инсталлировать 0 True False
Кнопка  cmdInstall Копировать 1 True False
Кнопка  cmdExit Выход   True True

Теперь о структуре: все инсталляционные пакеты разбиты на соответствующие подгруппы и каждый пакет лежит в своей отдельной папке. Для считывания информации из INI-файла нам потребуется API-функция:
Private Declare Function GetPrivateProfileString& Lib "kernel32" _
    Alias "GetPrivateProfileStringA" _
    (ByVal lpApplicationName$, _
    ByVal lpszKey$, _
    ByVal lpszDefault$, _
    ByVal lpszReturnBuffer$, _
    ByVal cchReturnBuffer&, _
    ByVal lpszFile$)

Чтобы защитить себя от возможных ошибок, а так же для упрощения доступа к данной функции - напишем функцию-обертку:
Function GetProfile(Section$, Key$, File$) As String
    Dim KeyValue$, Characters&
    
    KeyValue$ = String$(128, 0)
    'если программы мелкие и их много - можно увеличить размер буфера до 255 или больше
    Characters = GetPrivateProfileString(Section$, Key$, "", KeyValue$, 127, File$)
    If Characters > 1 Then
        KeyValue$ = Left$(KeyValue$, Characters)
    End If
    GetProfile = KeyValue$
End Function

И еще одна необходимая функция, для установки "\" в конце пути:
Private Function Path() As String
    Select Case Right(App.Path, 1)
    Case "\"
        Path = App.Path
    Case Else
        Path = App.Path & "\"
    End Select
End Function

Для кнопки выхода из программы - самый простой код :-)
Private Sub cmdExit_Click()
    Unload Me
End Sub

Дальнейшее написание кодов у нас будет проходить параллельно с написанием структуры INI-файла (здесь и далее структура INI-файла будет окрашена в сиреневый цвет):
[General]
Caption=Mik's Collection - 2

[Menu]
StartMenu=Выбор установки
Num=6
M0=Архиваторы
M1=Аудиопрограммы
M2=Обработка видео
M3=Работа с графикой
M4=Программы для интернета
M5=Прочие программы для ПК

В секции General у нас только один ключ - надпись, которая будет выводиться в заголовке программы. Секция Menu отвечает за построение нашего меню. Здесь ключ StartMenu - отвечает за выводимую надпись основного меню; Num - количество элементов подменю; М0 - М... - имена подменю. Обратите внимание, что нумерация подменю начинается с 0 и, следовательно, количество их на 1 меньше.

Теперь, сделав данные записи в текстовом файле, сохраните его с расширением *.ini (в данном примере это MikCollection.ini). Теперь попытаемся из программы получить, указанные в ini-файле, данные:
В разделе деклараций создадим переменную уровня формы
Private NameFileIni$

Private Sub Form_Load()
Dim NumMenu%, i%
NameFileIni = Path & "MikCollection.ini"

Caption = GetProfile("General", "Caption", NameFileIni)
mnuGeneral.Caption = GetProfile("Menu", "StartMenu", NameFileIni)
NumMenu = GetProfile("Menu", "Num", NameFileIni)

mnuSub(0).Caption = GetProfile("Menu", "M0", NameFileIni)
For i = 1 To NumMenu - 1
    Load mnuSub(i)
    mnuSub(i).Caption = GetProfile("Menu", "M" & i, NameFileIni)
Next
End Sub

Попробуйте, запустите программу и Вы увидите, что у формы появился заголовок, а так же полноценное меню (правда на данном этапе не подключенное). Двинулись дальше. Теперь нам необходимо, чтобы при выборе меню в ListBox загружался весь список находящихся в данном подразделе программ, лейблы выводили информацию о данном подразделе, кнопки инсталляции и копирования прятались, а кнопка и текстовое поле для серийных номеров блокировались.
[Menu1]
GlobalName=Аудиопрограммы
Description=Программы для обработки аудиофайлов
GlobalDir=AudioCD
NumProg=1
N0=Ra2Wav
D0=Конвертор RealAudio в Wav-формат
P0=AudioCD\Ra2Wav\ra2wav.exe
S0=""
B0=0

Итак, название секции будет нести имя Menu с соответствующим номером, т.е. Menu0, Menu1 и т.п. Далее по ключам:
GlobalName - имя раздела, выводимое в lblGeneral
Description - описание подраздела. Выводится в lblDescription
GlobalDir - имя директории данного раздела на диске
NumProg - количество программ, находящихся в данном разделе
Каждая программа имеет ряд параметров. Для простоты обозначим данный параметр одной буквой и цифрой
N0 - (от сокращенного Name) - имя программы, выводимое в ListBoxe и lblGeneral
D0 (от Description) - описание, будет выводиться в lblDescription
P0 - (от Path) - относительный путь к файлу
S0 - (от Serial Number) - серийный номер, выводится в текстовом поле. Если не требуется - ставим "".
B0 - (от Button) - номер индекса для кнопки cmdInsnall (какая кнопка должна отображаться)
Для следующей программы имена ключей будут те же, но со следующим номером: N1, D1, P1, S1, B1 и т.д.

Теперь, как все это работает в кодах:
В разделе деклараций добавим еще 3 переменные:
Private NameMenu$, PathFile$, PathDir$

Private Sub mnuSub_Click(Index As Integer)
Dim i%, NumProg%

NameMenu = "Menu" & Index
lblGeneral.Caption = GetProfile(NameMenu, "GlobalName", NameFileIni)
lblDescription.Caption = GetProfile(NameMenu, "Description", NameFileIni)
NumProg = GetProfile(NameMenu, "NumProg", NameFileIni)
PathDir = GetProfile(NameMenu, "GlobalDir", NameFileIni)
lstProgramm.Clear
If NumProg <> 0 Then
    For i = 0 To NumProg - 1
        lstProgramm.AddItem GetProfile(NameMenu, "N" & i, NameFileIni)
    Next
End If

cmdInstall(0).Visible = False
cmdInstall(1).Visible = False
txtClipboard.Text = vbNullString
txtClipboard.Enabled = False
cmdClipboard.Enabled = False
End Sub

Далее, при выборе программы из списка, мы должны отобразить всю информацию о конкретной программе:
Private Sub lstProgramm_Click()
    Dim NumButton%
    lblGeneral.Caption = lstProgramm.List(lstProgramm.ListIndex)
    lblDescription.Caption = GetProfile(NameMenu, "D" & lstProgramm.ListIndex, NameFileIni)
    txtClipboard.Text = GetProfile(NameMenu, "S" & lstProgramm.ListIndex, NameFileIni)
    PathFile = GetProfile(NameMenu, "P" & lstProgramm.ListIndex, NameFileIni)
    NumButton = GetProfile(NameMenu, "B" & lstProgramm.ListIndex, NameFileIni)
    cmdInstall(0).Visible = False
    cmdInstall(1).Visible = False
    cmdInstall(NumButton).Visible = True
End Sub

Давайте немного отвлечемся перед решительным шагом и сделаем более удобным вывод/блокировку кнопки и текстового поля, отвечающих за серийные номера. Нам необходимо, чтобы при наличии серийного номера - они были доступны и была бы возможность копировать это в буфер обмена. А при отсутствии серийного номера - эти два элемента блокировались бы.
Private Sub txtClipboard_Change()
    If txtClipboard.Text = vbNullString Then
        txtClipboard.Enabled = False
        cmdClipboard.Enabled = False
    Else
        txtClipboard.Enabled = True
        cmdClipboard.Enabled = True
    End If
End Sub

Private Sub cmdClipboard_Click()
    Clipboard.SetText txtClipboard.Text, vbCFText
End Sub

Заключительные коды отвечают у нас за удобство инсталляции (или копирования файлов). С инсталляцией, здесь не возникает никаких проблем:
Private Sub cmdInstall_Click(Index As Integer)

Select Case Index
Case
    Shell Path & PathFile, vbNormalFocus
Case 1
...
End Select
End Sub

А вот с копированием придется немного повозиться. Если Вы внимательно просмотрели INI-файл, расположенный в Примере, то, наверно, заметили маленькую хитрость: для тех программ, которые необходимо инсталлировать мы указываем полный относительный путь к файлу, запускающему начало инсталляции. А вот для тех программ, которые нет необходимости инсталлировать - мы указываем только имя папки, содержимое которой просто копируется на диск.
Private Sub cmdInstall_Click(Index As Integer)
Dim MyFile$, MyPath$, MyName$

Select Case Index
...
Case 1
'если директория существует пройдем дальше
On Error Resume Next
'создание директории всего подраздела
MkDir "C:\Program Files\" & PathDir
'создание директории для данной выбранной программы
MkDir "C:\Program Files\" & PathDir & "\" & PathFile
MyPath = Path & PathDir & "\" & PathFile & "\"
'получаем имя первого файла
MyName = Dir(MyPath)
'зацикливаемся, пока все файлы не скопируем
Do While MyName <> ""
    If MyName <> "." And MyName <> ".." Then
        FileCopy MyPath & MyName, "C:\Program Files\" & PathDir & _
            "\" & PathFile & "\" & MyName
    End If
    'получаем имя следующего файла в этой директории
    MyName = Dir
Loop
'По окончании копирования выводим сообщение
MsgBox "Копироване в папку:" & "C:\Program Files\" & PathDir & _
    "\" & PathFile & " - завершено!"
End Select
End Sub

На этом мы закончили с кодами. Ну и напоследок - структура файла Autorun.inf (файл выполняющий автозапуск нашей программы, при вставке диска в дисковод):
[autorun]
OPEN=MikCollection.exe
ICON=MikCollection.exe
где, ехе-файл - это файл нашей программы.

На прощание: к сожалению я не смог положить в данный примеры исходников всех, описанных в INI-файле программ :-)
Так что будьте внимательны при создании записей в структуру СВОЕГО INI-файла.

Ну что ж пора переходить к записи на CD-R своего архива программ.


Назад

Скачать пример

Hosted by uCoz