Войти

Показать полную графическую версию : Скрипты Inno Setup. Помощь и советы [часть 4]


Страниц : 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

R.i.m.s.k.y.
15-03-2012, 08:38
мне нужно чтоб на странице спрашивать пользователя куда сохранять бекап »
ну вот тут (http://forum.oszone.net/showthread.php?p=1874234&highlight=half#post1874234) в CurStepChanged и вставляй вопрос, или в список компонентов отдельную галочку
чтоб удалить базу и пользователя в postgres »
это в форум по postgres (щито это?)

Temyraz@fb
15-03-2012, 11:13
наверное я ослеп или чего та не понимаю.

вот конкретный код

#[Code]
procedure DeleteBitmaps(ADirName: string);
var
FindRec: TFindRec;
begin if FindFirst(ADirName + '\*.*', FindRec) then
begin try repeat if FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY <> 0 then begin if (FindRec.Name <> '.') and (FindRec.Name <> '..') then
begin DeleteBitmaps(ADirName + '\' + FindRec.Name); RemoveDir(ADirName + '\' + FindRec.Name);
end;
end else if Pos('.bmp', AnsiLowerCase(FindRec.Name)) > 0 then DeleteFile(ADirName + '\' + FindRec.Name); until not FindNext(FindRec); finally FindClose(FindRec);
end;
end;
end;
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin if MsgBox('Baskup:' #13#13 'Сделать бекап?', mbConfirmation, MB_YESNO) = idYes then
begin
CopyDir(ExpandConstant('{app}\files'),ExpandConstant('Путь сохранения бекапа'));
CopyDir(ExpandConstant('{app}\license'),ExpandConstant('Путь сохранения бекапа'));
end
begin if MsgBox('Вы хотите удалить все фаилы??', mbConfirmation, MB_YESNO) = IDYES then begin DeleteBitmaps(ExpandConstant('{app}')); end; end; end;


вот как спросить у пользователя куда сохранить бекап?

Johny777
15-03-2012, 12:51
Temyraz@fb,

я так понимаю сохранить нужно это?
CopyDir(ExpandConstant('{app}\files'),ExpandConstant('Путь сохранения бекапа'));
CopyDir(ExpandConstant('{app}\license'),ExpandConstant('Путь сохранения бекапа'));
создаёшь чекбокс на странице выбора компонентов
R.i.m.s.k.y. сказал же через CurStepChanged
вот так оно и будет выглядеть
для бэкапа взял шаг ssInstall, те перед установкой (удалением)

var
BackUp_CheckBox: TNewCheckBox;


function make_backup: Boolean;
begin
Result:=BackUp_CheckBox.Checked;
end;

procedure CurStepChanged(CurStep: TSetupStep);
begin
if CurStep = ssInstall then
begin
if BackUp_CheckBox.Checked then
CopyDir(ExpandConstant('{app}\files'),ExpandConstant('Путь сохранения бекапа'));
CopyDir(ExpandConstant('{app}\license'),ExpandConstant('Путь сохранения бекапа'));
end;


procedure InitializeWizard;
begin
BackUp_CheckBox := TNewCheckBox.Create(WizardForm);
with BackUp_CheckBox do
begin
Name := 'BackUp_CheckBox';
Parent := WizardForm.SelectComponentsPage;
Left := ScaleX(304);
Top := ScaleY(213);
Width := ScaleX(113);
Height := ScaleY(17);
Caption := 'Сделать бэкап?';
end;
end;

только это для удаления скрипт. Поэтому вместо {app} используй {src}
путь сохранения потом задашь в коде? Он статичный?

Temyraz@fb
15-03-2012, 13:08
путь сохранения пользователь сам укажет

Johny777
15-03-2012, 13:11
сам укажет »
можно подробнее?
как это работает?
одного это достаточно?
ExpandConstant('Путь сохранения бекапа'))

Temyraz@fb
15-03-2012, 13:15
Вообще бекап будет делаться в деистоляторе. т.е. когда пользователь начинает удалять программу, у него система будет спрашивать делать бекап? если он отвечает "да" , то система будет спрашивать куда сохранить бекап. система сохранить именно там где указал пользователь

Johny777
15-03-2012, 13:17
Temyraz@fb,
но учти у меня в примере этого нет
там чекбокс отмечается без MsgBox -а
а примеры копирования и не только есть в коллекции скриптов innoultra.ru/downloads/Scripts.rar

Temyraz@fb
15-03-2012, 13:42
да смотрел я эти скрипты, у меня почему та не хочет во время удаления появляться страницы. только сообщения.
а в MsgBox может пользователь выбрать путь сохранения бекапа?

R.i.m.s.k.y.
15-03-2012, 13:48
MsgBox может пользователь выбрать путь сохранения бекапа? »
нет, надо отдельное окно рисовать
как я не знаю

Temyraz@fb
15-03-2012, 13:51
а у кого можно спросить? реально срочно нужно

R.i.m.s.k.y.
15-03-2012, 13:56
Temyraz@fb, у кого можно спросить подписаны на эту тему
ждите ответа, ждите ответа...

Johny777
15-03-2012, 13:58
Temyraz@fb,
путь можно выбрать через эдит и string, но мне пока далеко до такого, потму что путь нужно получить из TFolderTreeView
а чтобы появлялось окно с выбором директории это нужно создать форму при нажатии на кнопку (такое есть) и в ней TFolderTreeView, как на странице выбора директории установки
попробовать могу, но не факт, что получится. Мне в будущем нужно тоже сохранёнки и достижения пред удалением сохранять, но путь хотел сделать статичным на рабочий стол.
хочет во время удаления появляться страницы »
есть такой пример создания формы после удаления, если тебе это поможет


[Setup]
AppName=My Program
AppVerName=My Program v.1.2
DefaultDirName={pf}\My Program
DirExistsWarning=no

[Files]
;Source: Files\*; DestDir: {app}

[ Code]
const
bidDelAll = 1;
bidSkipAll = 2;
var
Form: TSetupForm;
CheckListBox: TNewCheckListBox;
AllButton, UnAllButton, InvertButton: TButton;
CancelButton, DelButton: TButton;

MsgForm: TSetupForm;
MsgAllButton, MsgSkipAllButton: TButton;
MsgCancelButton, MsgDelButton: TButton;

DelAllReadOnly: Boolean;
SkipAllReadOnly: Boolean;

function Size64(Hi, Lo: integer): Extended;
var
i: integer;
begin
Result:= Lo;
if Lo < 0 then
Result:= Result + 2147483647 + 2147483647 + 2;
i:= Hi;
while i > 0 do
begin
Result:= Result + 2147483647 + 2147483647 + 2;
i:= i - 1;
end;
end;

procedure FillListBox(const fromDir, fileMask: string; Level: Byte);
var
FSR, DSR: TFindRec;
FindResult: Boolean;
APath: string;
i: integer;
begin
APath := AddBackslash(fromDir);
FindResult := FindFirst(APath + fileMask, FSR);
try
while FindResult do
begin
if FSR.Attributes and FILE_ATTRIBUTE_DIRECTORY = 0 then
begin
{files} i:= CheckListBox.AddCheckBox(FSR.Name, FloatToStr(Size64(FSR.SizeHigh, FSR.SizeLow)) + ' byte', Level, True, True, False, True, TStringList.Create);
TStrings(CheckListBox.ItemObject[i]).Text:= APath + FSR.Name;
end;
FindResult := FindNext(FSR);
end;
FindResult := FindFirst(APath + '*.*', DSR);
while FindResult do
begin
if ((DSR.Attributes and FILE_ATTRIBUTE_DIRECTORY) = FILE_ATTRIBUTE_DIRECTORY) and not ((DSR.Name = '.') or (DSR.Name = '..')) then
begin
{dir} i:= CheckListBox.AddCheckBox(DSR.Name,'DIR', Level, True, True, False, True, TStringList.Create);
TStrings(CheckListBox.ItemObject[i]).Text:= APath + DSR.Name;
{Recursion} FillListBox(APath + DSR.Name, fileMask, Level+1);
end;
FindResult := FindNext(DSR);
end;
finally
FindClose(FSR);
FindClose(DSR);
end;
end;

procedure ButtonOnClick(Sender: TObject);
begin
#if Ver < 83954944
CheckListBox.Checked[0]:= TButton(Sender).Tag = 0;
#else
Case TButton(Sender).Tag of
0 : CheckListBox.CheckItem(0, coCheckWithChildren);
1 : CheckListBox.CheckItem(0, coUncheck);
end;
#endif
end;

function HasChildren(Box: TNewCheckListBox; ItemIndex: integer): Boolean;
begin
if (ItemIndex = Box.Items.Count - 1) or (Box.ItemLevel[ItemIndex+1] <= Box.ItemLevel[ItemIndex]) then
Result:= False
else
Result:= True;
end;

procedure InvertOnClick(Sender: TObject);
var
i: integer;
begin
for i:= 1 to CheckListBox.Items.Count - 1 do
begin
if Not HasChildren(CheckListBox, i) then
CheckListBox.Checked[i]:= Not (CheckListBox.State[i] = cbChecked);
end;
end;

procedure MsgButtonOnClick(Sender: TObject);
begin
Case TButton(Sender).Tag of
bidDelAll : DelAllReadOnly:= True;
bidSkipAll: SkipAllReadOnly:= True;
end;
MsgForm.Close;
end;

function DelMsgBox(FileName: string): Boolean;
var
MsgLabel: TLabel;
begin
MsgForm:= CreateCustomForm;
MsgForm.ClientWidth := ScaleX(400);
MsgForm.ClientHeight := ScaleY(120);
MsgForm.Caption := 'Files to delete';
MsgForm.Center;

MsgLabel := TLabel.Create(MsgForm);
MsgLabel.Left := ScaleX(20);
MsgLabel.Top := ScaleY(20);
MsgLabel.Caption:= FileName + ' is protected file or directory !' + #10#10#13 +
'Do you want to delete the file with READONLY attribute ?';
MsgLabel.Parent := MsgForm;

MsgAllButton := TButton.Create(MsgForm);
MsgAllButton.Parent := MsgForm;
MsgAllButton.Width := ScaleX(75);
MsgAllButton.Height := ScaleY(23);
MsgAllButton.Left := ScaleX(20);
MsgAllButton.Top := MsgForm.ClientHeight - ScaleY(23 + 10);
MsgAllButton.Caption := 'Delete All';
MsgAllButton.Tag:= bidDelAll;
MsgAllButton.OnClick := @MsgButtonOnClick;

MsgSkipAllButton := TButton.Create(MsgForm);
MsgSkipAllButton.Parent := MsgForm;
MsgSkipAllButton.Width := ScaleX(75);
MsgSkipAllButton.Height := ScaleY(23);
MsgSkipAllButton.Left := MsgAllButton.Left + MsgAllButton.Width + ScaleX(10);
MsgSkipAllButton.Top := MsgForm.ClientHeight - ScaleY(23 + 10);
MsgSkipAllButton.Caption := 'Skip All';
MsgSkipAllButton.Tag:= bidSkipAll;
MsgSkipAllButton.OnClick := @MsgButtonOnClick;

MsgCancelButton := TButton.Create(MsgForm);
MsgCancelButton.Parent := MsgForm;
MsgCancelButton.Width := ScaleX(75);
MsgCancelButton.Height := ScaleY(23);
MsgCancelButton.Left := MsgForm.ClientWidth - MsgCancelButton.Width - ScaleX(20);
MsgCancelButton.Top := MsgForm.ClientHeight - ScaleY(23 + 10);
MsgCancelButton.Caption := 'Skip';
MsgCancelButton.ModalResult := mrCancel;

MsgDelButton := TButton.Create(MsgForm);
MsgDelButton.Parent := MsgForm;
MsgDelButton.Width := ScaleX(75);
MsgDelButton.Height := ScaleY(23);
MsgDelButton.Left := MsgCancelButton.Left - MsgDelButton.Width - ScaleX(10);
MsgDelButton.Top := MsgForm.ClientHeight - ScaleY(23 + 10);
MsgDelButton.Caption := 'Delete';
MsgDelButton.ModalResult := mrOk;

MsgForm.ActiveControl:= MsgCancelButton;

if MsgForm.ShowModal() = mrOk then
Result:= True
else
Result:= False;
end;

procedure DeleteFiles();
var
SR: TFindRec;
i: integer;
str: string;
ResultCode: Integer;
begin
DelAllReadOnly:= False;
SkipAllReadOnly:= False;
for i:= CheckListBox.Items.Count - 1 downto 0 do
begin
if CheckListBox.State[i] = cbChecked then
begin
str:= Trim(TStrings(CheckListBox.ItemObject[i]).Text);
FindFirst(str, SR);
if ((SR.Attributes and FILE_ATTRIBUTE_READONLY) = FILE_ATTRIBUTE_READONLY) then
if Not (DelAllReadOnly or SkipAllReadOnly) then
if DelMsgBox(SR.Name) then
Exec('attrib', ' -h -s -r ' + '"' + str + '"',
'', SW_HIDE, ewWaitUntilTerminated, ResultCode);
if DelAllReadOnly then
Exec('attrib', ' -h -s -r ' + '"' + str + '"',
'', SW_HIDE, ewWaitUntilTerminated, ResultCode);
FindClose(SR);
DeleteFile(str);
RemoveDir(str);
end;
end;
end;

procedure BrowseRemainedFiles();
begin
Form:= CreateCustomForm;
Form.ClientWidth := ScaleX(500);
Form.ClientHeight := ScaleY(400);
Form.Caption := 'Files to delete';
Form.Center;

CheckListBox := TNewCheckListBox.Create(Form);
CheckListBox.Left:= ScaleX(20);
CheckListBox.Top:= ScaleY(20);
CheckListBox.Width:= Form.ClientWidth - ScaleX(20*2);
CheckListBox.Height:= Form.ClientHeight - ScaleY(23*2 + 20);
CheckListBox.Offset:= 0;
CheckListBox.Parent:= Form;

AllButton := TButton.Create(Form);
AllButton.Parent := Form;
AllButton.Width := ScaleX(75);
AllButton.Height := ScaleY(23);
AllButton.Left := ScaleX(20);
AllButton.Top := Form.ClientHeight - ScaleY(23 + 10);
AllButton.Caption := 'Select All';
AllButton.Tag:= 0;
AllButton.OnClick := @ButtonOnClick;

UnAllButton := TButton.Create(Form);
UnAllButton.Parent := Form;
UnAllButton.Width := ScaleX(75);
UnAllButton.Height := ScaleY(23);
UnAllButton.Left := AllButton.Left + AllButton.Width + ScaleX(10);
UnAllButton.Top := Form.ClientHeight - ScaleY(23 + 10);
UnAllButton.Caption := 'Clear All';
UnAllButton.Tag:= 1;
UnAllButton.OnClick := @ButtonOnClick;

InvertButton := TButton.Create(Form);
InvertButton.Parent := Form;
InvertButton.Width := ScaleX(75);
InvertButton.Height := ScaleY(23);
InvertButton.Left := UnAllButton.Left + UnAllButton.Width + ScaleX(10);
InvertButton.Top := Form.ClientHeight - ScaleY(23 + 10);
InvertButton.Caption := 'Invert';
InvertButton.OnClick := @InvertOnClick;

CancelButton := TButton.Create(Form);
CancelButton.Parent := Form;
CancelButton.Width := ScaleX(75);
CancelButton.Height := ScaleY(23);
CancelButton.Left := Form.ClientWidth - CancelButton.Width - ScaleX(20);
CancelButton.Top := Form.ClientHeight - ScaleY(23 + 10);
CancelButton.Caption := 'Cancel';
CancelButton.ModalResult := mrCancel;
CancelButton.Cancel := True;

DelButton := TButton.Create(Form);
DelButton.Parent := Form;
DelButton.Width := ScaleX(75);
DelButton.Height := ScaleY(23);
DelButton.Left := CancelButton.Left - DelButton.Width - ScaleX(10);
DelButton.Top := Form.ClientHeight - ScaleY(23 + 10);
DelButton.Caption := 'Delete';
DelButton.ModalResult := mrOk;

Form.ActiveControl:= CancelButton;

CheckListBox.AddCheckBox(ExpandConstant('{app}'), '', 0, True, True, False, True, TStringList.Create);
TStrings(CheckListBox.ItemObject[0]).Text:= ExpandConstant('{app}');
FillListBox(ExpandConstant('{app}'), '*', 1);

if Form.ShowModal() = mrOk then DeleteFiles();
end;

procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
if DirExists(ExpandConstant('{app}')) and (CurUninstallStep = usPostUninstall) then
BrowseRemainedFiles();
end;

by_gangster
15-03-2012, 14:17
кто знает, как вставить это в скрипт??? (проигрывание музыки)
Код:
//************************************************ [Начало - Музыка] ***************************************************//
function BASS_Init(device: Integer; freq, flags: DWORD; win: hwnd; CLSID: Integer): Boolean; external 'BASS_Init@files:BASS.dll stdcall delayload';
function BASS_StreamCreateFile(mem: BOOL; f: PAnsiChar; offset: DWORD; length: DWORD; flags: DWORD): DWORD; external 'BASS_StreamCreateFile@files:BASS.dll stdcall delayload';
function BASS_Start: Boolean; external 'BASS_Start@files:BASS.dll stdcall delayload';
function BASS_ChannelPlay(handle: DWORD; restart: BOOL): Boolean; external 'BASS_ChannelPlay@files:BASS.dll stdcall delayload';
function BASS_ChannelIsActive(handle: DWORD): Integer; external 'BASS_ChannelIsActive@files:BASS.dll stdcall delayload';
function BASS_ChannelPause(handle: DWORD): Boolean; external 'BASS_ChannelPause@files:BASS.dll stdcall delayload';
function BASS_Pause: Boolean; external 'BASS_Pause@files:BASS.dll stdcall delayload';
function BASS_Stop: Boolean; external 'BASS_Stop@files:BASS.dll stdcall delayload';
function BASS_Free: Boolean; external 'BASS_Free@files:BASS.dll stdcall delayload';
procedure MusicButtonClick(hBtn:HWND);
begin
sndPlaySound(ExpandConstant('{tmp}\Click.wav'), $0001);
if BtnGetChecked(MusicButton) then BASS_ChannelPause(mp3Handle)
else if BASS_ChannelIsActive(mp3Handle)=BASS_ACTIVE_PAUSED then BASS_ChannelPlay(mp3Handle, False);
end;
procedure InsertMusic;
begin
ExtractTemporaryFile('MusicButton.png');
ExtractTemporaryFile('BASS.dll');
ExtractTemporaryFile('Music.mp3');
MusicButton:=BtnCreate(WizardForm.Handle,ScaleX(717),ScaleY(3),ScaleX(70),ScaleY(52),ExpandConstant( '{tmp}\MusicButton.png'),0,True);
BtnSetEvent(MusicButton,BtnClickEventID,WrapBtnCallback(@MusicButtonClick,1));
BtnSetEvent(MusicButton,BtnMouseEnterEventID,WrapBtnCallback(@WFBtnEnter,1));
BtnSetVisibility(MusicButton,True);
BtnSetCursor(MusicButton,LoadCursorFromFile(ExpandConstant('{tmp}\Cursor2.ani')));
mp3Name:=ExpandConstant('{tmp}\Music.mp3');
BASS_Init(-1,44100,0,0,0);
mp3Handle:=BASS_StreamCreateFile(FALSE,PAnsiChar(mp3Name),0,0,BASS_SAMPLE_LOOP);
BASS_Start;
BASS_ChannelPlay(mp3Handle,False); »

помогите это в скрипт вставить, пожалуйста

vitl
15-03-2012, 14:55
Пожалуйста, помогите решить задачу.

Имеем код:


[Setup]
AppName=MyProg
AppVerName=MyProg
DefaultDirName={reg:HKLM\SOFTWARE\MyProg\Inform,InstallPath} ; Здесь путь до программной папки
AppVersion=1.1.0.1
UsePreviousAppDir=no
AppendDefaultDirName=no
AllowRootDirectory=yes
DirExistsWarning=no
DisableStartupPrompt=yes
DisableReadyPage=yes
; DisableFinishedPage=yes
DisableDirPage=True
DisableProgramGroupPage=yes
OutputBaseFilename=Setup
Compression=lzma
SolidCompression=no
Uninstallable=false

[Languages]
Name: "russian"; MessagesFile: "compiler:Languages\Russian.isl"

[Files]
Source: {src}\add\*; DestDir: {app}\Serv\Lic\; Flags: external recursesubdirs skipifsourcedoesntexist

[_Code]
function InitializeSetup(): Boolean;
var
ResultCode: Integer;
s, ResultStr:string;
begin
Result:=True;
If not RegKeyExists(HKLM, 'SOFTWARE\MyProg\Inform')
then
begin
MsgBox('Программа не установлена или установлена неверно.' #13#13 'Дальнейшая работа Мастера невозможна.', mbError, mb_Ok);
Result:=False;
end
else
begin
MsgBox('Программа успешно обнаружена.' #13#13 'Скопируйте дополнения в папку:'+ExpandConstant('{app}')+'\Serv\Lic', mbInformrmation, mb_Ok);
end;
end;



1. Не хочет работать в MsgBox-е ExpandConstant('{app}') . Помогите исправить ошибку.

2. В идеале хотелось бы кое-что усовершенствовать:
вместо последнего простого предложения "скопировать в папку дополнения" в начале проверить, есть ли файлы в папке {src}\add\.
Если эта папка пустая, то предложить (Если "ДА") указать путь до папки с дополнениями или (Если "НЕТ") вывести сообщение (оно в коде уже имеется), т.е. "Скопируйте дополнения в папку {reg:HKLM\SOFTWARE\MyProg\Inform,InstallPath} после установки"

R.i.m.s.k.y.
15-03-2012, 14:59
Не хочет работать в MsgBox-е ExpandConstant('{app}') »
и не будет тк переменная {app} становится известной после страницы выбора директории установки

про указать папку выше пример как делать свою форму с выбором папки

vitl
15-03-2012, 15:20
и не будет тк переменная {app} становится известной после страницы выбора директории установки »

Хорошо, что дополнить в коде, чтобы {app} определилось?

R.i.m.s.k.y.
15-03-2012, 15:27
vitl, почитать в справке Installation order
по сути: выполнять после страницы wpSelectDir, как вариант проверять на странице wpSelectComponents или повесить на NextButtonClick

rasim933
15-03-2012, 17:42
Стёр везде ковычки. Попробовал прописать полный путь вот так:
[Run]
Filename: "{app}\psxfin.exe"; Description: "{cm:LaunchProgram,Spider-Man 2. Enter Electro (PS1)}"; Flags: nowait postinstall skipifsilent
Filename: {sd}\Program Files (x86)\Spider-Man 2. Enter Electro (PS1)\text\Read Me (for 2003).doc; Description: {cm:LaunchProgram,файл с инфой о запуске игры (2003)}; Flags: nowait postinstall skipifsilent
Filename: {sd}\Program Files (x86)\Spider-Man 2. Enter Electro (PS1)\text\Read Me (for 2010).doc; Description: {cm:LaunchProgram,файл с инфой о запуске игры (2010)}; Flags: nowait postinstall skipifsilentНо теперь новая ошибка -> http://i29.fastpic.ru/thumb/2012/0315/30/e5246dbf5f5be415a04f0647a9a2f130.jpeg (http://fastpic.ru/view/29/2012/0315/e5246dbf5f5be415a04f0647a9a2f130.jpg.html). Может проблема в флагах?


Кто нибудь знает, как сделать так, чтоб при повторной установке игры (без её удаления), появлялось сообщение об перночальном удалении старых файлов игры? Может об этом где-то написано?

Johny777
15-03-2012, 18:12
Может проблема в флагах? »
так точно
для документа ворд не хватает флага
писал тебе раньше
важно в твоём случае ставить флаг (уже стоит) shellexec, тк файл открывается внешней программой типа ворда »
сообщение об перночальном удалении старых файлов игры? »
не сосем понятно чего ты хочешь.
Сообщение (и не только его) вывести можно, что установлена
или в сообщении написать чтоб удалили?
или чтоб после сообщения вызывался деинсталятор?

R.i.m.s.k.y.
15-03-2012, 18:24
rasim933, флаг shellexec потерял
написано в шапке - сборник вопросов
Как прогу то будешь определять? Есть ли реперные точки типа значения в реестре или спецфайликов?




© OSzone.net 2001-2012