|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
||||
|
||||
Запись CD с помощью IMAPI2
Здравствуйте друзья! Призываю коллективный разум к помощи.
Как обычно наспех решаю небольшую задачу, в частности массовая запись подпапок из выбранной папки на диски (CD). Тема в интернетах освещена довольно скудно, но удалось найти статейку по imapi2 от MS, которая и была взята за основу. В целом получается всё, за одним небольшим исключением. После старта записи, мне нужно проверить что всё подходит для записи и если нет, то запросить смену диска и т.п. и сделать то же самое в цикле который пишет диски из массива папок, при этом нужно чтобы всё это дело ожидало вставки диска, проверяло его и соответственно либо продолжало итерацию, либо снова выплёвывало диск и ждало по новой. Первоначальную проверку сделал на onClick кнопки записи, через exception, а вот что делать в цикле ума не приложу, вроде как и исключение там не в тему, вроде и в библиотечках нету ничего что бы возвращало всё ОК или неОК. В общем вот код, думаю всё станет понятно. Импортированы библиотеки типов: Microsoft IMAPI2 Base Functionality Microsoft IMAPI2 File System Image Creator Из них использованы компоненты: TMsftDiscMaster2 TMsftDiscRecorder2 TMsftFileSystemImage TMsftDiscFormat2Data Код:
unit Unit1; interface uses Winapi.Windows, Winapi.Messages, Winapi.ActiveX, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.OleServer, Vcl.StdCtrls, Vcl.FileCtrl, Vcl.Menus, Vcl.ComCtrls, IMAPI2_TLB, IMAPI2FS_TLB, System.Win.ComObj; type Compare_Media_State = TOleEnum; const Compare_Media_State_UNKNOWN = $00000000; Compare_Media_State_INFORMATIONAL_MASK = $0000000F; Compare_Media_State_UNSUPPORTED_MASK = $0000FC00; Compare_Media_State_OVERWRITE_ONLY = $00000001; Compare_Media_State_STATE_RANDOMLY_WRITABLE = $00000001; Compare_Media_State_BLANK = $00000002; Compare_Media_State_APPENDABLE = $00000004; Compare_Media_State_FINAL_SESSION = $00000008; Compare_Media_State_DAMAGED = $00000400; Compare_Media_State_ERASE_REQUIRED = $00000800; Compare_Media_State_NON_EMPTY_SESSION = $00001000; Compare_Media_State_WRITE_PROTECTED = $00002000; Compare_Media_State_FINALIZED = $00004000; Compare_Media_State_UNSUPPORTED_MEDIA = $00008000; type TForm1 = class(TForm) GroupBox1: TGroupBox; Button1: TButton; RecorderComboBox: TComboBox; Button2: TButton; Edit1: TEdit; Memo1: TMemo; GroupBox2: TGroupBox; MainMenu1: TMainMenu; Vty1: TMenuItem; N1: TMenuItem; StatusBar1: TStatusBar; Label1: TLabel; TrackBar1: TTrackBar; Label2: TLabel; Button3: TButton; MsftDiscMaster: TMsftDiscMaster2; MsftDiscRecorder: TMsftDiscRecorder2; MsftFileSystemImage: TMsftFileSystemImage; MsftDiscFormat2Data: TMsftDiscFormat2Data; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure N1Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure TrackBar1Change(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; //Count copies of each folder. countCopy : integer; //Arrays is a folder-trees to write and to naming in log. treeToWrite, treeToName : array of string; const cap = 10; implementation {$R *.dfm} //Update recorder-list button. procedure TForm1.Button1Click(Sender: TObject); var i:integer; begin RecorderComboBox.Clear; for i := 0 to MsftDiscMaster.Count-1 do begin try MsftDiscRecorder.InitializeDiscRecorder(MsftDiscMaster.Item[i]); RecorderComboBox.Items.Add(MsftDiscRecorder.VendorId+' '+ MsftDiscRecorder.ProductId); MsftDiscRecorder.Disconnect; except RecorderComboBox.Items.Add('---'); end; end; RecorderComboBox.ItemIndex:=0; end; //Choose-directory button. //If folder choosen, then writing subfolders to array used 4 writing & naming. procedure TForm1.Button2Click(Sender: TObject); var choosenDirectory:string; sr: TSearchRec; i : integer; begin Edit1.Clear; i := 0; if SelectDirectory('Выберите каталог', '', choosenDirectory) then begin Edit1.Text := choosenDirectory; memo1.Lines.Add('Следующие папки будут записаны:'); if Edit1.Text[Length(Edit1.Text)] <> '\' then Edit1.Text := Edit1.Text + '\'; if FindFirst(Edit1.Text + '*.*', faAnyFile, sr) = 0 then repeat if (sr.Attr and faDirectory) <> 0 then if (sr.Name <> '.') and (sr.Name <> '..') then begin //Setting lenght of arrays if i = Length(treeToWrite) then SetLength(treeToWrite, i + cap); if i = Length(treeToName) then SetLength(treeToName, i + cap); //writing to trees treeToWrite[i] := Edit1.Text+sr.Name; treeToName[i] := sr.Name; //writing to log memo1.Lines.Add(treeToWrite[i]); i := i+1; end; until (FindNext(sr) <> 0); FindClose(sr); end else ShowMessage('Ошибка каталога! Пожалуйста выберите папку.'); end; //Writing button. //Create image 4 record, & writing according copycount. procedure TForm1.Button3Click(Sender: TObject); var DiscRoot : IFsiDirectoryItem; resimage : IFileSystemImageResult; DiscStream : IMAPI2_TLB.IStream; DR : IDiscRecorder2; i, j : integer; begin if RecorderComboBox.Items[RecorderComboBox.ItemIndex]='---' then exit; if Length(treeToWrite) = 0 then exit; try for i := 0 to Length(treeToWrite) do begin MsftDiscRecorder.InitializeDiscRecorder(MsftDiscMaster. Item[RecorderComboBox.ItemIndex]); DiscRoot:=MsftFileSystemImage.Root; if DirectoryExists(treeToWrite[i]) then DiscRoot.AddTree(treeToWrite[i], true); MsftDiscFormat2Data.Recorder:=MsftDiscRecorder.DefaultInterface; MsftDiscFormat2Data.ClientName:='IMAPI'; DR:=IDiscRecorder2(MsftDiscRecorder.DefaultInterface); MsftFileSystemImage.ChooseImageDefaults(DR); //Setup volume name MsftFileSystemImage.VolumeName:= treeToName[i]; //Writing volume name to log memo1.Lines.Add('Имя диска: ' + treeToName[i]); //Create result image to write resimage:=MsftFileSystemImage.CreateResultImage; //Create result stream DiscStream:=IMAPI2_TLB.IStream(resimage.ImageStream); memo1.Lines.Add('Подготовка диска завершена.'); for j := 1 to countCopy do begin try memo1.Lines.Add('Запись копии '+IntToStr(j)+' из '+ IntToStr(countCopy)); MsftDiscFormat2Data.Write(DiscStream); MsftDiscRecorder.EjectMedia; except on Err : EOleException do begin MsftDiscRecorder.EjectMedia; ShowMessage('Пожалуйста вставьте чистый диск!'); memo1.Lines.Add('Ожидание диска'); repeat sleep(1000); until ; memo1.Lines.Add('Диск вставлен'); j := j-1; end; end; end; MsftDiscRecorder.Disconnect; end; except on Err : EOleException do begin ShowMessage('Пожалуйста вставьте корректный диск!'); memo1.Lines.Add('Ошибка диска!'); MsftDiscRecorder.EjectMedia; end; end; end; procedure TForm1.FormCreate(Sender: TObject); var i : integer; begin //Setup copycount to default value. countCopy := TrackBar1.Position + 1; //Initialize recorders on start application RecorderComboBox.Clear; for i := 0 to MsftDiscMaster.Count-1 do begin try MsftDiscRecorder.InitializeDiscRecorder(MsftDiscMaster.Item[i]); RecorderComboBox.Items.Add(MsftDiscRecorder.VendorId+' ' +MsftDiscRecorder.ProductId); MsftDiscRecorder.Disconnect; except RecorderComboBox.Items.Add('---'); end; end; RecorderComboBox.ItemIndex:=0; end; procedure TForm1.N1Click(Sender: TObject); begin Form1.Close; end; //Setup copycount manually by changing trackbar position procedure TForm1.TrackBar1Change(Sender: TObject); begin countCopy := TrackBar1.Position + 1; memo1.Lines.Add('Количество копий каждой папки: ' + IntToStr(countCopy)); end; end. ps. Заранее прошу прощения, не знаю как его закатать под спойлер. Также буду благодарен за любые советы в части улучшения кода/производительности. |
#2
|
||||
|
||||
Собственно вопрос заключается в том как правильно сделать циклическую проверку на наличие "корректного" диска в цикле в строке 173, сейчас там лабуда, один из вариантов на "попробовать", который не работает. ООоооооочень прошу помощииии....!!!
Последний раз редактировалось ilikecrunch, 29.11.2012 в 14:54. |