using System;
using System.Collections.Generic;
using System.IO;
using Interop.VixCOM;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Drawing;
namespace Vestris.VMWareLib
{
///
/// Virtual machine clone type.
///
public enum VMWareVirtualMachineCloneType
{
///
/// A full, independent clone of the virtual machine.
///
Full = Constants.VIX_CLONETYPE_FULL,
///
/// A linked clone is a copy of a virtual machine that shares virtual disks with the parent virtual
/// machine in an ongoing manner.
///
Linked = Constants.VIX_CLONETYPE_LINKED
}
///
/// A VMWare Virtual Machine.
///
public class VMWareVirtualMachine : VMWareVixHandle
{
///
/// Guest file info.
///
public class GuestFileInfo
{
private int _flags = 0;
private long _fileSize = 0;
private Nullable _lastModified = null;
private string _guestPathName;
///
/// File size in bytes, zero for directories.
///
public long FileSize
{
get { return _fileSize; }
set { _fileSize = value; }
}
///
/// File attributes/flags.
///
public int Flags
{
get { return _flags; }
set { _flags = value; }
}
///
/// True if directory.
///
public bool IsDirectory
{
get { return (_flags & Constants.VIX_FILE_ATTRIBUTES_DIRECTORY) > 0; }
}
///
/// True if symbolic link.
///
public bool IsSymLink
{
get { return (_flags & Constants.VIX_FILE_ATTRIBUTES_SYMLINK) > 0; }
}
///
/// Last modified time.
///
public Nullable LastModified
{
get { return _lastModified; }
set { _lastModified = value; }
}
///
/// Guest file or directory name.
///
public string GuestPathName
{
get { return _guestPathName; }
set { _guestPathName = value; }
}
}
///
/// An indexer for variables.
///
public class VariableIndexer
{
private IVM2 _handle;
private int _variableType;
///
/// A variables indexer.
///
/// Virtual machine's variables to index.
/// Variable type, one of the following.
///
/// Constants.VIX_VM_GUEST_VARIABLE
/// Constants.VIX_VM_CONFIG_RUNTIME_ONLY
/// Constants.VIX_GUEST_ENVIRONMENT_VARIABLE
///
///
public VariableIndexer(IVM2 vm, int variableType)
{
_handle = vm;
_variableType = variableType;
}
///
/// Environment, guest and runtime variables.
///
/// Name of the variable.
[IndexerName("Variables")]
public string this[string name]
{
get
{
try
{
VMWareJobCallback callback = new VMWareJobCallback();
using (VMWareJob job = new VMWareJob(_handle.ReadVariable(
_variableType, name, 0, callback),
callback))
{
return job.Wait(
Constants.VIX_PROPERTY_JOB_RESULT_VM_VARIABLE_STRING,
VMWareInterop.Timeouts.ReadVariableTimeout);
}
}
catch (Exception ex)
{
throw new Exception(
string.Format("Failed to get virtual machine variable: name=\"{0}\"",
name), ex);
}
}
set
{
try
{
VMWareJobCallback callback = new VMWareJobCallback();
using (VMWareJob job = new VMWareJob(_handle.WriteVariable(
_variableType, name, value, 0, callback),
callback))
{
job.Wait(VMWareInterop.Timeouts.WriteVariableTimeout);
}
}
catch (Exception ex)
{
throw new Exception(
string.Format("Failed to set virtual machine variable: name=\"{0}\" value=\"{1}\"", name, value), ex);
}
}
}
}
///
/// A process running in the guest operating system.
///
public class Process
{
///
/// Process ID.
///
public long Id;
///
/// Process name.
///
public string Name;
///
/// Process owner.
///
public string Owner;
///
/// Process start date/time.
///
public DateTime StartDateTime;
///
/// Process command line.
///
public string Command;
///
/// True if process is being debugged.
///
public bool IsBeingDebugged = false;
///
/// Process exit code for finished processes.
///
public int ExitCode = 0;
private IVM2 _vm;
///
/// A process running in the guest operating system on a virtual machine.
///
/// Virtual machine.
public Process(IVM2 vm)
{
_vm = vm;
}
///
/// Kill a process in the guest operating system.
///
public void KillProcessInGuest()
{
KillProcessInGuest(VMWareInterop.Timeouts.KillProcessTimeout);
}
///
/// Kill a process in the guest operating system.
///
/// Timeout in seconds.
public void KillProcessInGuest(int timeoutInSeconds)
{
try
{
VMWareJobCallback callback = new VMWareJobCallback();
using (VMWareJob job = new VMWareJob(_vm.KillProcessInGuest(
Convert.ToUInt64(Id), 0, callback),
callback))
{
job.Wait(timeoutInSeconds);
}
}
catch (Exception ex)
{
throw new Exception(
string.Format("Failed to kill process in guest: processId={0}",
Id), ex);
}
}
}
private VariableIndexer _guestEnvironmentVariables = null;
private VariableIndexer _runtimeConfigVariables = null;
private VariableIndexer _guestVariables = null;
private VMWareRootSnapshotCollection _snapshots = null;
private VMWareSharedFolderCollection _sharedFolders = null;
///
/// A VMWare Virtual Machine.
///
/// A handle to a virtual machine.
public VMWareVirtualMachine(IVM2 vm)
: base(vm)
{
_guestEnvironmentVariables = new VariableIndexer(_handle, Constants.VIX_GUEST_ENVIRONMENT_VARIABLE);
_runtimeConfigVariables = new VariableIndexer(_handle, Constants.VIX_VM_CONFIG_RUNTIME_ONLY);
_guestVariables = new VariableIndexer(_handle, Constants.VIX_VM_GUEST_VARIABLE);
_sharedFolders = new VMWareSharedFolderCollection(_handle);
_snapshots = new VMWareRootSnapshotCollection(_handle);
}
///
/// The path to the virtual machine configuration file.
///
public string PathName
{
get
{
return GetProperty(Constants.VIX_PROPERTY_VM_VMX_PATHNAME);
}
}
///
/// Returns true if the virtual machine is running.
///
public bool IsRunning
{
get
{
return GetProperty(Constants.VIX_PROPERTY_VM_IS_RUNNING);
}
}
///
/// Returns virtual machine powerstate, an OR-ed set of VIX_POWERSTATE_* values.
///
public int PowerState
{
get
{
return GetProperty(Constants.VIX_PROPERTY_VM_POWER_STATE);
}
}
///
/// Returns true if the virtual machine is paused.
///
public bool IsPaused
{
get
{
return (PowerState & Constants.VIX_POWERSTATE_PAUSED) > 0;
}
}
///
/// Returns true if the virtual machine is suspended.
///
public bool IsSuspended
{
get
{
return (PowerState & Constants.VIX_POWERSTATE_SUSPENDED) > 0;
}
}
///
/// The memory size of the virtual machine.
///
public int MemorySize
{
get
{
return GetProperty(Constants.VIX_PROPERTY_VM_MEMORY_SIZE);
}
}
///
/// The number of virtual CPUs configured for the virtual machine.
///
public int CPUCount
{
get
{
return GetProperty(Constants.VIX_PROPERTY_VM_NUM_VCPUS);
}
}
///
/// Power on a virtual machine.
///
public void PowerOn()
{
PowerOn(VMWareInterop.Timeouts.PowerOnTimeout);
}
///
/// Power on a virtual machine.
///
/// Timeout in seconds.
public void PowerOn(int timeoutInSeconds)
{
PowerOn(Constants.VIX_VMPOWEROP_NORMAL | Constants.VIX_VMPOWEROP_LAUNCH_GUI,
timeoutInSeconds);
}
///
/// Power on a virtual machine.
///
/// Additional power options.
/// Timeout in seconds.
public void PowerOn(int powerOnOptions, int timeoutInSeconds)
{
try
{
VMWareJobCallback callback = new VMWareJobCallback();
using (VMWareJob job = new VMWareJob(_handle.PowerOn(
powerOnOptions, null, callback), callback))
{
job.Wait(timeoutInSeconds);
}
}
catch (Exception ex)
{
throw new Exception(
string.Format("Failed to power on virtual machine: powerOnOptions={0} timeoutInSeconds={1}",
powerOnOptions, timeoutInSeconds), ex);
}
}
///
/// This function returns when VMware Tools has successfully started in the guest operating system.
/// VMware Tools is a collection of services that run in the guest.
///
public void WaitForToolsInGuest()
{
WaitForToolsInGuest(VMWareInterop.Timeouts.WaitForToolsTimeout);
}
///
/// This function returns when VMware Tools has successfully started in the guest operating system.
/// VMware Tools is a collection of services that run in the guest.
///
/// Timeout in seconds.
public void WaitForToolsInGuest(int timeoutInSeconds)
{
try
{
// wait till the machine boots or times out with an error
VMWareJobCallback callback = new VMWareJobCallback();
using (VMWareJob job = new VMWareJob(
_handle.WaitForToolsInGuest(timeoutInSeconds, callback), callback))
{
job.Wait(timeoutInSeconds);
}
}
catch (Exception ex)
{
throw new Exception(
string.Format("Failed to wait for tools in guest: timeoutInSeconds={0}",
timeoutInSeconds), ex);
}
}
///
/// Get all snapshots.
///
/// A list of snapshots.
public VMWareRootSnapshotCollection Snapshots
{
get
{
return _snapshots;
}
}
///
/// This function establishes a guest operating system authentication context.
///
/// The name of a user account on the guest operating system.
/// The password of the account identified by userName.
public void LoginInGuest(string username, string password)
{
LoginInGuest(username, password, VMWareInterop.Timeouts.LoginTimeout);
}
///
/// This function establishes a guest operating system authentication context.
///
/// The name of a user account on the guest operating system.
/// The password of the account identified by userName.
/// Timeout in seconds.
public void LoginInGuest(string username, string password, int timeoutInSeconds)
{
LoginInGuest(username, password, 0, timeoutInSeconds);
}
///
/// This function establishes a guest operating system authentication context.
///
/// The name of a user account on the guest operating system.
/// The password of the account identified by userName.
///
/// Must be 0 or VixCOM.Constants.VIX_LOGIN_IN_GUEST_REQUIRE_INTERACTIVE_ENVIRONMENT, which forces interactive
/// guest login within a graphical session that is visible to the user. On Linux, interactive environment
/// requires that the X11 window system be running to start the vmware-user process. Without X11, pass 0 as
/// options to start the vmware-guestd process instead.
///
/// Timeout in seconds.
///
/// Logins are supported on Linux and Windows. To log in as a Windows Domain user, specify the "userName" parameter in
/// the form "domain\username". Other guest operating systems are not supported for login, including Solaris, FreeBSD,
/// and Netware.
///
public void LoginInGuest(string username, string password, int options, int timeoutInSeconds)
{
try
{
VMWareJobCallback callback = new VMWareJobCallback();
using (VMWareJob job = new VMWareJob(_handle.LoginInGuest(
username, password, options, callback),
callback))
{
job.Wait(timeoutInSeconds);
}
}
catch (Exception ex)
{
throw new Exception(
string.Format("Failed to login in guest: username=\"{0}\" options={1} timeoutInSeconds={2}",
username, options, timeoutInSeconds), ex);
}
}
///
/// This function waits for the vmwareuser process to exist in the guest.
///
/// The name of a user account on the guest operating system.
/// The password of the account identified by userName.
/// Timeout in seconds.
public void WaitForVMWareUserProcessInGuest(string username, string password, int timeoutInSeconds)
{
//http://communities.vmware.com/message/1154264
bool loggedIn = false;
try
{
LoginInGuest(username, password, timeoutInSeconds);
loggedIn = true;
DateTime dtStart = DateTime.Now;
while (true)
{
VMWareProcessCollection guestProcesses = this.GuestProcesses;
Process vmwareUserExeProcess = guestProcesses.FindProcess("vmwareuser.exe", StringComparison.OrdinalIgnoreCase);
if (vmwareUserExeProcess != null)
{
break;
}
vmwareUserExeProcess = guestProcesses.FindProcess("vmware-user", StringComparison.OrdinalIgnoreCase);
if (vmwareUserExeProcess != null)
{
break;
}
TimeSpan ts = DateTime.Now.Subtract(dtStart);
if (ts.TotalSeconds >= timeoutInSeconds)
{
throw new VMWareException(Constants.VIX_E_TIMEOUT_WAITING_FOR_TOOLS, "vmwareuser");
}
}
}
finally
{
if (loggedIn)
{
try
{
LogoutFromGuest(timeoutInSeconds);
}
catch
{
//ignore this exception so that it does not swallow any previous exceptions
}
}
}
}
///
/// This function waits for the vmwareuser process to exist in the guest.
///
/// The name of a user account on the guest operating system.
/// The password of the account identified by userName.
public void WaitForVMWareUserProcessInGuest(string username, string password)
{
WaitForVMWareUserProcessInGuest(username, password, VMWareInterop.Timeouts.WaitForToolsTimeout);
}
///
/// Copies a file or directory from the local system (where the Vix client is running) to the guest operating system.
///
/// File location on the host operating system.
/// File location on the guest operating system.
public void CopyFileFromHostToGuest(string hostPathName, string guestPathName)
{
CopyFileFromHostToGuest(hostPathName, guestPathName, VMWareInterop.Timeouts.CopyFileTimeout);
}
///
/// Copies a file or directory from the local system (where the Vix client is running) to the guest operating system.
/// You must call LoginInGuest() before calling this procedure.
/// Only absolute paths should be used for files in the guest; the resolution of relative paths is not specified.
///
/// File location on the host operating system.
/// File location on the guest operating system.
/// Timeout in seconds.
public void CopyFileFromHostToGuest(string hostPathName, string guestPathName, int timeoutInSeconds)
{
try
{
VMWareJobCallback callback = new VMWareJobCallback();
using (VMWareJob job = new VMWareJob(_handle.CopyFileFromHostToGuest(
hostPathName, guestPathName, 0, null, callback), callback))
{
job.Wait(timeoutInSeconds);
}
}
catch (Exception ex)
{
throw new Exception(
string.Format("Failed to copy file from host to guest: hostPathName=\"{0}\" guestPathName=\"{1}\" timeoutInSeconds={2}",
hostPathName, guestPathName, timeoutInSeconds), ex);
}
}
///
/// Deletes a file from guest file system.
///
/// File location on the guest operating system.
public void DeleteFileFromGuest(string guestPathName)
{
DeleteFileFromGuest(guestPathName, VMWareInterop.Timeouts.DeleteFileTimeout);
}
///
/// Deletes a file from guest file system.
///
/// File location on the guest operating system.
/// Timeout in seconds.
public void DeleteFileFromGuest(string guestPathName, int timeoutInSeconds)
{
try
{
VMWareJobCallback callback = new VMWareJobCallback();
using (VMWareJob job = new VMWareJob(_handle.DeleteFileInGuest(
guestPathName, callback),
callback))
{
job.Wait(timeoutInSeconds);
}
}
catch (Exception ex)
{
throw new Exception(
string.Format("Failed to delete file from guest: guestPathName=\"{0}\" timeoutInSeconds={1}",
guestPathName, timeoutInSeconds), ex);
}
}
///
/// Deletes a directory from guest directory system.
///
/// Directory location on the guest operating system.
public void DeleteDirectoryFromGuest(string guestPathName)
{
DeleteDirectoryFromGuest(guestPathName, VMWareInterop.Timeouts.DeleteDirectoryTimeout);
}
///
/// Deletes a directory from guest directory system.
///
/// Directory location on the guest operating system.
/// Timeout in seconds.
public void DeleteDirectoryFromGuest(string guestPathName, int timeoutInSeconds)
{
try
{
VMWareJobCallback callback = new VMWareJobCallback();
using (VMWareJob job = new VMWareJob(_handle.DeleteDirectoryInGuest(
guestPathName, 0, callback),
callback))
{
job.Wait(timeoutInSeconds);
}
}
catch (Exception ex)
{
throw new Exception(
string.Format("Failed to delete directory from guest: guestPathName=\"{0}\" timeoutInSeconds={1}",
guestPathName, timeoutInSeconds), ex);
}
}
///
/// Copies a file or directory from the guest operating system to the local system (where the Vix client is running).
///
/// File location on the guest operating system.
/// File location on the host operating system.
public void CopyFileFromGuestToHost(string guestPathName, string hostPathName)
{
CopyFileFromGuestToHost(guestPathName, hostPathName, VMWareInterop.Timeouts.CopyFileTimeout);
}
///
/// Copies a file or directory from the guest operating system to the local system (where the Vix client is running).
/// You must call LoginInGuest() before calling this procedure.
/// Only absolute paths should be used for files in the guest; the resolution of relative paths is not specified.
///
/// File location on the guest operating system.
/// File location on the host operating system.
/// Timeout in seconds.
public void CopyFileFromGuestToHost(string guestPathName, string hostPathName, int timeoutInSeconds)
{
try
{
VMWareJobCallback callback = new VMWareJobCallback();
using (VMWareJob job = new VMWareJob(_handle.CopyFileFromGuestToHost(
guestPathName, hostPathName, 0, null, callback),
callback))
{
job.Wait(timeoutInSeconds);
}
}
catch (Exception ex)
{
throw new Exception(
string.Format("Failed to copy file from guest to host: guestPathName=\"{0}\" hostPathName=\"{1}\" timeoutInSeconds={2}",
guestPathName, hostPathName, timeoutInSeconds), ex);
}
}
///
/// Creates a directory on the guest operating system.
///
/// Directory location on the guest operating system.
public void CreateDirectoryInGuest(string guestPathName)
{
CreateDirectoryInGuest(guestPathName, VMWareInterop.Timeouts.CreateDirectoryTimeout);
}
///
/// Creates a directory on the guest operating system.
///
/// Directory location on the guest operating system.
/// Timeout in seconds.
public void CreateDirectoryInGuest(string guestPathName, int timeoutInSeconds)
{
try
{
VMWareJobCallback callback = new VMWareJobCallback();
using (VMWareJob job = new VMWareJob(_handle.CreateDirectoryInGuest(
guestPathName, null, callback),
callback))
{
job.Wait(timeoutInSeconds);
}
}
catch (Exception ex)
{
throw new Exception(
string.Format("Failed to create directory in guest: guestPathName=\"{0}\" timeoutInSeconds={1}",
guestPathName, timeoutInSeconds), ex);
}
}
///
/// Creates a temp file on the guest operating system.
///
/// Name of the temporary file created.
public string CreateTempFileInGuest()
{
return CreateTempFileInGuest(VMWareInterop.Timeouts.CreateTempFileTimeout);
}
///
/// Creates a temp file on the guest operating system.
///
/// Timeout in seconds.
/// Name of the temporary file created.
public string CreateTempFileInGuest(int timeoutInSeconds)
{
try
{
VMWareJobCallback callback = new VMWareJobCallback();
using (VMWareJob job = new VMWareJob(_handle.CreateTempFileInGuest(
0, null, callback),
callback))
{
return job.Wait(Constants.VIX_PROPERTY_JOB_RESULT_ITEM_NAME, timeoutInSeconds);
}
}
catch (Exception ex)
{
throw new Exception(
string.Format("Failed to create temp file in guest: timeoutInSeconds={0}",
timeoutInSeconds), ex);
}
}
///
/// Return information about a file or directory in the guest operating system.
///
/// File or path in the guest operating system.
/// Guest file information.
public GuestFileInfo GetFileInfoInGuest(string guestPathName)
{
return GetFileInfoInGuest(guestPathName, VMWareInterop.Timeouts.GetFileInfoTimeout);
}
///
/// Return information about a file or directory in the guest operating system.
///
/// File or path in the guest operating system.
/// Timeout in seconds.
/// Guest file information.
public GuestFileInfo GetFileInfoInGuest(string guestPathName, int timeoutInSeconds)
{
try
{
VMWareJobCallback callback = new VMWareJobCallback();
using (VMWareJob job = new VMWareJob(_handle.GetFileInfoInGuest(guestPathName, callback), callback))
{
object[] properties =
{
Constants.VIX_PROPERTY_JOB_RESULT_FILE_SIZE,
Constants.VIX_PROPERTY_JOB_RESULT_FILE_FLAGS,
Constants.VIX_PROPERTY_JOB_RESULT_FILE_MOD_TIME
};
object[] propertyValues = job.Wait