Copying Directories

Aug 3, 2009 at 6:35 PM

The CopyFileFromHostToGuest method says it can copy directories.  How do you do this?  Because when I put in the directpry it gives an exception.

Drew

Coordinator
Aug 4, 2009 at 1:18 AM

I have this working for a directory with ESX without any issues. What VMWare server are you using?

If you're copying a large volume of files I recommend going the VMWareTasks.Tools route, mapping the drive and doing a recursive copy via regular filesystem functions.

Aug 4, 2009 at 4:01 PM
Edited Aug 4, 2009 at 4:18 PM

I am using ESX Server 3i 3.5.  I am calling CopyFileFromHostToGuest().  Do I need to have a backslash at the end of the address as in C:\someFolder\ or C:\someFolder.  Also by the tools route do you mean launching the VMWare Tools program and going through that?  Also the exception I am getting is a file not found exception.

Coordinator
Aug 6, 2009 at 1:16 PM

No no, sorry I wasn't clear.

When I have a moment I'll try CopyFileFromHostToGuest to see whether it's copying a directory for me on ESX 3i 3.5. No idea about a backslash. Since I wrote that doc, I distinctly remember it did, so either I was crazy or something is not right. I would bring this question up on VMWare Communities, someone from VMWare should clarify whether this is by design.

VMWareTasks comes with a library called VMWare Tools. It simplifies some additional tasks, notably it can take the IP of your guest operating system and map \\ip\c$ for example. Then you can copy files or directories using normal file copy API.

        void CopyFiles(string sourcePath, string destinationPath)
        {
            if (File.Exists(sourcePath))
            {
                // this is a file, target is a directory or a file
                if (Directory.Exists(destinationPath))
                {
                    // target is a directory
                    File.Copy(sourcePath, Path.Combine(destinationPath, Path.GetFileName(sourcePath)), true);
                }
                else
                {
                    File.Copy(sourcePath, destinationPath, true);
                }
            }
            else
            {
                if (!Directory.Exists(destinationPath))
                {
                    Directory.CreateDirectory(destinationPath);
                }

                string[] systementries = Directory.GetFileSystemEntries(sourcePath);

                foreach (string systementry in systementries)
                {
                    if (Directory.Exists(systementry))
                    {
                        CopyFiles(systementry, Path.Combine(destinationPath, Path.GetFileName(systementry)));
                    }
                    else
                    {
                        File.Copy(systementry, Path.Combine(destinationPath, Path.GetFileName(systementry)), true);
                    }
                }
            }
        }

 

May 14, 2010 at 10:07 AM
Edited May 14, 2010 at 10:08 AM

Dear dblock,

I am following your suggestion from  this thread, but I can't figure out the right way.

        private void CopyFilesFromHostToGuest()
        {
            string from = ConfigurationData.ThisAssemblyDirectory +@"\"+ ConfigurationManager.AppSettings["RelativePathFromBinToRoot"];

            var driveInfo = new MappedNetworkDriveInfo(@"\\" + GuestShell.IpAddress + @"\" + "C$" + @"\");

            var mappedNetworkDrive = new MappedNetworkDrive(VirtualMachine, driveInfo);
            mappedNetworkDrive.MapNetworkDrive();

            CopyFiles(from,mappedNetworkDrive.GuestPathToNetworkPath(RootDirAtGuest));
        }

It seems I should add login password to map path right?

Maybe someone have the example that works?

Thank in advance!

 

Coordinator
May 14, 2010 at 11:45 AM

This is how I do it in RemoteInstall:

                    string guestRootPath = Path.GetPathRoot(guestPath);
                    MappedNetworkDriveInfo mappedNetworkDriveInfo = new MappedNetworkDriveInfo(guestRootPath);
                    mappedNetworkDriveInfo.Username = username;
                    mappedNetworkDriveInfo.Password = password;
                    mappedNetworkDriveInfo.Auto = false;
                    Console.WriteLine(" Mapping 'Remote:{0}' as '{1}'", mappedNetworkDriveInfo.RemotePath, _username);
                    using (MappedNetworkDrive mappedNetworkDrive = new MappedNetworkDrive(_vm, mappedNetworkDriveInfo))
                    {
                     string guestNetworkPath = mappedNetworkDrive.GuestPathToNetworkPath(guestPath);
                     string guestNetworkRootPath = mappedNetworkDrive.GuestPathToNetworkPath(guestRootPath);
                     ConsoleOutput.WriteLine(" Resolving 'Remote:{0}'", guestNetworkRootPath);
                     mappedNetworkDrive.MapNetworkDrive();
                     Console.WriteLine(" Copying '{0}' => 'Remote:{1}'", hostPath, guestNetworkPath);
                     CopyFiles(hostPath, guestNetworkPath);
                    }

You might want to take a complete trimmed down version of VMWareMappedVirtualMachine.cs from the RemoteInstall project.

May 17, 2010 at 8:42 AM

Thanks much. I am carefully looking at RemoteInstall Project.

However, even without any software, just windows I failed to map XP C$ from Win7. It continiously asked for login/password. I tried many different possibilities and finally decided to share folder at the host machine, since it is ok for my requirements.

 

Coordinator
May 17, 2010 at 11:54 AM

Windows 7 administrative shares are not enabled by default. See this post.

May 17, 2010 at 12:05 PM

My post was not clear (

I tried to map "IP of XP sys"\C$ and connect to it from Win7.

Jun 5, 2010 at 6:16 PM

I have found the solution for mapping C$ of some Win XP machine.

To make it work I disabled "Simple file sharing"

http://support.microsoft.com/kb/307874/en-us