routerboy309
asked on
Copy files and create folders from CD-ROM to PC
Hello All -
I need to copy the contents of a CD-ROM to a pre-selected path. The path (edSelected) gets picked when
the user clicks Btn2 and navigates to the folder (browse folder), and then I'll append the folder 'app'
to that path.
For example:
They select:
C:\Program Files
When they click the button, the folder 'app' gets added (C:\Program Files\app) and the contents of the
CD-ROM gets copied.
The code below works, but I have two issues:
A) The pathing issue places an extra '\' when they select the root to be the path. C:\ - becomes C:\\app
B) I can't get the value - StrECopy to read the CD-ROM drive letter so I can copy. Trying to use ExtractFileDir(Application .ExeName), but that fails.
I can get the folders and files to copy from one folder on the PC to another on the PC, but not from the CD-ROM to PC.
procedure CopyFiles(const FromFolder: string; const ToFolder: string);
var
Fo : TSHFileOpStruct;
buffer : array[0..4096] of char;
p : pchar;
begin
FillChar(Buffer, sizeof(Buffer), #0);
p := @buffer;
StrECopy(p, PChar(FromFolder)); //this is folder that you want to copy
FillChar(Fo, sizeof(Fo), #0);
Fo.Wnd := Application.Handle;
Fo.wFunc := FO_COPY;
Fo.pFrom := @Buffer;
Fo.pTo := PChar(ToFolder); //this is where the folder will go
Fo.fFlags := 0;
if ((SHFileOperation(Fo) <> 0) or (Fo.fAnyOperationsAborted <> false)) then
ShowMessage('File copy process cancelled')
end;
procedure TForm1.Btn1Click(Sender: TObject);
begin
Close;
end;
// problem here: If you pick the root of the drive, you get two '\\'
// example: pick C: drive and you get C:\\App
//pick a normal folder, and it works
procedure TForm1.Btn2Click(Sender: TObject);
var
s: string;
begin
if SelectDirectory('Select Directory','',S) then
edSelected.Caption := s + '\app';
end;
//need StrECopy to default to the CD-ROM. On it an eniter group of folders and files
//need to copied
procedure TForm1.Btn3Click(Sender: TObject);
var
Fo : TSHFileOpStruct;
buffer : array[0..4096] of char;
p : pchar;
begin
FillChar(Buffer, sizeof(Buffer), #0);
p := @buffer;
StrECopy(p, 'C:\MyDir\*.*');
FillChar(Fo, sizeof(Fo), #0);
Fo.Wnd := Handle;
Fo.wFunc := FO_COPY;
Fo.pFrom := @Buffer;
Fo.pTo := pchar(edSelected.caption);
if ((SHFileOperation(Fo) <> 0) or (Fo.fAnyOperationsAborted <> false)) then
ShowMessage('Cancelled')
end;
Since this is a double questions, I've double up on the points.
RB
I need to copy the contents of a CD-ROM to a pre-selected path. The path (edSelected) gets picked when
the user clicks Btn2 and navigates to the folder (browse folder), and then I'll append the folder 'app'
to that path.
For example:
They select:
C:\Program Files
When they click the button, the folder 'app' gets added (C:\Program Files\app) and the contents of the
CD-ROM gets copied.
The code below works, but I have two issues:
A) The pathing issue places an extra '\' when they select the root to be the path. C:\ - becomes C:\\app
B) I can't get the value - StrECopy to read the CD-ROM drive letter so I can copy. Trying to use ExtractFileDir(Application
I can get the folders and files to copy from one folder on the PC to another on the PC, but not from the CD-ROM to PC.
procedure CopyFiles(const FromFolder: string; const ToFolder: string);
var
Fo : TSHFileOpStruct;
buffer : array[0..4096] of char;
p : pchar;
begin
FillChar(Buffer, sizeof(Buffer), #0);
p := @buffer;
StrECopy(p, PChar(FromFolder)); //this is folder that you want to copy
FillChar(Fo, sizeof(Fo), #0);
Fo.Wnd := Application.Handle;
Fo.wFunc := FO_COPY;
Fo.pFrom := @Buffer;
Fo.pTo := PChar(ToFolder); //this is where the folder will go
Fo.fFlags := 0;
if ((SHFileOperation(Fo) <> 0) or (Fo.fAnyOperationsAborted <> false)) then
ShowMessage('File copy process cancelled')
end;
procedure TForm1.Btn1Click(Sender: TObject);
begin
Close;
end;
// problem here: If you pick the root of the drive, you get two '\\'
// example: pick C: drive and you get C:\\App
//pick a normal folder, and it works
procedure TForm1.Btn2Click(Sender: TObject);
var
s: string;
begin
if SelectDirectory('Select Directory','',S) then
edSelected.Caption := s + '\app';
end;
//need StrECopy to default to the CD-ROM. On it an eniter group of folders and files
//need to copied
procedure TForm1.Btn3Click(Sender: TObject);
var
Fo : TSHFileOpStruct;
buffer : array[0..4096] of char;
p : pchar;
begin
FillChar(Buffer, sizeof(Buffer), #0);
p := @buffer;
StrECopy(p, 'C:\MyDir\*.*');
FillChar(Fo, sizeof(Fo), #0);
Fo.Wnd := Handle;
Fo.wFunc := FO_COPY;
Fo.pFrom := @Buffer;
Fo.pTo := pchar(edSelected.caption);
if ((SHFileOperation(Fo) <> 0) or (Fo.fAnyOperationsAborted <> false)) then
ShowMessage('Cancelled')
end;
Since this is a double questions, I've double up on the points.
RB
oops,
change
procedure TForm1.Button8Click(Sender : TObject);
to
procedure TForm1.Btn2Click(Sender: TObject);
change
procedure TForm1.Button8Click(Sender
to
procedure TForm1.Btn2Click(Sender: TObject);
One hint for copying from CD-ROM. All files on a CD-ROM are read only and may stay read only when copied. You may need to change the file attributes.
ASKER
Cynna -
Thanks for the iinfo. I'm testing it now.
robert_marquardt -
You bring up a good point. 3 of 6 files will need to be changed.
RB
Thanks for the iinfo. I'm testing it now.
robert_marquardt -
You bring up a good point. 3 of 6 files will need to be changed.
RB
ASKER
Cynna -
A) Is solved. :)
B) I have this:
StrECopy(p, 'C:\MyDir\*.*');
StrECopy = the copy folder - but right now its hard coded. I need the application to know where its at, so StrECopy can gets its value and then appending a folder to that.
For example:
My CD-ROM is F. So StrECopy reads the value and adds the folder APP to it for a result of
StrECopy(p, 'F:\App\*.*');
In short, when the user clicks the button, the folder App gets created and its contents of F:\App gets moved to the Hard drive location (the part you fix 'A' of this question already).
I tried using ExtractFilePath(Applicatio n.EXEName) +'\app\*.* ' but this falied:
StrECopy(p, ExtractFilePath(Applicatio n.EXEName) +'\app\*.* );
Does this help?
RB
A) Is solved. :)
B) I have this:
StrECopy(p, 'C:\MyDir\*.*');
StrECopy = the copy folder - but right now its hard coded. I need the application to know where its at, so StrECopy can gets its value and then appending a folder to that.
For example:
My CD-ROM is F. So StrECopy reads the value and adds the folder APP to it for a result of
StrECopy(p, 'F:\App\*.*');
In short, when the user clicks the button, the folder App gets created and its contents of F:\App gets moved to the Hard drive location (the part you fix 'A' of this question already).
I tried using ExtractFilePath(Applicatio
StrECopy(p, ExtractFilePath(Applicatio
Does this help?
RB
ASKER
I may have found the solution.
StrECopy(p,pchar(ExtractFi lePath(App lication.E XEName)+'\ app\*.*')) ;
Cynna -
Can you check my code? Looking for options towards 'read only' changing attribute situation, too.
RB
StrECopy(p,pchar(ExtractFi
Cynna -
Can you check my code? Looking for options towards 'read only' changing attribute situation, too.
RB
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Sorry,
Forgot to add cast PChar() to StrECopy(p, ...) statements:
Wherever you have StrECopy(p,...), change it to StrECopy(p, PChar(...));
For example:
StrECopy(p, s+'*.*');
change to:
StrECopy(p, PChar(s+'*.*'));
Forgot to add cast PChar() to StrECopy(p, ...) statements:
Wherever you have StrECopy(p,...), change it to StrECopy(p, PChar(...));
For example:
StrECopy(p, s+'*.*');
change to:
StrECopy(p, PChar(s+'*.*'));
> Looking for options towards 'read only' changing attribute situation, too
Copy/Paste:
------------------
procedure ClearReadOnlyAttrib(const Filename: string );
var
Attributes: word;
begin
Attributes := FileGetAttr( Filename );
FileSetAttr( Filename, (Attributes and not faReadOnly));
end;
Copy/Paste:
------------------
procedure ClearReadOnlyAttrib(const Filename: string );
var
Attributes: word;
begin
Attributes := FileGetAttr( Filename );
FileSetAttr( Filename, (Attributes and not faReadOnly));
end;
ASKER
Your due dilegence is certainly worth me giving you the points. :)
"You need to let user decide FROM where files should be
copied (choose source folder)."
No. The User doesn't get the option to change where the files are to be copied FROM. Only gets to change where to PUT the files. So I Guess #2 is closest.
StrECopy is set based on where the CD-ROM was inserted with appending the value of 'APP' for the folder (and its contents).
I want the code to read the drive where the CD-ROM was inserted, append the path of that value with APP, and then when the user clicks the btn, the entire contents of the folder is transferred to the PC.
I think you have plenty of GOOD examples for me to test with. Plus, I like the fact you provided the code sample for the read only issue, hense, I've changed the point value. If my explaination is still unclear, please let me know.
"You need to let user decide FROM where files should be
copied (choose source folder)."
No. The User doesn't get the option to change where the files are to be copied FROM. Only gets to change where to PUT the files. So I Guess #2 is closest.
StrECopy is set based on where the CD-ROM was inserted with appending the value of 'APP' for the folder (and its contents).
I want the code to read the drive where the CD-ROM was inserted, append the path of that value with APP, and then when the user clicks the btn, the entire contents of the folder is transferred to the PC.
I think you have plenty of GOOD examples for me to test with. Plus, I like the fact you provided the code sample for the read only issue, hense, I've changed the point value. If my explaination is still unclear, please let me know.
>I want the code to read the drive where the CD-ROM was inserted,
Did you solve this problem? How do you know in which CD drive the
CD has been inserted?
Previously you mentioned you have CD drive F:\ - if this is the case,
why bother finding out the letter of the CD drive with CD in question?
This makes sense only if you have multiple CD drives in your target system,
(for example, CD-ROM and CD-RW could be E: and F:), and you don't know
which one contains the CD.
If you want to automatically find the drive letter of the drive that
contains desired CD, you should know the CD title.
Its a bit more complicated then what you needed so far.
>... append the path of that value with APP, and then when the user clicks the btn,
>the entire contents of the folder is transferred to the PC.
This is very easy.
CopyFiles() does everything you need, so I'm puzzled, why did you use
Btn3Click() code at all?
It can be done much more easily. Assuming you know CD drive letter
(let's say F:), then just use your CopyFiles() function this way:
procedure TForm1.Btn2Click(Sender: TObject);
var DriveLetter, TargetDir: String;
begin
DriveLetter:='F:\';
if SelectDirectory('Select target folder','', TargetDir) then begin
// Be sure selected dir ends with '\':
if TargetDir[Length(TargetDir )]<>'\' then TargetDir:=TargetDir+'\';
// We want to copy files to subfolder APP of selected dir
TargetDir:=TargetDir+'APP' ;
// Finally copy all items from F:\APP:
CopyFiles(DriveLetter+'APP ', TargetDir);
end;
end;
Just copy/paste this code, and be sure you leave CopyFiles() function.
Did you solve this problem? How do you know in which CD drive the
CD has been inserted?
Previously you mentioned you have CD drive F:\ - if this is the case,
why bother finding out the letter of the CD drive with CD in question?
This makes sense only if you have multiple CD drives in your target system,
(for example, CD-ROM and CD-RW could be E: and F:), and you don't know
which one contains the CD.
If you want to automatically find the drive letter of the drive that
contains desired CD, you should know the CD title.
Its a bit more complicated then what you needed so far.
>... append the path of that value with APP, and then when the user clicks the btn,
>the entire contents of the folder is transferred to the PC.
This is very easy.
CopyFiles() does everything you need, so I'm puzzled, why did you use
Btn3Click() code at all?
It can be done much more easily. Assuming you know CD drive letter
(let's say F:), then just use your CopyFiles() function this way:
procedure TForm1.Btn2Click(Sender: TObject);
var DriveLetter, TargetDir: String;
begin
DriveLetter:='F:\';
if SelectDirectory('Select target folder','', TargetDir) then begin
// Be sure selected dir ends with '\':
if TargetDir[Length(TargetDir
// We want to copy files to subfolder APP of selected dir
TargetDir:=TargetDir+'APP'
// Finally copy all items from F:\APP:
CopyFiles(DriveLetter+'APP
end;
end;
Just copy/paste this code, and be sure you leave CopyFiles() function.
ASKER
I only used the F letter as a reference to the question. While I have mulitple CD-ROM drives, I sure many don't. So based on using the code:
(ExtractFilePath(Applicati on.EXEName )+'\app\*. *'));
adds the Drive letter to the path, right?
I just applied the answer to the read-only issue and it worked perfectly.
RB
(ExtractFilePath(Applicati
adds the Drive letter to the path, right?
I just applied the answer to the read-only issue and it worked perfectly.
RB
1. ExtractFilePath(Applicatio
should be (read my previous post, or go to Help about ExtractFilePath):
ExtractFilePath(Applicatio
2. > adds the Drive letter to the path, right?
Well, not quite. It extracts path of your application and and '\app\*.*' to it... :)
For example, if your app is called Project1, and is saved
in 'C:\Program Files\Delphi5\Projects\tes
Application.ExeName='C:\Pr
ExtractFilePath(Applicatio
ExtractFilePath(Applicatio
ASKER
Excallant! I think you just solved another issue I had. I was using Application.ExeName (and appending to it) to find a Word doc so my app would open it. But I should be using ExtractFilePath.
Also, something else just bit me in as$. My copy file routine fails on Win98... I get an error - Cannot copy File File System Error (1026). So I guess its back to the drawing board...:(
procedure TForm1.btncopyClick(Sender : TObject);
var
Fo : TSHFileOpStruct;
buffer : array[0..4096] of char;
p : pchar;
begin
FillChar(Buffer, sizeof(Buffer), #0);
p := @buffer;
StrECopy(p,pchar(ExtractFi lePath(App lication.E XEName)+'\ app\*.*')) ;
FillChar(Fo, sizeof(Fo), #0);
Fo.Wnd := Handle;
Fo.wFunc := FO_COPY;
Fo.pFrom := @Buffer;
Fo.pTo := pchar(edSelected.caption);
if ((SHFileOperation(Fo) <> 0) or (Fo.fAnyOperationsAborted <> false)) then
ShowMessage('Cancelled');
ClearReadOnlyAttrib(edSele cted.capti on + '\settings.txt');
end;
Also, something else just bit me in as$. My copy file routine fails on Win98... I get an error - Cannot copy File File System Error (1026). So I guess its back to the drawing board...:(
procedure TForm1.btncopyClick(Sender
var
Fo : TSHFileOpStruct;
buffer : array[0..4096] of char;
p : pchar;
begin
FillChar(Buffer, sizeof(Buffer), #0);
p := @buffer;
StrECopy(p,pchar(ExtractFi
FillChar(Fo, sizeof(Fo), #0);
Fo.Wnd := Handle;
Fo.wFunc := FO_COPY;
Fo.pFrom := @Buffer;
Fo.pTo := pchar(edSelected.caption);
if ((SHFileOperation(Fo) <> 0) or (Fo.fAnyOperationsAborted <> false)) then
ShowMessage('Cancelled');
ClearReadOnlyAttrib(edSele
end;
Are you shure you have
ExtractFilePath(Applicatio n.EXEName) +'\app\
folder?
If you do, what is it (copy/paste it here)?
ExtractFilePath(Applicatio
folder?
If you do, what is it (copy/paste it here)?
ASKER
Ah---You're right again. Too many '\'. Once I changed it, everythign worked right.
Thanks again!
RB
Thanks again!
RB
No problem, hope it turns out OK...
Cy.
Cy.
ASKER
It did. :) Many thanks.
I'm about to post another issue surrounding the ExtractFilePath(Applicatio n.EXEName) function and two OpenDialog components (They fail to find the proper path, sharing one path for both).
It seems you have plenty of experience and I'd like you to get the points. Since I'm not sure how the 'expert side' works, is there a way to post and hope you get the chance to answer?
RB
I'm about to post another issue surrounding the ExtractFilePath(Applicatio
It seems you have plenty of experience and I'd like you to get the points. Since I'm not sure how the 'expert side' works, is there a way to post and hope you get the chance to answer?
RB
routerboy309,
Sorry I didn't get your last comment. When you post comment on answered question, I don't get any mail notification, so I really don't know when you posted something here.
Thank you for your trust in me, but you should give everybody a chance to give you your answer. But still, if you'd like your question to be targeted at me, probably the best way would be asking the question titled 'For Cynna: files followup' or something; that will soon get my attention ;) ....
And please remember, I tipically look only at the questions I get notified on by mail (except the new ones, of course).
Thanks!
Sorry I didn't get your last comment. When you post comment on answered question, I don't get any mail notification, so I really don't know when you posted something here.
Thank you for your trust in me, but you should give everybody a chance to give you your answer. But still, if you'd like your question to be targeted at me, probably the best way would be asking the question titled 'For Cynna: files followup' or something; that will soon get my attention ;) ....
And please remember, I tipically look only at the questions I get notified on by mail (except the new ones, of course).
Thanks!
> A) The pathing issue places an extra '\' when they select the root to be the path. C:\ - becomes C:\\app
This is quite normal. Simply change your code:
procedure TForm1.Btn2Click(Sender: TObject);
var
s: string;
begin
if SelectDirectory('Select Directory','',S) then
edSelected.Caption := s + '\app';
end;
to this:
procedure TForm1.Button8Click(Sender
var s: string;
begin
if SelectDirectory('Select Directory','',S) then begin
if s[Length(s)]<>'\' then s:=s+'\';
edSelected.Caption := s + 'app';
end;
end
B) I can't get the value - StrECopy to read the CD-ROM drive letter so I can copy. Trying to use ExtractFileDir(Application
Hmmm... I don't quite understand you here.
I'll assume you want to extract drive letter of the CD-ROM.
If this is true, this function will get you first available CD drive letter in system:
function GrabCDLetter: String;
// search for first available CD drive letter in system
var i: Integer;
DriveLetters: String;
begin
DriveLetters:='DEFGHIJK';
for i:=1 to Length(DriveLetters) do begin
Result:=DriveLetters[i]+':
if GetDriveType(PChar(Result)
end;
end;
If this isn't what you need, please give simplified example (I have this: ...., but I need this: .....) to explain B) futher.