Visual Studio 2022 Release Date

Visual Studio 2022 has been available in test form for a while. I’ve got the release candidate running now. But there is now a release date available for it. If you are looking to upgrade to VS 2022, your wait will be over on November 8, 2022. On this day Microsoft is holding a launch event for Visual Studio 2022. This isn’t just a software release, but also will have demonstrations on what Visual Studio 2022 is bringing.

Visual Studio 2022 brings greater support/integration with GitHub (Microsoft agreed to purchase GitHub back in 2018), code editor, and debugging improvements. The range of new feature touch the areas of WPF, WinForms, WinUI, ASP.NET, and areas not traditionally thought of as Windows specific, such as cross-platform game technologies, developing applications for Mac, and apps for Linux.

The fun starts on November 8, 8:30AM PDT. Learn more here.

#VS2022


Twitter: @j2inet
Instagram: @j2inet
Facebook: j2inet
YouTube: j2inet

Posts may contain products with affiliate links. When you make purchases using these links, we receive a small commission at no extra cost to you. Thank you for your support.


Simple HTTP Server in .Net

.Net and .Net Core both already provide fully functional HTTPS servers, as does IIS on Windows. But I found the need to make my own HTTP server in .Net for a plugin that I was making for a game (Kerbal Space Program, specifically). For my scenario, I was trying to limit the assemblies that I needed to add to the game to as few as possible. So I decided to build my own instead of adding references to the assemblies that had the functionality that I wanted.

For the class that will be my HTTP server, there are only two member variables needed. One to hold a reference to a thread that will accept my request and another for the TcpListener on which incoming requests will come.

Thread _serverThread = null;
TcpListener _listener;

I need to be able to start and top the server at will. For now, when the server stops all that I want it to do is terminate the thread and release any network resources that it had. In the Start function, I want to create the listener and start the thread for receiving the requests. I could have the server only listen on the loopback adapter (localhost) by using the IP address 127.0.0.1 (IPV4) or :1 (IPV6). This would generally be preferred unless there is a reason for external machines to access the service. I’ll need for this to be accessible from another device. Here I will use the IP address 0.0.0.0 (IPV4) or :0 (IPV6) . I’ll be using

public void Start(int port = 8888)
{
    if (_serverThread == null)
    {
        IPAddress ipAddress = new IPAddress(0);
        _listener = new TcpListener(ipAddress, 8888);
        _serverThread = new Thread(ServerHandler);
        _serverThread.Start();
    }
}

public void Stop()
{
    if(_serverThread != null)
    {
        _serverThread.Abort();
        _serverThread = null;
    } 
}

The TcpListener has been created, but it isn’t doing anything yet. The call to have it listen for a request is a blocking request. The TcpListener will start listening on a different thread. When a request comes in, we read the request that was sent and then send a response. I’ll read the entire response and store it in a string. But I’m not doing anything with the request just yet. For the sake of getting to something that functions quickly, I’m going to hardcode a response

String ReadRequest(NetworkStream stream)
{
    MemoryStream contents = new MemoryStream();
    var buffer = new byte[2048];
    do
    {
        var size = stream.Read(buffer, 0, buffer.Length);
        if(size == 0)
        {
            return null;
        }
        contents.Write(buffer, 0, size);
    } while (stream.DataAvailable);
    var retVal = Encoding.UTF8.GetString(contents.ToArray());
    return retVal;
}

void ServerHandler(Object o)
{
    _listener.Start();
    while(true)
    {
        TcpClient client = _listener.AcceptTcpClient();
        NetworkStream stream = client.GetStream();

        try
        {
            var request = ReadRequest(stream);

            var responseBuilder = new StringBuilder();
            responseBuilder.AppendLine("HTTP/1.1 200 OK");
            responseBuilder.AppendLine("Content-Type: text/html");
            responseBuilder.AppendLine();
            responseBuilder.AppendLine("<html><head><title>Test</title></head><body>It worked!</body></html>");
            responseBuilder.AppendLine("");
            var responseString = responseBuilder.ToString();
            var responseBytes = Encoding.UTF8.GetBytes(responseString);

            stream.Write(responseBytes, 0, responseBytes.Length);

        }
        finally
        {
            stream.Close();
            client.Close();
        }
    }
}

To test the server, I made a .Net console program that instantiates the server.

namespace TestConsole
{
    class Program
    {
        static void Main(string[] args)
        {

            var x = new HTTPKServer();
            x.Start();
            Console.ReadLine();
            x.Stop();
        }
    }
}

I rant the program and opened a browser to http://localhost:8888. The web page shows the response “It worked!”. Now to make it a bit more flexible. The logic for what to do with a response will be handled elsewhere. I don’t want it to be part of the logic for the server itself. I’m adding a delegate to my server. The delegate function will receive the request string and must return the response bytes that should be sent. I’ll also need to know the Mime type. I’ve made a class for holding that information.

public class Response
{
    public byte[] Data { get; set; }
    public String MimeType { get; set; } = "text/plain";
}

public delegate Response ProcessRequestDelegate(String request);
public ProcessRequestDelegate ProcessRequest;

I’m leaving the hard coded response in place, though I am changing the message to say that no request processor has been added. Generally, the code is expecting that the caller has registered a delegate to perform request processing. If it has not, then this will server as a message to the developer.

The updated method looks like the following.

