using System;
using System.Collections.Generic;
using Interop.VixCOM;
using Microsoft.Win32;
namespace Vestris.VMWareLib
{
///
/// A VMWare virtual host.
///
public class VMWareVirtualHost : VMWareVixHandle
{
///
/// VMWare service provider type.
///
public enum ServiceProviderType
{
///
/// No service provider type, not connected.
///
None = 0,
///
/// VMWare Server.
///
Server = Constants.VIX_SERVICEPROVIDER_VMWARE_SERVER,
///
/// VMWare Workstation.
///
Workstation = Constants.VIX_SERVICEPROVIDER_VMWARE_WORKSTATION,
///
/// Virtual Infrastructure Server, eg. ESX.
///
VirtualInfrastructureServer = Constants.VIX_SERVICEPROVIDER_VMWARE_VI_SERVER,
///
/// VMWare Player.
///
Player = Constants.VIX_SERVICEPROVIDER_VMWARE_PLAYER
}
private ServiceProviderType _serviceProviderType = ServiceProviderType.None;
///
/// An IHost2 handle, where supported.
///
protected IHost2 _host2
{
get
{
return _handle as IHost2;
}
}
///
/// A VMWare virtual host.
///
public VMWareVirtualHost()
{
}
///
/// Connected host type.
///
public ServiceProviderType ConnectionType
{
get
{
return _serviceProviderType;
}
}
///
/// Connect to a WMWare Player.
///
///
///
/// using System;
/// using System.Collections.Generic;
/// using Vestris.VMWareLib;
///
/// VMWareVirtualHost virtualHost = new VMWareVirtualHost();
/// virtualHost.ConnectToVMWarePlayer();
/// VMWareVirtualMachine virtualMachine = virtualHost.Open("C:\Virtual Machines\xp\xp.vmx");
/// virtualMachine.PowerOn();
///
///
public void ConnectToVMWarePlayer()
{
ConnectToVMWarePlayer(VMWareInterop.Timeouts.ConnectTimeout);
}
///
/// Connect to a WMWare Player.
///
/// Timeout in seconds.
public void ConnectToVMWarePlayer(int timeoutInSeconds)
{
Connect(ServiceProviderType.Player, null, 0, null, null, timeoutInSeconds);
}
///
/// Connect to a WMWare Workstation.
///
///
///
/// using System;
/// using System.Collections.Generic;
/// using Vestris.VMWareLib;
///
/// VMWareVirtualHost virtualHost = new VMWareVirtualHost();
/// virtualHost.ConnectToVMWareWorkstation();
/// VMWareVirtualMachine virtualMachine = virtualHost.Open("C:\Virtual Machines\xp\xp.vmx");
/// virtualMachine.PowerOn();
///
///
public void ConnectToVMWareWorkstation()
{
ConnectToVMWareWorkstation(VMWareInterop.Timeouts.ConnectTimeout);
}
///
/// Connect to a WMWare Workstation.
///
/// Timeout in seconds.
public void ConnectToVMWareWorkstation(int timeoutInSeconds)
{
Connect(ServiceProviderType.Workstation, null, 0, null, null, timeoutInSeconds);
}
///
/// Connect to a WMWare Virtual Infrastructure Server (eg. ESX or VMWare Server 2.x).
///
/// VMWare host name and optional port.
/// Username.
/// Password.
///
///
/// using System;
/// using System.Collections.Generic;
/// using Vestris.VMWareLib;
///
/// VMWareVirtualHost virtualHost = new VMWareVirtualHost();
/// virtualHost.ConnectToVMWareVIServer("esx.mycompany.com", "vmuser", "password");
/// VMWareVirtualMachine virtualMachine = virtualHost.Open("[storage] testvm/testvm.vmx");
/// virtualMachine.PowerOn();
///
///
///
///
/// using System;
/// using System.Collections.Generic;
/// using Vestris.VMWareLib;
///
/// VMWareVirtualHost virtualHost = new VMWareVirtualHost();
/// virtualHost.ConnectToVMWareVIServer("localhost:8333", "vmuser", "password");
/// VMWareVirtualMachine virtualMachine = virtualHost.Open("[standard] testvm/testvm.vmx");
/// virtualMachine.PowerOn();
///
///
public void ConnectToVMWareVIServer(string hostName, string username, string password)
{
ConnectToVMWareVIServer(hostName, username, password, VMWareInterop.Timeouts.ConnectTimeout);
}
///
/// Connect to a WMWare Virtual Infrastructure Server (eg. ESX or VMWare Server 2.x).
///
/// VMWare host name and optional port.
/// Username.
/// Password.
/// Timeout in seconds.
///
///
/// using System;
/// using System.Collections.Generic;
/// using Vestris.VMWareLib;
///
/// VMWareVirtualHost virtualHost = new VMWareVirtualHost();
/// virtualHost.ConnectToVMWareVIServer("esx.mycompany.com", "vmuser", "password");
/// VMWareVirtualMachine virtualMachine = virtualHost.Open("[storage] testvm/testvm.vmx");
/// virtualMachine.PowerOn();
///
///
///
///
/// using System;
/// using System.Collections.Generic;
/// using Vestris.VMWareLib;
///
/// VMWareVirtualHost virtualHost = new VMWareVirtualHost();
/// virtualHost.ConnectToVMWareVIServer("localhost:8333", "vmuser", "password");
/// VMWareVirtualMachine virtualMachine = virtualHost.Open("[standard] testvm/testvm.vmx");
/// virtualMachine.PowerOn();
///
///
public void ConnectToVMWareVIServer(string hostName, string username, string password, int timeoutInSeconds)
{
if (string.IsNullOrEmpty(hostName))
{
throw new ArgumentException("The host is required.");
}
ConnectToVMWareVIServer(new Uri(string.Format("https://{0}/sdk", hostName)),
username, password, timeoutInSeconds);
}
///
/// Connect to a WMWare Virtual Infrastructure Server (eg. ESX).
///
/// Host SDK uri, eg. http://server/sdk.
/// Username.
/// Password.
/// Timeout in seconds.
public void ConnectToVMWareVIServer(Uri hostUri, string username, string password, int timeoutInSeconds)
{
if (string.IsNullOrEmpty(username))
{
throw new ArgumentException("The username is required.");
}
Connect(ServiceProviderType.VirtualInfrastructureServer,
hostUri.ToString(), 0, username, password, timeoutInSeconds);
}
///
/// Connect to a WMWare Server.
///
/// Username.
/// Password.
/// DNS name or IP address of a VMWare host, leave blank for localhost.
public void ConnectToVMWareServer(string hostName, string username, string password)
{
ConnectToVMWareServer(hostName, username, password, VMWareInterop.Timeouts.ConnectTimeout);
}
///
/// Connect to a WMWare Server.
///
/// DNS name or IP address of a VMWare host, leave blank for localhost.
/// Username.
/// Password.
/// Timeout in seconds.
public void ConnectToVMWareServer(string hostName, string username, string password, int timeoutInSeconds)
{
Connect(ServiceProviderType.Server,
hostName, 0, username, password, timeoutInSeconds);
}
///
/// Connects to a VMWare VI Server, VMWare Server or Workstation.
///
private void Connect(ServiceProviderType serviceProviderType,
string hostName, int hostPort, string username, string password, int timeout)
{
try
{
// check if VmWare COM object could be loaded
// if we try to load a COM object which does not exist, an RCW exception will occure on exit of Visual Studio 2013
using (RegistryKey baseKey = RegistryKey.OpenBaseKey(RegistryHive.ClassesRoot, RegistryView.Registry32)) {
using (var xReg = baseKey.OpenSubKey(@"CLSID\{6874E949-7186-4308-A1B9-D55A91F60728}", false)) {
if (xReg == null) {
throw new ApplicationException("No Vmware Library installed!");
}
}
}
int serviceProvider = (int)serviceProviderType;
VMWareJobCallback callback = new VMWareJobCallback();
using (VMWareJob job = new VMWareJob(new VixLib().Connect(
Constants.VIX_API_VERSION, serviceProvider, hostName, hostPort,
username, password, 0, null, callback), callback))
{
_handle = job.Wait(Constants.VIX_PROPERTY_JOB_RESULT_HANDLE, timeout);
}
_serviceProviderType = serviceProviderType;
}
catch (ApplicationException)
{
throw;
}
catch (Exception ex)
{
throw new Exception(
string.Format("Failed to connect: serviceProviderType=\"{0}\" hostName=\"{1}\" hostPort={2} username=\"{3}\" timeout={4}",
Enum.GetName(serviceProviderType.GetType(), serviceProviderType), hostName, hostPort, username, timeout), ex);
}
}
///
/// Open a virtual machine.
///
/// Virtual Machine file, local .vmx or [storage] .vmx.
/// An instance of a virtual machine.
public VMWareVirtualMachine Open(string fileName)
{
return Open(fileName, VMWareInterop.Timeouts.OpenVMTimeout);
}
///
/// Open a virtual machine.
///
/// Virtual Machine file, local .vmx or [storage] .vmx.
/// Timeout in seconds.
/// An instance of a virtual machine.
public VMWareVirtualMachine Open(string fileName, int timeoutInSeconds)
{
try
{
if (_handle == null)
{
throw new InvalidOperationException("No connection established");
}
VMWareJobCallback callback = new VMWareJobCallback();
using (VMWareJob job = new VMWareJob(_handle.OpenVM(fileName, callback), callback))
{
return new VMWareVirtualMachine(job.Wait(
Constants.VIX_PROPERTY_JOB_RESULT_HANDLE,
timeoutInSeconds));
}
}
catch (Exception ex)
{
throw new Exception(
string.Format("Failed to open virtual machine: fileName=\"{0}\" timeoutInSeconds={1}",
fileName, timeoutInSeconds), ex);
}
}
///
/// Add a virtual machine to the host's inventory.
///
/// Virtual Machine file, local .vmx or [storage] .vmx.
public void Register(string fileName)
{
Register(fileName, VMWareInterop.Timeouts.RegisterVMTimeout);
}
///
/// Add a virtual machine to the host's inventory.
///
/// Virtual Machine file, local .vmx or [storage] .vmx.
/// Timeout in seconds.
public void Register(string fileName, int timeoutInSeconds)
{
if (_handle == null)
{
throw new InvalidOperationException("No connection established");
}
switch (ConnectionType)
{
case ServiceProviderType.VirtualInfrastructureServer:
case ServiceProviderType.Server:
break;
default:
throw new NotSupportedException(string.Format("Register is not supported on {0}",
ConnectionType));
}
try
{
VMWareJobCallback callback = new VMWareJobCallback();
using (VMWareJob job = new VMWareJob(_handle.RegisterVM(fileName, callback), callback))
{
job.Wait(timeoutInSeconds);
}
}
catch (Exception ex)
{
throw new Exception(
string.Format("Failed to register virtual machine: fileName=\"{0}\" timeoutInSeconds={1}",
fileName, timeoutInSeconds), ex);
}
}
///
/// Remove a virtual machine from the host's inventory.
///
/// Virtual Machine file, local .vmx or [storage] .vmx.
public void Unregister(string fileName)
{
Unregister(fileName, VMWareInterop.Timeouts.RegisterVMTimeout);
}
///
/// Remove a virtual machine from the host's inventory.
///
/// Virtual Machine file, local .vmx or [storage] .vmx.
/// Timeout in seconds.
public void Unregister(string fileName, int timeoutInSeconds)
{
if (_handle == null)
{
throw new InvalidOperationException("No connection established");
}
switch (ConnectionType)
{
case ServiceProviderType.VirtualInfrastructureServer:
case ServiceProviderType.Server:
break;
default:
throw new NotSupportedException(string.Format("Unregister is not supported on {0}",
ConnectionType));
}
try
{
VMWareJobCallback callback = new VMWareJobCallback();
using (VMWareJob job = new VMWareJob(_handle.UnregisterVM(fileName, callback), callback))
{
job.Wait(timeoutInSeconds);
}
}
catch (Exception ex)
{
throw new Exception(
string.Format("Failed to unregister virtual machine: fileName=\"{0}\" timeoutInSeconds={1}",
fileName, timeoutInSeconds), ex);
}
}
///
/// Dispose the object, hard-disconnect from the remote host.
///
public override void Dispose()
{
if (_handle != null)
{
Disconnect();
}
GC.SuppressFinalize(this);
}
///
/// Disconnect from a remote host.
///
public void Disconnect()
{
if (_handle == null)
{
throw new InvalidOperationException("No connection established");
}
_handle.Disconnect();
_handle = null;
_serviceProviderType = ServiceProviderType.None;
}
///
/// Returns true when connected to a virtual host, false otherwise.
///
public bool IsConnected
{
get
{
return _handle != null;
}
}
///
/// Destructor.
///
~VMWareVirtualHost()
{
if (_handle != null)
{
Disconnect();
}
}
///
/// Returns all running virtual machines.
///
public IEnumerable RunningVirtualMachines
{
get
{
if (_handle == null)
{
throw new InvalidOperationException("No connection established");
}
try
{
List runningVirtualMachines = new List();
VMWareJobCallback callback = new VMWareJobCallback();
using (VMWareJob job = new VMWareJob(_handle.FindItems(
Constants.VIX_FIND_RUNNING_VMS, null, -1, callback),
callback))
{
object[] properties = { Constants.VIX_PROPERTY_FOUND_ITEM_LOCATION };
foreach (object[] runningVirtualMachine in job.YieldWait(
properties, VMWareInterop.Timeouts.FindItemsTimeout))
{
runningVirtualMachines.Add(this.Open((string)runningVirtualMachine[0]));
}
}
return runningVirtualMachines;
}
catch (Exception ex)
{
throw new Exception("Failed to get all running virtual machines", ex);
}
}
}
///
/// All registered virtual machines.
///
/// This function is only supported on Virtual Infrastructure servers.
public IEnumerable RegisteredVirtualMachines
{
get
{
switch (ConnectionType)
{
case ServiceProviderType.VirtualInfrastructureServer:
case ServiceProviderType.Server:
break;
default:
throw new NotSupportedException(string.Format("RegisteredVirtualMachines is not supported on {0}",
ConnectionType));
}
try
{
List registeredVirtualMachines = new List();
VMWareJobCallback callback = new VMWareJobCallback();
using (VMWareJob job = new VMWareJob(_handle.FindItems(
Constants.VIX_FIND_REGISTERED_VMS, null, -1, callback),
callback))
{
object[] properties = { Constants.VIX_PROPERTY_FOUND_ITEM_LOCATION };
foreach (object[] runningVirtualMachine in job.YieldWait(properties, VMWareInterop.Timeouts.FindItemsTimeout))
{
registeredVirtualMachines.Add(this.Open((string)runningVirtualMachine[0]));
}
}
return registeredVirtualMachines;
}
catch (Exception ex)
{
throw new Exception("Failed to get all registered virtual machines", ex);
}
}
}
}
}