VMWare API disconnect USB-Passthrough - c#

I am using VMWare Workstation (v11) to run a Virtual Machine for testing.
Now I'd like to pragmatically add and remove USB-devices attached to the system.
using VMware.Vim; I can connect to the server and query it. I can also remove devices like CD-Drives and other things. But I can't disconnect any USB-Passthrough-Device. I either get : "Invalid Config" or "Unknown Error" (most likely due to the lib being interopt and not transporting all information)
My current code:
using VMware.Vim;
var dongle = devs.SingleOrDefault(i => i.DeviceInfo.Summary.Contains("Silicon"));
if (dongle != null) {
var usbDongle = (dongle as VirtualUSB);
usbDongle.Connected = false;
var spec = new VirtualMachineConfigSpec() {
DeviceChange = new[] {
new VirtualDeviceConfigSpec() {
Device = dongle,
Operation = VirtualDeviceConfigSpecOperation.remove,
}
}
};
vm.ReconfigVM(spec);
Neither Operation = "remove" or "edit" has any effect. I'm always getting some kind of error...
I appreciate any ideas!
Regards,
Corelgott

Related

Establish connection to wifi using ManagedNativeWifi package

Nice framework... but I am trying to establish a connection to an available network. I have connected manually, and made a snapshot of the XML. Then removed the connection.
I am able to find the network,
I pass in the SSID I want to connect to (yes, it is found..). I also pass the profileSecurity to use... but not really sure what to put there. From my XML I tried bot AES as well as WPA2PSK. But, SetProfile always returns false. And not sure how to extract an error message about what went wrong. That would be nice.
As the profile fails, the ConnectNetwork also fails, but that would be expected I think.
Any pointer would be nice. And a bit more documentation on these points would make the tool a lot better.
// get the network to connect to
var availableNetwork = NativeWifi.EnumerateAvailableNetworks()
.FirstOrDefault(x => x.Ssid.ToString() == ssid);
if (availableNetwork is null)
return;
var profile = NativeWifi.EnumerateProfiles().FirstOrDefault(x => x.Name == ssid);
if (profile is null)
{
// build XML
string profileName = ssid;
string mac = StringToHex(profileName);
string profileXml = string.Format("<?xml version=\"1.0\"?><WLANProfile xmlns = \"http://www.microsoft.com/networking/WLAN/profile/v1\"><name>{0}</name><SSIDConfig><SSID><hex>{1}</hex><name>{0}</name></SSID></SSIDConfig><connectionType>ESS</connectionType><connectionMode>auto</connectionMode><MSM><security><authEncryption><authentication>WPA2PSK</authentication><encryption>AES</encryption><useOneX>false</useOneX></authEncryption><sharedKey><keyType>passPhrase</keyType><protected>true</protected><keyMaterial>... key removed for security...</keyMaterial></sharedKey></security></MSM><MacRandomization xmlns=\"http://www.microsoft.com/networking/WLAN/profile/v3\"><enableRandomization>false</enableRandomization><randomizationSeed>153878511</randomizationSeed></MacRandomization></WLANProfile>", ssid, mac);
// create a profile
var profileResult = NativeWifi.SetProfile(availableNetwork.Interface.Id, ProfileType.AllUser, profileXml, encryption, true);
}
else
{
//todo: log here
}
var wasConnected = NativeWifi.ConnectNetwork(availableNetwork.Interface.Id, ssid, availableNetwork.BssType);

Reflection in gRPC \ Protobuf in C#

Due to the lack of examples in C#, I can't get reflection in gRPC\Protobuf working. One application would be supplying a version of all interfaces and messages.
syntax = "proto3";
import "google/protobuf/descriptor.proto";
option csharp_namespace = "Addressbook.Services";
extend google.protobuf.FileOptions {
string version = 50000;
}
option (version) = "1.2.3.0";
service AddressBookService {
...
Is it possible that a client parses the connected server with reflection? Is the version supplied to all interfaces and messages? How to I do that in C#?
Thanks for any help...
If I understand the question correctly, you want to see if client and server are in sync with all .proto files.
Here's a solution that will have to be tweaked but otherwise will work.
This only works if server has reflection enabled - maybe not an option everywhere.
In ServiceName.Descriptor.File ServiceName refers to class generated by protoc.
using var channel = _channelFactory.GetChannel();
var client = new ServerReflection.ServerReflectionClient(channel);
using var call = client.ServerReflectionInfo();
// To get all service names on the server, you can use this:
// await call.RequestStream.WriteAsync(new ServerReflectionRequest{ ListServices = ""});
// await call.ResponseStream.MoveNext(CancellationToken.None);
// foreach (var serviceResponse in call.ResponseStream.Current.ListServicesResponse.Service)
// {
// _logger.LogInformation("Service name on server: {ServiceName}", serviceResponse.Name);
// }
await call.RequestStream.WriteAsync(new ServerReflectionRequest{FileContainingSymbol = "name.space.service_name"});
await call.ResponseStream.MoveNext(CancellationToken.None);
var descriptorResponse = call.ResponseStream.Current;
// This list has to be reversed. Check `.BuildFromByteStrings` docstring for more info.
var fileDescriptors = FileDescriptor.BuildFromByteStrings(descriptorResponse.FileDescriptorResponse.FileDescriptorProto.Reverse());
var localDescriptor = ServiceName.Descriptor.File;
var relevantFileDescriptor = fileDescriptors.Single(descriptor => descriptor.Name == localDescriptor.Name);
if (relevantFileDescriptor.SerializedData != localDescriptor.SerializedData)
{
_logger.LogWarning("Remote .proto differs from local copy. Please update.");
}
else
{
_logger.LogInformation(".proto definition matches between client and server.");
}
await call.RequestStream.CompleteAsync();

USB Printing for DOT Matrix POS printer

I was trying to print to an usb printer using usbmanager, the App can detect the printer device but when i run it doesnt print. there are no errors and all passing data is ok.
Printer : Bixolon SRP 275III
Type: USB
private async void printReciept()
{
UsbManager m_usbManager;
m_usbManager = (UsbManager)Application.Context.GetSystemService(Context.UsbService);
var deviceList = m_usbManager.DeviceList;
IEnumerable<UsbDevice> deviceIterator = deviceList.Values.AsEnumerable();
UsbDevice m_usbdevice = null;
if (deviceIterator.Count() > 0)
{
var device = deviceIterator.ElementAt(0);
m_usbdevice = device;
string ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
var mPermissionIntent = PendingIntent.GetBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
m_usbManager.RequestPermission(m_usbdevice, mPermissionIntent);
UsbDeviceConnection deviceConnection = null;
try
{
using (var usbInterface = m_usbdevice.GetInterface(0))
{
using (var usbEndpoint = usbInterface.GetEndpoint(0))
{
mEndPoint = usbEndpoint;
deviceConnection = m_usbManager.OpenDevice(m_usbdevice);
byte[] bytesHello = Encoding.UTF8.GetBytes("Hello");
deviceConnection.BulkTransfer(usbEndpoint, bytesHello, bytesHello.Length, 0);
}
}
}
catch
{
}
}
}
You are sending the string to be printed directly to the bulk endpoint, or actually you are doing bulk transfer to the first endpoint found without knowing any of it's characteristics? I think it is a bit more complex than that.
First try to find out whether your printer supports USB printing class or some proprietary implementation. You can do this easily e.g. by connecting the printer to Windows PC and looking from the device manager, usbdeview or some other similar application.
If it supports printing class, read this document and implement your driver based on that (or use the one you may already have in Android). If it only supports proprietary implementation, you need to get the specifications for it or do some reverse engineering.
You may need to learn about PCL which may also be needed.

Setting and Getting DHCP option for Windows in C#

Using C#, I'm trying to set dhcp option 12 using ManageDHCP.dll. In a nutshell, this is what I'm doing:
var dhcpManager = new DHCPManager(dhcpServerName)
var hostRecord = new HostInfo
{
Name = deviceDhcpName,
IPv4 = deviceIpAddress,
IsReserved = true,
MAC = deviceMacAddress
};
dhcpManager.SetRecord(dhcpServerScope, hostRecord);
String hostName = deviceDhcpName + "." + dnsZoneName;
var hostnameOpt = new Option
{
ID = 12,
Values = new List<string> { hostName }
};
dhcpManager.SetOption(hostnameOpt, dhcpServerScope, deviceIpAddress);
The thing is, is that it just dies at this point and the logs don't record an exception. So I was thinking maybe the format I'm sending it is not correct. So I went to try and get an option. So instead, after creating the reservation, with SetRecord function above - I called this instead, just to try an see if I could get an option to see the correct format:
Option test = dhcpManager.GetOption(3, dhcpServerScope, deviceIpAddress);
Which throws this exception:
ManageDHCP.DhcpException: DhcpGetOptionInfo
at ManageDHCP.DHCPManager._GetOption(OptionTarget target, UInt32 optionID, String subnet, String reservedIP)
I'm new to C# and I'm not really sure what's causing this exception. Here is a link to the source code for ManageDHCP. What am I doing wrong? Is my format incorrect?
It seems like the 32-bit dll's setOption function does not work (DhcpGetOptionInfo throws an exception), so I switched to 64 bit dll.

How to access WinRM in C#

I'd like to create a small application that can collect system information (Win32_blablabla) using WinRM as opposed to WMI. How can i do that from C#?
The main goal is to use WS-Man (WinRm) as opposed to DCOM (WMI).
I guess the easiest way would be to use WSMAN automation. Reference wsmauto.dll from windwos\system32 in your project:
then, code below should work for you. API description is here: msdn: WinRM C++ API
IWSMan wsman = new WSManClass();
IWSManConnectionOptions options = (IWSManConnectionOptions)wsman.CreateConnectionOptions();
if (options != null)
{
try
{
// options.UserName = ???;
// options.Password = ???;
IWSManSession session = (IWSManSession)wsman.CreateSession("http://<your_server_name>/wsman", 0, options);
if (session != null)
{
try
{
// retrieve the Win32_Service xml representation
var reply = session.Get("http://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/Win32_Service?Name=winmgmt", 0);
// parse xml and dump service name and description
var doc = new XmlDocument();
doc.LoadXml(reply);
foreach (var elementName in new string[] { "p:Caption", "p:Description" })
{
var node = doc.GetElementsByTagName(elementName)[0];
if (node != null) Console.WriteLine(node.InnerText);
}
}
finally
{
Marshal.ReleaseComObject(session);
}
}
}
finally
{
Marshal.ReleaseComObject(options);
}
}
hope this helps, regards
I've got an article that describes an easy way to run Powershell through WinRM from .NET at http://getthinktank.com/2015/06/22/naos-winrm-windows-remote-management-through-net/.
The code is in a single file if you want to just copy it and it's also a NuGet package that includes the reference to System.Management.Automation.
It auto manages trusted hosts, can run script blocks, and also send files (which isn't really supported but I created a work around). The returns are always the raw objects from Powershell.
// this is the entrypoint to interact with the system (interfaced for testing).
var machineManager = new MachineManager(
"10.0.0.1",
"Administrator",
MachineManager.ConvertStringToSecureString("xxx"),
true);
// will perform a user initiated reboot.
machineManager.Reboot();
// can run random script blocks WITH parameters.
var fileObjects = machineManager.RunScript(
"{ param($path) ls $path }",
new[] { #"C:\PathToList" });
// can transfer files to the remote server (over WinRM's protocol!).
var localFilePath = #"D:\Temp\BigFileLocal.nupkg";
var fileBytes = File.ReadAllBytes(localFilePath);
var remoteFilePath = #"D:\Temp\BigFileRemote.nupkg";
machineManager.SendFile(remoteFilePath, fileBytes);
Hope this helps, I've been using this for a while with my automated deployments. Please leave comments if you find issues.
I would like to note that this shows an interop error by default in Visual Studio 2010.
c.f. http://blogs.msdn.com/b/mshneer/archive/2009/12/07/interop-type-xxx-cannot-be-embedded-use-the-applicable-interface-instead.aspx
There appear to be two ways to solve this. This first is documented in the article listed above and appears to be the correct way to handle the problem. The pertinent changes for this example is:
WSMan wsManObject = new WSMan();
This is in lieu of IWSMan wsman = new WSManClass(); which will throw the error.
The second resolution is to go to the VS2010—>Solution Explorer—>Solution—>Project—>References and select WSManAutomation. Right click or hit Alt-Enter to access the properties. Change the value of the "Embed Interop Types" property of the wsmauto reference.

Categories