Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations derfloh on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

copy files accross network 1

Status
Not open for further replies.

room24

Programmer
Dec 28, 2003
83
JM
how would i copy a specific file from my computer to a specific place on the computers on my network using delphi
 
Provided that the computer running your application has 'mapped' the network drives, the simplist way is just a matter of using 'filecopy' or 'copyfile' to the required location.

This uses the rather eaisier to use copyfile procedure provided in the fmxutils unit in you Delphi demos/docs folder.

e.g.
If 'Filename' is the full path of the file you want to copy

CopyFile(Filename, location);

where location could be 'G:\backup\' + extractfilename(Filename)

If the network is not mapped then things get more complicated.



Steve
Two things are infinite
The Universe and Human stupidity: Einstein.
(He wasn't too sure about the Universe)
 
Hi,

you can do this using the movefileex API function.

like this (untested) :

Code:
function CopyFileAcrossNetwork(source, dest : string): boolan;
Result:=MoveFileEx(PChar(source),PChar(dest),MOVEFILE_COPY_ALLOWED or MOVEFILE_WRITE_THROUGH);

source is local filename like 'c:\winnt\temp.log';
if dest is on a different volume/network it will copy the file. like :'\\myserver\c$'

make sure that the logged in account has the rights to write to the network destination. If you use this function from inside a service application you must start the service with a domain account and not the system account.

cheers

--------------------------------------
What You See Is What You Get
 
Movefileex is in the same group as CopyFile, My Delphi Help here dosnt specify the effect of the MOVEFILE_WRITE_THROUGH constant?

but MOVEFILE_COPY_ALLOWED makes it simulate The API Function
'CopyFile(pchar; pcahar; longbool);
(This is the API function used by the demo function I mentioned)
CopyFile(const filename, destname: string);

In which case the Mapping issue would still apply.




Steve
Two things are infinite
The Universe and Human stupidity: Einstein.
(He wasn't too sure about the Universe)
 
Hi sggaunt,
you're correct with copyfile. my service uses movefileex (which offcourse MOVES the file). I'm 100% sure you can use an UNC name as destname since I'm doing this from my app. so you don't need local mapped network drives...

--------------------------------------
What You See Is What You Get
 
Because this has mega implications for several of my applications (one in particular) you get a star for putting me on the write track whosrdaddy.

Room24
This is an important point it dosnt work if you do it otherwise. You should not put a colon ':' after the remote drive letter in the destination field.

As can be seen in this working example.
I have used copyfile here because I dont want to delete the origin file.

Code:
procedure TForm1.Button1Click(Sender: TObject);
begin
  if copyfileacrossnetwork('c:\T1.TXT','\\development5\c\T1.TXT')then
     showmessage('OK')
  else
     showmessage('ooerrr');

end;

function TForm1.CopyFileAcrossNetwork(source, dest : string): boolean;
begin
   Result := CopyFile(PChar(source), pchar(dest), FALSE);
end;

Steve
Two things are infinite
The Universe and Human stupidity: Einstein.
(He wasn't too sure about the Universe)
 
Sorry to come back to this but there is another problem.
The above code is fine, if you know what the UNC name of the network drive is.
I have been experimenting with e.g.

Code:
WNetGetUniversalName(pchar(Local), REMOTE_NAME_INFO_LEVEL, pchar(NameStruct), MaxNetPathLen)

But agin this only seems to work if the network drives are mapped.
The above code still returns an 'invalid parametr error' when passed the local address ['L:/'] of a mapped drive but returns 'not connected' in all other cases.
['a:/' to 'k:/' and 'm:/ to 'z']
Is there any way to get the UNC names of all network drives?

Steve
Be excellent to each other and Party on!
 
so what you really want is to see the (also hidden) shares that are available on a remote machine?

--------------------------------------
What You See Is What You Get
 
this is how it should be used :

Code:
function GetUNCName(const LocalPath: string): string; 
var 
  BufferSize: DWord; 
  DummyBuffer: Byte; 
  Buffer: Pointer; 
  Error: DWord; 
begin 
  BufferSize := 1; 
  WNetGetUniversalName(PChar(LocalPath), UNIVERSAL_NAME_INFO_LEVEL, @DummyBuffer, BufferSize); 
  Buffer := AllocMem(BufferSize); 
  try 
    Error := WNetGetUniversalName(PChar(LocalPath), UNIVERSAL_NAME_INFO_LEVEL, Buffer, BufferSize); 
    if Error <> NO_ERROR then 
      begin 
        SetLastError(Error); 
        RaiseLastWin32Error; 
      end; 
    Result := PUniversalNameInfo(Buffer)^.lpUniversalName 
  finally 
    FreeMem(Buffer); 
  end; 
end; 


...
 str := GetUNCName('y:\abc\')

--------------------------------------
What You See Is What You Get
 
Hmm
Your code snippit only finds the single mapped drive, anything else results in a 'network connection does not exist' error, which is what you would expect from my previous experiment.

The first function on the link site just hangs ups mostly or returns the mapped drive only.

The second just seems to return the Domain name and nothing else.
I have full access on our P2P network and everything is shared! I donmt know if this would make a difference but This machine runs XP pro as does one other, the rest are 98SE or 95.

I will mess around with them see if I can see whats happening.








Steve
Be excellent to each other and Party on!
 
messed around and found that the second link function
is returning the domian name because it is searching down the XP network tree thus:-

e.g.

Entire network contains
Microsoft terminal services
Microsoft windows network (The one we want)
Microsoft Web client

It then drops down a level and finds nothing in 'Terminal services' (as we would expect)
then it does 'Windows network' and here it finds the domain name which it sticks in the computers list. then it gives up.

This differs from the structure of the network neigbourhood tree in W98.

If this is the reason then to ensure that this works on all networks it will have to be (much) more complex.







Steve
Be excellent to each other and Party on!
 
That does it !

I had to change the 'cardinal' type to 'longint' (maybe because I am using D3 here)
and
I had to change this
{ Add a child to the selected TreeNode }
// itc := trvNetwork.Items.AddChild(it, s);
itc := Treeview1.Items.AddChild(it, s);

Where they seem to have renamed the treeview but only within the GetNetwork function.

Yes it works and its much quicker than windows explorer!!

room24
Don't know if you have been following all this, but the crux is.
If your application is an 'in house' program then you will (most likly) know the UNC names of the computers on the network and can hard wire this into your app.
If you want to deploy your programs to joe public then you cant expect users to have that information, and windows dialogs dont display UNC names. So your program will idealy have the ability to find the UNC names avalible.





Steve
Be excellent to each other and Party on!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top