void ServerHandler(Object o)
{
    _listener.Start();
    while(true)
    {
        TcpClient client = _listener.AcceptTcpClient();
        NetworkStream stream = client.GetStream();

        try
        {
            var request = ReadRequest(stream);

            if (ProcessRequest != null)
            {
                var response = ProcessRequest(request);
                var responseBuilder = new StringBuilder();
                responseBuilder.AppendLine("HTTP/1.1 200 OK");      
                responseBuilder.AppendLine("Content-Type: application/json");
                responseBuilder.AppendLine($"Content-Length: {response.Data.Length}");
                responseBuilder.AppendLine();

                var headerBytes = Encoding.UTF8.GetBytes(responseBuilder.ToString());

                stream.Write(headerBytes, 0, headerBytes.Length);
                stream.Write(response.Data, 0, response.Data.Length);
            }
            else
            {
                var responseBuilder = new StringBuilder();
                responseBuilder.AppendLine("HTTP/1.1 200 OK");
                responseBuilder.AppendLine("Content-Type: text/html");
                responseBuilder.AppendLine();
                responseBuilder.AppendLine("<html><head><title>Test</title></head><body>No Request Processor added</body></html>");
                responseBuilder.AppendLine("");
                var responseString = responseBuilder.ToString();
                var responseBytes = Encoding.UTF8.GetBytes(responseString);

                stream.Write(responseBytes, 0, responseBytes.Length);
            }
        }
        finally
        {
            stream.Close();
            client.Close();
        }
    }
}

The test program now registers a delegate. The delegate will show the request and send a response that is derived by the time. I’m marking the response as a JSON response.

static Response ProcessMessage(String request)
{
    Console.Out.WriteLine($"Request:{request}");
    var response = new HTTPKServer.Response();
    response.MimeType = "application/json";
    var responseText = "{\"now\":" + (DateTime.Now).Ticks + "}";
    var responseData = Encoding.UTF8.GetBytes(responseText);
    response.Data = responseData;
    return response;

}

static void Main(string[] args)
{

    var x = new HTTPServer();
    x.ProcessRequest = ProcessMessage;
    x.Start();
    Console.ReadLine();
    x.Stop();
}
}

I grabbed my iPhone and made a request to the server. From typing the URL in there are actually two requests; there is a request for the URL that I typed for for an icon for the site.

Request:
Request:GET /HeyYall HTTP/1.1
Host: 192.168.50.79:8888
Upgrade-Insecure-Requests: 1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 14_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/91.0.4472.80 Mobile/15E148 Safari/604.1
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Connection: keep-alive


Request:GET /favicon.ico HTTP/1.1
Host: 192.168.50.79:8888
Connection: keep-alive
User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 14_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/91.0.4472.80 Mobile/15E148 Safari/604.1
Accept-Encoding: gzip, deflate
Accept-Language: en,en-US;q=0.9,ja-JP;q=0.8

To make sure this work, I loaded it into my game and made a request. The request was successful and I am ready to move on to implementing the logic that is needed for the game.

Why Your Computer Might not Run Windows 11

As of October 5, 2021, the RTM version of Windows 11 is available for download. I’ve downloaded it and have tried to install it on a range of machines. In doing this, the first thing that stands out is that there are a lot of otherwise capable machines in existence today that may not be able to run the new operating system. There are three requirements that tended to be the obstacles on the computers on which I did not install Windows 11.

  • Secure Boot Enabled
  • TPM 2.0
  • Unsupported Processor

Because of the Secure Boot and the TPM requirements, I found that I could not install Windows 11 on my Macs using Bootcamp. Other guides that I’ve found all have Windows 11 on Mac being installed within a virtual machine. The unsupported processor issue was not expected. One of the computers on which the installation failed to install has a Xeon 3.0 GHz processor with 16 cores and an RTX 3090 video card. This computer has 64 gigs of ram, 2 terabytes of M.2 storage, and a few terabytes on conventional drives. But its processor is not supported. If your computer matches the Windows 11 requirements on paper, that doesn’t give assurance that it is actually compatible. If you want to test for yourself, the best method is to run the Windows 11 upgrade advisor.

Microsoft is using virtualization-based security (VBS) to protect processes in Windows 11. There is a sub-feature of this called Hypervisor-Protected Code Integrity (HVCI) that prevents code injection attacks. Microsoft has said that computer’s with processors that support this feature have a 99.8% crash free experience (source). For purposes of reliability and security, Microsoft has decided that this feature will be part of the baseline for Windows 11. Back in August, Microsoft made a blog post stating that they found some older processors that met their requirements and would be adding them to their compatibility list. There’s a chance that a computer that shows as no compatible today could show as compatible later.

A Windows feature that I’ve enjoyed using is Windows 2 GO. With W2G, a Windows environment is installed on a USB drive specifically made for this feature (it would not quite work on a regular drive). The W2G drive could be plugged into any PC or Intel based Mac as a boot drive. It was a great way to port an environment around to use as an emergency drive. Microsoft discontinued support of the feature some time ago. But it still worked. With Windows 11, this feature is effectively dead.

You can find both the upgrade advisor and the Windows 11 download at the following link.

https://www.microsoft.com/en-us/software-download/windows11

Windows 11 offers a a lot of consumer focused features and a new look. But my interest is in the new APIs that the OS provides. Microsoft has extended the DirectX APIs, especially in Composition and DirectDisplay. The Bluetooth APIs have extended support for low energy devices. And there is now support for haptic pen devices and more phone control.

I was already on the market for a new laptop. I’ll be getting another computer that runs Windows 11 soon enough. But in the mean time, I’ve moved one of my successful installs to my primary work area so that I can try it out as my daily driver. More to come…


Twitter: @j2inet
Instagram: @j2inet
Facebook: j2inet
YouTube: j2inet