First, I have extensively read through Autoconnect to MS Wireless display on Windows 10 and tried basically every solution. (I did technically get the AutoHotKey solution working, and in fact did that before even researching. But, I feel like that's kind of unprofessional and surely there is some API that can connect to this thing.) After going through all of this, I just started reading through the different namespaces. Finally, I found Windows.Devices.WiFiDirect. This gave me the most progress I've been able to get, which is, it begins to connect and says so on screen, then an exception stating that the device is unreachable occurs. Very infuriating.
Can anyone explain exactly what is happening here? It seems like this should be the proper way to connect my screen to this device, but it is just not working. Code below, it's pretty short and straightforward.
Edit:
Based on Roy Li's suggestion, I attempted to use a different overload of the socket.ConnectAsync method. This actually did have an effect but I am still receiving an exception, although a different one. The method now attempts to connect for longer but still fails out, this time with a "connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond" exception. Could this mean there is some sort of secret handshake that Window's OS is using when connecting to this device? If so, this might be a dead end. The code has been updated below.
static async Task Main()
{
string id = null;
string prefix = "MicrosoftDisplayAdapter";
WiFiDirectDevice device;
StreamSocket socket = new StreamSocket();
try
{
DeviceInformationCollection devInfoCollection = await DeviceInformation.FindAllAsync(WiFiDirectDevice.GetDeviceSelector());
foreach (DeviceInformation devInfo in devInfoCollection)
{
if (devInfo.Name.StartsWith(prefix))
{
id = devInfo.Id;
}
}
device = await WiFiDirectDevice.FromIdAsync(id);
var endpointPairCollection = device.GetConnectionEndpointPairs();
await socket.ConnectAsync(endpointPairCollection[0].RemoteHostName, "50001"); //This line begins connecting to the display but ultimately fails
}
catch (Exception e)
{
//device unreachable exception
}
}
I finally found something along the lines of what I need. I came across https://social.msdn.microsoft.com/Forums/en-US/7608d127-d864-436a-802e-472fd55cc02c/use-projectionmanager-from-net-framework?forum=csharpgeneral, which gave me a way to cast/project to the Microsoft Display Adapter. As the link states, I do get a "Catastrophic Error" but it does make the connection and keep it, anyway. What my code ended up looking like is below:
static async Task Main()
{
string prefix = "MicrosoftDisplayAdapter";
DeviceInformation displayAdapter = null;
try
{
//Get projection devices
DeviceInformationCollection devices = await DeviceInformation.FindAllAsync(ProjectionManager.GetDeviceSelector());
foreach (DeviceInformation device in devices)
{
if (device.Name.StartsWith(prefix))
{
displayAdapter = device;
}
}
//Start projection. This throws an error but works without issue.
await ProjectionManager.StartProjectingAsync(0, 0, displayAdapter);
}
catch (Exception e)
{
//Ignore this error
if (e.Message.StartsWith("Catastrophic"))
{
//Change display to use secondary only
Process proc = new Process();
proc.StartInfo.UseShellExecute = true;
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.FileName = @"C:\Windows\Sysnative\DisplaySwitch.exe";
proc.StartInfo.Arguments = "/external";
proc.Start();
proc.WaitForExit();
}
else
{
Console.WriteLine(e);
}
}
}