Golo Roden: 75 Prozent aller Softwareprojekte scheitern – was tun?

Viele Softwareprojekte sprengen sowohl den zeitlichen als auch den finanziellen Rahmen und liefern dann nachher trotzdem nicht das gewünschte Ergebnis. Warum?

Holger Schwichtenberg: Ende der .NET-8.0-Serie – NET 9.0 kommt bald​

Die umfangreiche Serie mit Blogbeiträgen zu .NET 8.0 und den Neuerungen in C# 12 geht zwei Monate vor dem Release von .NET 9.0 zu Ende.

Holger Schwichtenberg: Neu in .NET 8.0 [40]: Eigener Workload für WASI

Das WebAssembly System Interface (WASI) wird durch Microsoft nun mit einem eigenen SDK unterstützt – aber weiterhin im Status "experimentell".

Golo Roden: Die Einführung des EU Accessibility Act? Das wird teuer!

Es sollte selbstverständlich sein, Menschen nicht auszuschließen – doch in der IT wird genau das ständig gemacht. Ab 2025 gelten in der EU andere Regeln.

Golo Roden: Mehr als nur Programmieren: Ankündigung der tech:lounge Masterclass

Die the native web GmbH veranstaltet ab dem 11. November 2024 insgesamt zwölf Webinare zu den Themen Performance, Clean Code, Security und Architektur.

Golo Roden: Eine Frage des Vertrauens: Finger weg vom Homeoffice!

Viele Konzerne wollen das Homeoffice abschaffen. Die Politik hingegen diskutiert über ein gesetzlich verankertes Recht darauf. Was spricht dafür, was dagegen?

Code-Inside Blog: OpenAI API, LM Studio and Ollama

This is more of a “Today-I-Learned” post and not a “full-blown How-To article.” If something is completely wrong, please let me know - thanks!

I had the opportunity to attend the .NET User Group Dresden at the beginning of September for the exciting topic “Using Open Source LLMs” and learned a couple of things.

How to choose an LLM?

There are tons of LLMs (= Large Language Models) that can be used, but which one should we choose? There is no general answer to that - of course - but there is a Chatbot Arena Leaderboard, which measures the “cleverness” between those models. Be aware of the license of each model.

There is also a HuggingChat, where you can pick some models and experiment with them.

For your first steps on your local hardware: Phi3 does a good job and is not a huge model.

LM Studio

Ok, you have a model and an idea, but how to play with it on your local machine?

The best tool for such a job is: LM Studio.

The most interesting part was (and this was “new” to me), that you run those local models in an local, OpenAI compatible (!!!) server.

x

OpenAI Compatible server?!

If you want to experiment with a lightweight model on your system and interact with it, then it is super handy, if you can use the standard OpenAI client and just run against your local “OpenAI”-like server.

Just start the server, use the localhost endpoint and you can use a code like this:

using OpenAI.Chat;
using System.ClientModel;

ChatClient client = new(model: "model", "key",
        new OpenAI.OpenAIClientOptions()
        { Endpoint = new Uri("http://localhost:1234/v1") });

ChatCompletion chatCompletion = client.CompleteChat(
    [
        new UserChatMessage("Say 'this is a test.'"),
    ]);

Console.WriteLine(chatCompletion.Content[0].Text);

The model and the key don’t seem to matter that much (or at least I worked on my machine). The localhost:1234 service is hosted by LM Studio on my machine. The actual model can be configured in LM Studio and there is a huge choice available.

Even streaming is supported:

AsyncCollectionResult<StreamingChatCompletionUpdate> updates
    = client.CompleteChatStreamingAsync("Write a short story about a pirate.");

Console.WriteLine($"[ASSISTANT]:");
await foreach (StreamingChatCompletionUpdate update in updates)
{
    foreach (ChatMessageContentPart updatePart in update.ContentUpdate)
    {
        Console.Write(updatePart.Text);
    }
}

Ollama

The obvious next question is: How can I run my own LLM on my own server? LM Studio works fine, but it’s just a development tool.

One answer could be: Ollama, which can run large language models and has a compatibility to the OpenAI API.

Is there an Ollama for .NET devs?

Ollama looks cool, but I was hoping to find an “OpenAI compatible .NET facade”. I already played with LLamaSharp, but LLamaSharp doesn’t offer currently a WebApi, but there are some ideas around. My friend Gregor Biswanger released OllamaApiFacade, which looks promising, but at least it doesn’t offer a real OpenAI compatible .NET facade, but maybe this will be added in the future.

Acknowledgment

Thanks to the .NET User Group for hosting the meetup, and a special thanks to my good friend Oliver Guhr, who was also the speaker!

Hope this helps!

Holger Schwichtenberg: Neu in .NET 8.0 [38]: Containerdateien per dotnet publish erstellen

Es ist nun möglich, .NET-Anwendungen in eine Containerdatei zu veröffentlichen – ohne Dockerfile und ohne Bereitstellung in Docker.

Golo Roden: Nur Mut! – Endlich raus aus der Scrum-Hölle

Viele Entwicklerinnen und Entwickler leiden unter Scrum, doch kaum jemand wehrt sich gegen dessen Einsatz im Unternehmen. Woran liegt das?

Holger Schwichtenberg: Entwickler-Community-Konferenz am 27. und 28.09.2024 in Essen

Die iterate=>RUHR ist eine zweitägige Community-Konferenz mit Vorträgen zu .NET, KI, agilen Arbeitsweisen, Softwarearchitektur und -qualität.

Code-Inside Blog: Entity Framework Core 8.0 Breaking Changes & SQL Compatibility Level

We recently switched from .NET 6 to .NET 8 and encountered the following Entity Framework Core error:

Microsoft.Data.SqlClient.SqlException: 'Incorrect syntax near the keyword 'WITH'....

The EF code uses the Contains method as shown below:

var names = new[] { "Blog1", "Blog2" };

var blogs = await context.Blogs
    .Where(b => names.Contains(b.Name))
    .ToArrayAsync();

Before .NET 8 this would result in the following Sql statement:

SELECT [b].[Id], [b].[Name]
FROM [Blogs] AS [b]
WHERE [b].[Name] IN (N'Blog1', N'Blog2')

… and with .NET 8 it uses the OPENJSON function, which is not supported on older versions like SQL Server 2014 or if the compatibility level is below 130 (!)

  • See this blogpost for more information about the OPENJSON change.

The fix is “simple”

Ensure you’re not using an unsupported SQL version and that the Compatibility Level is at least on level 130.

If you can’t change the system, then you could also enforce the “old” behavior with a setting like this (not recommended, because it is slower!)

...
.UseSqlServer(@"<CONNECTION STRING>", o => o.UseCompatibilityLevel(120));

How to make sure your database is on Compatibility Level 130?

Run this statement to check the compatibility level:

SELECT name, compatibility_level FROM sys.databases;

We updated our test/dev SQL Server and then moved all databases to the latest version with this SQL statement:

DECLARE @DBName NVARCHAR(255)
DECLARE @SQL NVARCHAR(MAX)

-- Cursor to loop through all databases
DECLARE db_cursor CURSOR FOR
SELECT name
FROM sys.databases
WHERE name NOT IN ('master', 'tempdb', 'model', 'msdb') -- Exclude system databases

OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @DBName

WHILE @@FETCH_STATUS = 0
BEGIN
    -- Construct the ALTER DATABASE command
    SET @SQL = 'ALTER DATABASE [' + @DBName + '] SET COMPATIBILITY_LEVEL = 150;'
    EXEC sp_executesql @SQL

    FETCH NEXT FROM db_cursor INTO @DBName
END

CLOSE db_cursor
DEALLOCATE db_cursor

Check EF Core Breaking Changes

There are other breaking changes, but only the first one affected us: Breaking Changes

Hope this helps!

Holger Schwichtenberg: Neu in .NET 8.0 [37]: Zusammenfassung aller Build-Artefakte in ein Verzeichnis

Entwicklerinnen und Entwickler können nun die Ordner /bin, /obj und /publish unter einem Ordner zusammenfassen.

Code-Inside Blog: Connection Resiliency for Entity Framework Core and SqlClient

This is more of a “Today-I-Learned” post and not a “full-blown How-To article.” If something is completely wrong, please let me know - thanks!

If you work with SQL Azure you might find this familiar:

Unexpected exception occurred: An exception has been raised that is likely due to a transient failure. Consider enabling transient error resiliency by adding ‘EnableRetryOnFailure’ to the ‘UseSqlServer’ call.

EF Core Resiliency

The above error already shows a very simple attempt to “stabilize” your application. If you are using Entity Framework Core, this could look like this:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder
        .UseSqlServer(
            @"Server=(localdb)\mssqllocaldb;Database=EFMiscellanous.ConnectionResiliency;Trusted_Connection=True;ConnectRetryCount=0",
            options => options.EnableRetryOnFailure());
}

The EnableRetryOnFailure-Method has a couple of options, like a retry count or the retry delay.

If you don’t use the UseSqlServer-method to configure your context, there are other ways to enable this behavior: See Microsoft Docs

Microsoft.Data.SqlClient - Retry Provider

If you use the “plain” Microsoft.Data.SqlClient NuGet Package to connect to your database have a look at Retry Logic Providers

A basic implementation would look like this:

// Define the retry logic parameters
var options = new SqlRetryLogicOption()
{
    // Tries 5 times before throwing an exception
    NumberOfTries = 5,
    // Preferred gap time to delay before retry
    DeltaTime = TimeSpan.FromSeconds(1),
    // Maximum gap time for each delay time before retry
    MaxTimeInterval = TimeSpan.FromSeconds(20)
};

// Create a retry logic provider
SqlRetryLogicBaseProvider provider = SqlConfigurableRetryFactory.CreateExponentialRetryProvider(options);

// Assumes that connection is a valid SqlConnection object 
// Set the retry logic provider on the connection instance
connection.RetryLogicProvider = provider;
// Establishing the connection will retry if a transient failure occurs.
connection.Open();

You can set a RetryLogicProvider on a Connection and on a SqlCommand.

Some more links and tips

These two options seem to be the “low-level-entry-points”. Of course could you wrap each action with a library like Polly.

During my research I found a good overview: Implementing Resilient Applications.

Hope this helps!

Holger Schwichtenberg: Neu in .NET 8.0 [36]: Andere Grundeinstellung bei dotnet publish und dotnet pack

Die Kommandozeilenbefehle dotnet publish und dotnet pack erstellen nun standardmäßig ein Release-Build.

Golo Roden: Scrum, XP & Co. – warum keiner mehr agil arbeiten will

Die Hochphase agiler Methoden wie Scrum und Extreme Programming scheint vorbei zu sein – ja, es scheint sogar einen Gegentrend zu geben. Wie kommt das?

Holger Schwichtenberg: Neu in .NET 8.0 [35]: Sicherheitswarnungen vor NuGet-Paketen

Visual Studio und die .NET-Kommandozeilenwerkzeuge können nun vor Paketen mit Sicherheitslücken warnen.

Code-Inside Blog: UrlEncode the Space Character

This is more of a “Today-I-Learned” post and not a “full-blown How-To article.” If something is completely wrong, please let me know - thanks!

This might seem trivial, but last week I noticed that the HttpUtility.UrlEncode(string) encodes a space ` ` into +, whereas the JavaScript encodeURI(string) method encodes a space as %20. This brings up the question:

Why?

It seems that in the early specifications, a space was encoded into a +, see this Wikipedia entry:

When data that has been entered into HTML forms is submitted, the form field names and values are encoded and sent to the server in an HTTP request message using method GET or POST, or, historically, via email.[3] The encoding used by default is based on an early version of the general URI percent-encoding rules,[4] with a number of modifications such as newline normalization and replacing spaces with + instead of %20. The media type of data encoded this way is application/x-www-form-urlencoded, and it is currently defined in the HTML and XForms specifications. In addition, the CGI specification contains rules for how web servers decode data of this type and make it available to applications.

This convention has persisted to this day. For instance, when you search something on Google or Bing with a space in the query, the space is encoded as a +.

There seems to be some rules however, e.g. it is only “allowed” in the query string or as form parameters.

I found the question & answers on StackOverflow quite informative, and this answer summarizes it well enough for me:

| standard      | +   | %20 |
|---------------+-----+-----|
| URL           | no  | yes |
| query string  | yes | yes |
| form params   | yes | no  |
| mailto query  | no  | yes |

What about .NET?

If you want to always encode spaces as %20, use the UrlPathEncode method, see here.

You can encode a URL using with the UrlEncode method or the UrlPathEncode method. However, the methods return different results. The UrlEncode method converts each space character to a plus character (+). The UrlPathEncode method converts each space character into the string “%20”, which represents a space in hexadecimal notation. Use the UrlPathEncode method when you encode the path portion of a URL in order to guarantee a consistent decoded URL, regardless of which platform or browser performs the decoding.

Hope this helps!

Golo Roden: Node.js + TypeScript = Nie wieder JavaScript

Wer mit Node.js entwickelt, schreibt JavaScript – oder muss umständlich TypeScript konfigurieren. Doch beides hat nun bald ein Ende.

Holger Schwichtenberg: Neu in .NET 8.0 [34]: Verbesserte Ausgaben beim Kompilieren

Der neue Terminal Logger erzeugt übersichtlichere Ausgaben, aber der alte lässt sich auf Wunsch weiterhin verwenden.

Golo Roden: OpenAI und Microsoft: Der Tragödie zweiter Teil

Wer dachte, dass nach dem Drama um Sam Altman im November 2023 Ruhe bei OpenAI eingekehrt ist, irrt. Das war erst der Anfang. Eine Analyse von Golo Roden.

Holger Schwichtenberg: Neu in .NET 8.0 [33]: Erweiterung des AOT-Compilers

Der AOT-Compiler kann auch Webservices und Hintergrunddienste übersetzen, aber mit einigen Einschränkungen.

Code-Inside Blog: dsregcmd, WAM and 'Connected to Windows'-Accounts

This is more of a “Today-I-Learned” post and not a “full-blown How-To article.” If something is completely wrong, please let me know - thanks!

I was researching if it is possible to have a “real” single-sign-on experience with Azure AD/Entra ID and third-party desktop applications and I stumbled across a few things during my trip.

“Real” SSO?

There are a bunch of definitions out there about SSO. Most of the time, SSO just means: You can use the same account in different applications.

But some argue that a “real” SSO experience should mean: You log in to your Windows Desktop environment, and that’s it - each application should just use the existing Windows account.

Problems

With “Integrated Windows Auth,” this was quite easy, but with Entra ID, it seems really hard. Even Microsoft seems to struggle with this task, because even Microsoft Teams and Office need at least a hint like an email address to sign in the actual user.

Solution?

I _didn’t__ found a solution for this (complex) problem, but I found a few interesting tools/links that might help achieve it.

Please let me know if you find a solution 😉

“dsregcmd”

There is a tool called dsregcmd, which stands for “Directory Service Registration” and shows how your device is connected to Azure AD.

PS C:\Users\muehsig> dsregcmd /?
DSREGCMD switches
                        /? : Displays the help message for DSREGCMD
                   /status : Displays the device join status
               /status_old : Displays the device join status in old format
                     /join : Schedules and monitors the Autojoin task to Hybrid Join the device
                    /leave : Performs Hybrid Unjoin
                    /debug : Displays debug messages
               /refreshprt : Refreshes PRT in the CloudAP cache
          /refreshp2pcerts : Refreshes P2P certificates
          /cleanupaccounts : Deletes all WAM accounts
             /listaccounts : Lists all WAM accounts
             /UpdateDevice : Update device attributes to Azure AD

In Windows 11 - as far as I know - a new command was implemented: /listaccounts

dsregcmd /listaccounts

This command lists all “WAM” accounts from my current profile:

The ...xxxx... is used to hide information

PS C:\Users\muehsig> dsregcmd /listaccounts
Call ListAccounts to list WAM accounts from the current user profile.
User accounts:
Account: u:a17axxxx-xxxx-xxxx-xxxx-1caa2b93xxxx.85c7xxxx-xxxx-xxxx-xxxx-34dc6b33xxxx, user: xxxx.xxxx@xxxx.com, authority: https://login.microsoftonline.com/85c7xxxx-xxxx-xxxx-xxxx-34dc6b33xxxx.
Accounts found: 1.
Application accounts:
Accounts found: 0.
Default account: u:a17axxxx-xxxx-xxxx-xxxx-1caa2b93xxxx.85c7xxxx-xxxx-xxxx-xxxx-34dc6b33xxxx, user: xxxx.xxxx@xxxx.com.

What is WAM?

It’s not the cool x-mas band with the fancy song (that we all love!).

WAM stands for Web Account Manager and it integrates with the Windows Email & accounts setting:

x

WAM can also be used to obtain a Token - which might be the right direction for my SSO question, but I couldn’t find the time to test this out.

“Connected to Windows”

This is now pure speculation, because I couldn’t find any information about it, but I think the “Connected to Windows” hint here:

x

… is based on the Email & accounts setting (= WAM), and with dsregcmd /listaccounts I can see diagnostic information about it.

“Seamless single sign-on”

I found this troubleshooting guide and it seems that there is a thing called “seamless single sign-on”, but I’m not 100% sure if this is more a “Development” topic or “IT-Pro” topic (or a mix of both).

TIL

I (and you!) have learned about a tool called dsregcmd.

Try out the dsregcmd /status, it’s like ipconfig /all, but for information about AD connectivity.

WAM plays an important part with the “Email & accounts” setting and maybe this is the right direction for the actual SSO topic.

Open questions…

Some open questions:

  • Why does dsregcmd /listAccounts only list one account when I have two accounts attached under the “WAM” (see screenshot - a Azure AD account AND an Microsoft account)?
  • Where does “Connected to Windows” come from? How does the browser know this?
  • What is “seamless single-sign-on”?

Hope this helps!

Golo Roden: Spielerisch Assembler lernen

Das Buch "Einführung in die moderne Assembler-Programmierung" von Scot W. Stevenson bietet eine solide Einführung in Assembler auf Basis der RISC-V-Architektur.

Holger Schwichtenberg: Neu in .NET 8.0 [32]: Weitere Neuerungen in System.Text.Json 8.0

Die JSON-Bibliothek kann nun auch nicht öffentliche Mitglieder serialisieren und deserialisieren.

Holger Schwichtenberg: Neu in .NET 8.0 [31]: Erweiterte Serialisierung in System.Text.Json 8.0

Die JSON-Bibliothek kann nun auch nicht öffentliche Mitglieder serialisieren und deserialisieren.

Code-Inside Blog: SQL ConnectionString: Encrypt & Trust Server Certificate

This is more of a “Today-I-Learned” post and not a “full-blown How-To article.” If something is completely wrong, please let me know - thanks!

In our product, we store all data in an MS SQL database. One of our clients had issues with the SQL connection, and I want to share what I learned about SQL Encryption and how (some) properties of the Connection String affect the behavior.

Basic SQL Connection String

In general, we have a pretty easy setup:

Our application reads a typical connection string that looks like this Data Source=your-sql-server.yourcorp.local;Initial Catalog=database_x;User ID=username;Password=password_here;MultipleActiveResultSets=True;Encrypt=False or (for Windows Authentication) Integrated Security=true instead of User ID=username;Password=password_here, and uses the (new) Microsoft.Data.SqlClient to connect to the database.

Let’s look at all applied properties:

Since Version 4.0 of the Microsoft.Data.SqlClient the Encrypt property defaults to true instead of false, and now we are entering the field of encryption…

Encryption

We usally use Encrypt=False, because in most cases, there is no proper certificate installed on the SQL Server - at least this is our experience with our clients. If a client has a proper setup, we recommend using it, of course, but most of the time there is none.

With Encrypt=True, the data between the client and the server is TLS encrypted (and this is a good thing, and the breaking change therefore had a good intention).

If you are interested how to set it up, this might be a good starting point for you: Configure SQL Server Database Engine for encrypting connections

In some cases, your client might not be able to trust the server certificate (e.g. there is just a self-signed cert installed on the SQL server). Then you can disable the certification validation via TrustServerCertification, but this shouldn’t be used (at least in production) or handled with care. If the certificate doesn’t match the name of the Data Source, then you can use HostNameInCertificate.

What have I learned?

I already knew about Encrypt=True or Encrypt=False, but the behavior of TrustServerCertification (and when to use it) was new for me. This Stackoverflow-question helped me a lot to discover it.

Hope this helps!

Holger Schwichtenberg: Neu in .NET 8.0 [30]: Neue Datentypen in System.Text.Json 8.0

System.Text.Json beherrscht nun Half, Int128, UInt128, Memory und ReadOnlyMemory.

Golo Roden: Risiko Microservices? Vor- und Nachteile einer verteilten Architektur

Microservices sind die perfekte Lösung für gewisse Probleme. Doch unpassend eingesetzt, können sie das ganze Projekt ruinieren. Worauf gilt es zu achten?

Holger Schwichtenberg: Neu in .NET 8.0 [29]: Verbesserungen für den JSON-Source-Generator

Der Source Generator ist in .NET 8.0 wichtiger, damit die JSON-Serialisierung und -Deserialisierung auch AOT-Anwendungen funktioniert.​

Golo Roden: Zwölf Regeln für die perfekte (Micro-)Services-Architektur

Services versprechen eine einfache, zielgerichtetete und fachlich adäquate Softwareentwicklung. Doch worauf sollte man bei ihrem Bau achten?

Marco Scheel: Erste Schritte mit macOS als Windows IT Pro und Microsoft 365 Berater

Seit ich mein Beruf ausübe bin ich von macOS Benutzern umgeben. Der erste MacBook User begleitet mich seit 2005 und die letzten vier Jahre gab es quasi ein MacBook-Boom. In meiner Rolle als Cloud Architeckt für Modern Collaboration im Microsoft 365 Umfeld hatte ich also immer Gelegenheit, das Leiden meiner Mac-Freunde mit Microsoft-Software zu begleiten. Es ist 2024 und “alles ist Gut”, also wollte ich selbst wissen, was dran ist am Hype des (Arbeits-)Leben im Apple-Ökosystem.

boy looking at a old crt with an apple logo

Ausgangssituation

Ich habe meine Computerbegeisterung mit einem C64 (danke an meinen Vater) gestartet und etwas später durfte ich einen Commodore 116 mit Datasette mein Eigen nennen. Der nächste Schritt war schon ein Microsoft PC (286). Ich habe schon immer mit Begeisterung die Apple Keynotes verfolgt. Steve Jobs Keynotes sind unerreicht und nur Steve Balmer kam einmal ganz kurz ganz nah (Developer, Developer, Developer, …).

Ich habe in einer Webagentur gearbeitet und bin seit 2005 beim meiner Meinung nach besten Microsoft Partner in Deutschland.

“10 Finger System” Fehlanzeige"! Aber die meisten Tasks auf meinem Windows System kann ich recht sicher, schnell und effizient umsetzen. Auf macOS bin ich ein absoluter Anfänger und ich habe so meine Startschwierigkeiten. Ich bin auf der Suche nach einem Schnellstart für macOS für Benutzer die Windows schon lange sicher bedienen. Ich suche also euer Feedback und möchte meine Erfahrungen teilen.

Aufgabenstellung

Um einen besseren Eindruck zu bekommen, hier eine Liste der Tasks, die ich täglich oder wöchentlich durchführe:

  • Microsoft Teams ist das Herz unserer Unternehmenskommunikation (Chat und Meetings)
  • Arbeiten mit Office Dokumenten (Word, PowerPoint), Loop und Copilot
  • Arbeiten mit browserbasierten Systemen (Ticketsystem, Technische Dokumentation, …)
  • Administration von Microsoft 365 Umgebungen (PROD / LAB)
    • Web via verschiedener Microsoft Edge Profile
    • PowerShell
    • Virtueller Privilege Admin Workstation (PAW)
    • Fido Key Anmeldung
  • Leichte Dev Tätigkeiten
    • Visual Studio 2022
    • VS Code
    • GitHub

Hardware

Anfang Juni 2024 hatte ich die Chance, “kurzfristig” ungenutzte Apple Hardware im produktiven Einsatz zu testen. Ich habe eine Woche lang ein MacBook Pro M3 13’’ verwendet und meine ersten Gehversuche gemacht. Aktuell habe ich ein “Downgrade” mit einem “abgelegten” MacBook Pro M1 13’’ im Einsatz. Es hat sich auch die Gelegenheit ergeben, ein MacBook Air M3 13’’ (8 GB RAM!) zu testen. Wenn ich aber Öko-System sage, dann MUSS da auch noch ein iPhone 15 Pro mitspielen. Allerdings nutze ich das nur mit WLAN, denn meine SIM-Karte bleibt in meinem Pixel ❤️.

the microsoft logo, the apple logo and the google logo sitting at a round table playing cards

In meinem Alter hat man auf der Windows Seite schon einige Erfahrungen gesammelt. Einige Highlights:

  • Toshiba Protege M200
  • Surface Pro 1
  • Surface Pro 2
  • Surface Book 1
  • Surface Book 2
  • Dell XPS 15 (i7 11800H mit RTX 3050 TI)

Aktuell bin ich auf einem top ausgerüsteten Dell XPS 15 (i7 13700H mit RTX 4060) unterwegs. Seit dem Absprung von Windows Phone mit dem Microsoft Lumia 950 XL bin ich beim nativen Google Pixel geblieben (2 Pro, 4 Pro und aktuell 6 Pro). Für kurze Zeit hatte ich ein Apple iPad Air (4th Gen mit USB-C), welches ich gegen ein Samsung Tab S9 FE “getauscht” habe.

Wenn unsere Mitarbeiter keinen speziellen Wunsch haben, setzen wir seit einiger Zeit auf HP Elitebooks und auch die habe ich hin und wieder getestet. Im Jahr 2024 setzt Apple noch immer hohe Standards aber eben auch mit “wenig” Auswahl und passenden Preisen. Auf der Windows Seite gibt es ein breites Spektrum mit jeder Menge “Nieten”. Im Business Umfeld kann das schnell gefährlich werden und es kann sich rentieren an die etablierten Business Laptop Hersteller zu halten (Dell, Lenovo und HP).

Mein aktueller Dell muss sich nicht hinter den Apple Geräten verstecken. Der Mac hat eine sehr gute Webcam. Mein Dell leider eine sehr schlecht. Tastatur, Trackpad und die gesamte Verarbeitung sind für mich gleich auf. Die Funktion, das iPhone als Web-Kamera zu verwenden, funktioniert und stürzt nicht nach ein paar Minuten ab wie bei meinem Google Pixel. Allerdings habe ich keinen Nutzen bei der bereits guten Webcam im MacBook selbst.

Fazit: Hier kann man auf keiner Seite was falsch machen.

Installation

Mein Windows Device ist natürlich per Autopilot via Intune gemanaged und nach der Out-Of-The-Box Experience in 30 Minuten compliant und mit Office/Teams sofort einsetzbar. Die “Installation” von Windows ist also bei meinen Geräten ein absoluter Traum, aber wir machen so was halt auch professionell.

Für Apple Geräte erfordern wir das Onboarding via Apple Business Manager. Bevor ich also den Desktop sehe, MUSS ich mich mit meiner Entra ID anmelden und das Gerät wird via Intune konfiguriert und mit dem Company Portal + Microsoft Edge vorinstalliert. Noch muss ich einen lokalen Benutzer anlegen und ein dediziertes Passwort festlegen. Hier hat der Windows PC noch die Nase vorn. Es folgt das Onboarding von Touch ID und schon ist das Leben ein ganzes Stück leichter. Allerdings gibt es immer wieder Situationen (z.B. Reboot), wo ich das Passwort eingeben muss. Als neuer Benutzer muss man auch die Touch ID Prompts lesen… sonst gibt man permanent sein Passwort ein, statt sein Fingerabdruck zu verwenden (UAC Like Prompts).

create account on macos

Auf dem Desktop angekommen, muss der Business User bei uns das Microsoft Company Portal öffnen und den Mac final onboarden. Gleich noch Microsoft 365 Apps for Enterprise zur Installation angeklickt und dann den Reboot für die Aktivierung des Filevault (Bitlocker für Mac) durchgeführt. Erst jetzt ist der Mac compliant und kann mit dem Entra ID Konto wie auf Windows genutzt werden.

Beim Zurücksetzen des Mac (zum Beispiel via Intune) ist der Mac in gefühlt wenigen Minuten bereit für den nächsten Benutzer. Die Windowsgeräte brauchen hier schon deutlich länger. Klappt der Reset nicht, dann muss man ins Recovery Menü und die Installation dauert ähnlich lang, wie ein Windows Wipe&Reload.

Fazit: Die Entra ID Anmeldung, die OOBE und die Softwareverteilung machen Windows für mich zum Gewinner, allerdings nur solange der Mac noch den lokalen Benutzer benötigt. Kein Grund, um nicht zum Mac zu wechseln.

User Interface

Die Unterschiede könnten hier nicht deutlicher sein. Es gibt ähnliche Konzepte, aber die Ausführung unterscheidet sich deutlich.

Taskleiste, Dock

Das Dock am unteren Rand erlaubt den schnellen Zugriff auf Anwendungen wie die Taskleiste auf Windows. Hat das Programm ein schwarzen Punkt unter seinem Icon, dann ist es gerade gestartet. Im Dock gibt es rechts neben den gepinnten Apps ein Bereich für “empfohlene und zuletzt verwendete Apps”. Ich habe mir meine 11 Anwendungen, die ich häufig benötige gepinnt. Der zusätzlich Bereich mit den letzten und empfohlenen Apps hat mich ständig gestört, weil dann nicht relevante Elemente sichtbar sind. Beispiel: Activity Monitor, Preview, … und mehr. Ich habe den Teil über die Einstellungen ausgeblendet.

Nach dem ersten Boot sitzen im Dock 17 Anwendungen. Da ich nicht im Ökosystem bin, habe ich 15 davon mühsam über Rechtsklick “Option -> Keep in dock” ausgeblendet. Im Verlauf meiner Nutzung habe ich gelernt, dass man die Apps auch ins “Nichts” ziehen kann, um sie aus dem Dock zu entfernen. Macht man nur einmal nach dem Setup, aber man fragt sich immer, ob es nicht eleganter geht.

my dock writing this article

Ganz rechts im Dock sitzt der Papierkorb, den ich noch nicht einmal gebraucht habe. Daneben sitzt dann der Download Ordner, welcher auch das letzte Element als Preview-Icon anzeigt. Beim Download eines Bildes hat man es also permanent in Sicht. Ich nutze unter Windows den Download Ordner auch recht häufig, aber immer über den “Umweg” Datei Explorer. Den Download Teil kann man immerhin ausblenden. Den Papierkorb nicht.

Startmenü

Das Startmenü des Mac sieht aus wie ein iPad-Homescreen und heißt “Launchpad”. Das Windows Startmenü hat eine lange Reise hinter sich. Ich war selbst zu Windows 8 Zeiten nicht unzufrieden. Ich persönlich nutze das Startmenü nur wenig. Ich navigiere nicht zu Apps sondern ich Suche und auch wenn es keiner glauben mag: mit Erfolg! Ich habe eine paar Apps ins Windows-Startmenü gepinnt. Das Launchpad wird dann wichtig, wenn man “einige” Apps deinstallieren will. Im Launchpad einfach die OPTION Taste festhalten, dann fangen die Apps an zu wackeln und kann über den Apps mit Uninstall Option das kleine X Drücken. Ich glaube zu wissen, dass Apps die nicht “Wackeln” aus dem Finder über den Ordner “Applications” gelöscht werden können.

Spotlight

Meine Mac Kollegen schwören auf Spotlight und finden, dass es auf dem PC keine Alternative gibt. Ich kann das nicht nachvollziehen. Ich bin sicher man kann sich an Spotlight gewöhnen. Ich suche auf meinem Windows entweder eine App, eine Datei oder will eine Websuche starten. Ich bin Microsoft 365 Benutzer und unsere Entra ID-joined Geräte bieten per Default bei der Suche zugriff auf unsere Inhalte in der Cloud. Teams, Groups, Kontakte, Dateien, … alles da und ich persönlich bin begeistert von der Umsetzung. Es mag sein, dass Spotlight besser in den Lokalen Dateien suchen kann. Ich frage nur: Welche lokalen Dateien? Ja, es mag Use Cases geben, aber das ist mein Bericht und ich habe schon lange nicht mehr nach einer lokalen Datei gesucht. Auf dem Windows nutze ich die Windows Taste, um alle genannten Aktionen zu starten. Auf dem Mac ist es COMMAND + Leertaste. Es ist sicher ein effektives System, aber ich bevorzuge die Integration von Microsoft 365 in meinem Windows Startmenü/Suche.

macOS spotlight search for keeper

Window-Management OMG

Jetzt kommen wir zum Window-Management. Für mich eine der größten Hürden zur persönlichen Prduktivität. Auf dem Windows System ist das über die Jahre immer besser geworden. Ich nutze im Büro ein 34 Zoll Widescreen Bildschirm und bin auf ein gutes Window Handling angewiesen. Nach zwei Wochen habe ich gelernt, mit der Mac-Implementierung zu leben. Lieben kann ich es nicht. Auf dem Hauptbildschirm hilft der Doppelick, um ein Fenster zu “maximieren”. Auf dem Wide Screen bin ich noch immer auf “manuelles” Ausrichten und ziehen angewiesen. Wenn ich die letzte Keynote richtig verstanden habe, dann zieht Apple mit der nächsten macOS Version nach und implementiert “Snap”. So lange versuche ich es auch noch ohne extra Tool. Ein absolutes K.O. Kriterium ist allerdings die Windows Alt-Tab Implementierung von macOS (CONTROL + TAB). Ich nutze den Microsoft Edge als Browser und hab da 8-12 Profile eingerichtet. Auf Windows nutze ich die Edge Beta Version für meine LAB Profile, um eine noch einfachere Unterscheidung zwischen Produktion und LAB zu haben. Jedes Profil ist unter Windows ein eigenes Task Symbol. Ich kann also am Beta Logo sehen, ob LAB oder PROD und das Profilbild zeigt, welcher Kunde/Persona/Use Case damit verbunden ist. Auf dem Mac steckt alles hinter einem Edge Icon (oder zwei mit Beta). Über ein Rechtsklick auf das Icon, kann ich offene Tabs sehen (ohne Profilinformation). COMMAND + TAB bringt einfach den letzten Tab nach vorne. Hier MUSS man mit einem Helper-Tool unterstützen. Alle meine Kollegen haben hier auf AltTab verwiesen. Wenn man dann OPTION + TAB benutzt, dann gibt es ein Windows ähnliches Menü. Wenn man seine Edge Profile noch mit Farben versieht, kommt man auf ein nutzbares Niveau.

alt tab on my system

Fazit

Wenn Apple das Window Management verbessert, dann kann es auch mit nativen Tools etwas werden. AltTab wird aber wohl noch eine Weile nötig sein. Wächst man als Apple User auf, dann bin ich sicher man hat sich eine andere Arbeitsweise angewöhnt und ist genauso effektive und nutzt vielleicht 8 verschiedene Browser 😆

Userinteraktion

Das Keyboard des MacBook Pro (M1 & M3) ist OK. Mein Dell XPS 15 hat ein großartiges Keyboard. Es gibt Windowsgeräte mit schlechten oder mittelmäßigem Keyboard. In der Windows Welt gibt es mehr Auswahl, aber eben auch die Chance mal im Mittelmaß zu landen, bei vergleichbarer Preisklasse. Als Windows User fehlen mir PRINT-SCR, POS1, END, PIPE “|” und noch ein paar Tasten, welche “falsch” belegt sind. Mit einer externen Tastatur (die ich auch unter Windows nur selten nutze) ist das weniger ein Problem, aber am Ende sicher einfach nur Gewohnheit.

Eine große Umstellung sind allerdings die Shortcuts, die man über die Zeit gelernt hat. Die Handhaltung für Copy, Cut und Paste ist “ungewöhnlich”. Nach fast 27 Jahren Berufserfahrung bevorzuge ich die Windows Handhaltung. Wenn man sich unter macOS mal an COMMAND+C(X/V) gewöhnt hat, dann fällt als nächstes auf, dass der Mac das Springen zwischen einzelnen “Wörtern” mit der OPTION Taste implementiert. Ich bin sehr oft nur mit dem Keyboard unterwegs und will die letzten 3 Worte (C# Code) markieren, ausschneiden und 2 Worte weiter rechts einfügen. Auf dem PC geht das alles mit der STRG Taste (SHIFT + STRG + LINKS + LINKS + LINKS + X -> STRG + RECHTS + RECHTS + V). Auf dem Mac ist COMMAND + Links aber POS1. OPTION + Links sprint ein Wort in die gewünschte Richtung. Besonders bei Textbearbeitung (Word, PowerPoint, Outlook, VS Code) merke ich die Umstellung und bin noch immer nicht 100% flüssig unterwegs. Screenhots sind ebenfalls als Windows User super “komisch”.

  • COMMAND + SHIFT + 3 = Ganzer Bildschirm
  • COMMAND + SHIFT + 4 = Bildschirmauswahl (wobei der Bildschirminhalt nicht einfriert und “stillhält”)
  • COMMAND + SHIFT + 4 + Spacebar = Fenster auswählen (wobei der Bildschirminhalt nicht einfriert und “stillhält”)
  • COMMAND + SHIFT + 5 = Screenshot App mit ähnlichen Optionen wie Windows Snipping Tool (Screenrecoding, Annotations, …) Es kommt hinzu, dass der Screenshot “nur” auf den Desktop gespeichert wird und nicht parallel ins Clipboard. Dafür muss man zusätzlich die CONTROL Taste festhalten.

Ich habe noch nie und ich hoffe ich muss auch NIE eine Magic Mouse verwenden. Nicht nur das Ladekabel wäre eine K.O. Kriterium (Lightning), sondern der Wechsel von eine Logitech MX Master (2&3) wäre einfach unfair 😂 Ich spare mit mal mein “Fake” Dad-Joke zum fehlenden Rechtsklick. Ich hab von einem Mac User gelernt, dass man mit einem 3x Klick der linken Maustaste einen ganzen Block markiert. Mit einer externen Maus gelingt mir das leider nicht wirklich konsistent.

the holy mouse

Früher war der Trackpad des Mac ein Riesenvorteil. Heute haben wir im Windows alles kopiert, was wichtig war. Ob Maus oder Trackpad die Scrollrichtung ist als Windows-User falsch, aber man kann es für beide Geräte “richtigstellen”. Als Windows User gab es sonst hier keine großen Umstellungen.

Fazit: Die Umstellung fällt recht einfach, wenn man die wichtigsten Command im Kopf behält. Wechselt man immer hin und her, dann wird es etwas komplizierter (in meinem Alter zumindest).

Software

Wenn ich an macOS denke, wenn ich Apple und Software höre, dann denke ich an den Apple App Store. Wenn ich jetzt allerdings mein System anschaue, dann kommen weniger als 50% der Apps aus dem App Store. Ich nutze den Mac ja überwiegen als Microsoft 365 Berater und nicht als Privatperson. Mich hat aber schon überrascht, dass ich so “wenig” aus dem App Store installiert habe. Es war besonders irritieren, wenn ich versucht hab im Store nach Kollegen-Empfehlungen gesucht habe und dann nicht diese Version gefunden habe, sondern ähnliche und Fake-Apps".

search for the browser opera

Für meine Arbeit mit PowerShell (Graph, PnP, Teams, Exchange, …) bin ich auf einen Terminal angewiesen. Ich habe schon viel gutes vom Terminal auf macOS gehört. Eventuell geht es da aber um das grundlegende Vorhandensein eines echten Terminal. Ich persönlich komme damit nicht klar. Der Terminal unter Windows ist noch recht Jung und erst mit Windows 11 ab Werk integriert, aber ich bin sehr happy mit der Implementierung der verschiedenen Commandlines (CMS, PS5, PS7, VS Cmd, Cloud Shell, ..). Auf macOS habe ich dann den Tipp von einem Kollegen bekommen: Warp. Kostenlos und eine super Unterstützung. Danke Philipp!

Windows hat irgendwann mit Windows 10 ein eingebautes Multi-Clipboard bekommen. Tatsächlich ist es viel zu unbekannt (alle mal WIN+V drücken). Durch meine Sitznachbarin dachte ich tatsächlich, dass macOS es schon seit Jahren hat. Allerdings war es keine Systemoption, sondern flycut. Ich brauche aber eine Lösung mit Bildersupport. Ich bin dann hier bei maccy gelandet. Es ist eine dieser Apps, die man via Brew installieren kann ohne zu zahlen oder aber für 10 Euro aus dem App Store.

Was unter Windows die Tray Icons sind, finden wir im Mac oben rechts in den Menu Bar. Es ist verwunderlich, dass es hier keine Möglichkeit vom System gibt, diese Icons zu verschieben. Auf einem 13’’ Mac (Pro oder Air) mit Notch hat man nur wenig Platz und die Icons verschwinden tatsächlich hinter der Notch. Auf einem MacBook Pro 16’’ ist das Problem nicht ganz so dramatisch, aber die Tatsache, dass man die Reihenfolge nicht verändern kann, ist sehr irritierend. Philipp hat mir hier Bartender empfohlen, aber die 20 Euro !!! haben mich dann doch nach Alternativen suchen lassen. Ich bin dann über Hidden Bar gestolpert und ganz zufrieden. Wenn man einen zweiten Bildschirm hat, dann kann man alle Icons so anordnen wie man will.

want my windows tray icons back

Die Microsoft 365 Apps for Enterprise funktinieren natürlich auf dem Mac. In der täglichen Nutzung habe ich aber immer wieder den Eindruck, dass es sich irgendwie anders anfühlt. Es ist vielleicht nur ein Gefühl eines alternden Office 95 Benutzers. Outlook spielt nur eine untergeordnete Rolle in meinem Alltag. Für das Verwalten von geschäftlichen und privaten Terminen ist es aber noch immer das Tool meiner Wahl. Ich bin immer davon ausgegangen, dass es auch auf dem Mac ein “New Outlook” gibt. Es gibt tatsächlich zwei Versionen von Outlook, aber keine Version entspricht dem “New Outlook” unter Windows. Ich bin aktuell noch unentschlossen, ob ich deswegen wieder Outlook on the Web als Edge App nutzen soll oder bei der neuen Outlook Version des Mac bleibe.

not the new outlook you are looking for

  • Intune
    • Company Portal
    • Microsoft 365 Apps for Enterprise (Outlook, Word, Excel, PowerPoint und Teams)
    • Microsoft Edge
    • Microsoft Remote Desktop
  • Downloads von der Website
  • Installation via Brew
    • Terminal Warp: Your terminal, reimagined Link
    • Stats a better ressource monitor Link
    • Maccy a multi clipboard with picture support Link
    • AltTab Link
    • PowerShell 7 Link
  • App Store
    • Hidden Bar [Link]https://apps.apple.com/de/app/hidden-bar/id1452453066?l=en-GB&mt=12
    • Keeper Password manager Link
    • WhatsApp Link
    • Lightshot a screenshot tool Link
    • Azure VPN Client Link

Ich habe auch nach etwas wie Zoomit gesucht aber leider nicht gefunden. Allerdings gibt es eine Teil-Lösung für den Zoom aus dem System (Accessability)

  • System Settings - Zoom - Finger double tap

Gaming

Auf meinem Windows ist das kein Problem. Ich habe eine Xbox und seit Jahren ein Xbox Ultimate Abo. Meine Kids und ich können so mit eigenem Konto auf der Xbox eine Menge Games nutzen. Das Ultimate Abo unterstützt auch Windows und so nutze ich immer wieder Games aus dem Angebot (Minecraft, Age of Empires und zuletzt Valheim). Auf dem Mac gibt es keines der Angebote lokal. Durch das Xbox Cloud Gaming gibt es die Möglichkeit, die Spiele aus der Cloud zu streamen.

Meine Steam Library ist nicht riesig, aber es sind schon ein paar Games enthalten. Es gibt einige Spiele die automatisch mit einer macOS Version kommen. Ich habe Stelaris und Age of Wonders - Planetfall getestet. Aktuelle im Angebot für 2,49 Euro ist X-Com 2. Es hat funktioniert. Leider sind Spiele wie Counter Strike 2 nicht nativ verfügbar. Auf dem PC spiele ich ab und an Age Of Wonders 4 und genau das Spiel gibt es nicht für macOS.

no age of wonders 4

Auf dem PC kann ich dank einer RTX 4060 eine Menge spiele gute Gewissens kaufen und spielen. Ich mache es selten, aber ein Wechsel auf macOS würde bedeuten, dass ich einige Spiele nicht spielen kann oder neu kaufen muss.

Performance

Ich nutze die Systeme im Business Kontext. Microsoft ist weit gekommen, was das Mac Management angeht, aber es ist offensichtlich, dass auf Windows viel mehr Kontrolle möglich ist. Wir nutzen auf Windows die volle Palette aus dem Security Stack. Überall steckt der Defender drin und passt auf uns auf. Auf keinem meiner Systeme hatte ich aber über die letzten Jahre den Eindruck, dass ich behindert wurde. Meine Development Tasks sind aber alle sehr Windows nah (Azure Function mit C#). Microsoft Teams mit viel Video und vielen Teams war der Performance Killer der letzten Jahre. Nach 3 Wochen und am Ende mit einem Low Tier Apple MacBook Air 13’’ (8 GB RAM, 265 GB Disk für ca 1.300 Euro) bin ich von der Performance beindruckt. Allerding fühlt sich auch das MacBook 13’’ M1 (16 GB) und M3 (16 GB) nicht viel schneller an. Es geht hier um meinen Einsatzzweck ohne Video Editing oder ähnlichen Medien lastigen Aufgaben. Wir nutzen auch auf dem Mac alles, was im Defender und Microsoft Security Stack geht. Meine Kollegen sagen mir aber immer, dass noch längst nicht alle geht. Vielleicht braucht der Mac das auch gar nicht… bekomme ich immer wieder zu hören. Ich sehe hier also keinen klaren Vorteil, was die reine Rechenleistung für meine tägliche Arbeit angeht.

windows and apple racing

Im Bereich Akkuleistung muss ich den Hut ziehen. Alles was man hört ist wahr. Das kleine MacBook Air hat gerade VS Code, Hugo Server, Teams, Outlook, 5 Edgeprofile mit einiges Tabs offen und ich sitze seit 2 Stunden auf der Couch und schreibe den Artikel. Das Gerät ist warm. Aber ich habe noch immer 64% Akku. Mein Dell XPS 15 wäre nach 1 Stunde bei 10%. Wenn ich den Hugo Server stoppe, dann wäre die Laufzeit nochmal länger. Steckdosen sind für Mac User nicht so relevant wie für uns Windows User. Vielleicht wird es mit den neuen Snapdragon X Elite/Pro besser, aber der Mac ist der deutliche Gewinner im Bereich mobile Nutzung.

Resümee

Jedes System hat seine Stärken und Schwächen. Ich nutze nicht nur Windows, sondern bin auch privat im Microsoft und Google Ökosystem verwurzelt, so dass ein Wechsel für mich kein Sinn macht. Bei glueckkanja leben wir schon seit vielen Jahren mit einer großen Zahl an macOS Benutzern. Microsoft 365 und Apple funktionieren zusammen. In meiner Rolle fehlen, dann aktuell noch ein paar Stücke Software, um wirklich wechseln zu können. Ich werde weiter in der Nähe von Steckdosen meine erarbeitete Produktivität genießen und von einer ARM-basierten Revolution im Windows-Lager warten.

Microsoft Loves Apple

Ich hoffe meine Gedanken und Experimente helfen anderen schneller in der Plattform Fuß zu fassen. Ich bin sehr an euren Kommentaren interessiert und an euren Geschichten. Meldet euch doch via Twitter oder LinkedIn.

Holger Schwichtenberg: Neu in .NET 8.0 [28]: Erweiterung für die Deserialisierung von JSON-Objekten

System.Text.Json 8.0 bietet eine neue Einstellung zur Handhabung zusätzlicher Informationen bei der Deserialisierung von JSON in Objekten.

Holger Schwichtenberg: Neu in .NET 8.0 [27]: Konfigurierbare Namenskonventionen in System.Text.Json 8.0

In der JSON-Bibliothek können Entwicklerinnen und Entwickler nun neben CamelCasing auch andere Namenskonventionen wählen.

Golo Roden: Schätzung eines Softwareentwicklers: Ich werde Gärtner

Softwareentwicklung ähnelt mehr der Arbeit im Garten als einer Ingenieurswissenschaft – meint zumindest Chris Aitchison. Was ist an dieser These dran?

Holger Schwichtenberg: Neu in .NET 8.0 [26]: Anpassung der Resilienz im HTTP-Client

Entwicklerinnen und Entwickler können eigene Polly-Pipelines zur Handhabung von Fehlersituationen definieren.

Golo Roden: Meinung: Softwareentwicklung ist keine Kunst

Was sind Softwareentwicklung und Informatik? Kunst oder Ingenieurswissenschaften? Ein Kommentar.

Holger Schwichtenberg: Neu in .NET 8.0 [25]: Resilienz im HTTP-Client

.NET 8.0 enthält die etablierte Bibliothek Polly für Ausfallsicherheit und den Umgang mit temporären Fehlersituationen.

Golo Roden: Ente gut, alles gut? DuckDB ist eine besondere Datenbank

DuckDB ist in Version 1.0 erschienen. Was hat es mit dieser Datenbank auf sich, die einiges anders macht als andere Datenbanken?

Holger Schwichtenberg: Neu in .NET 8.0 [24]: HTTPS-Proxies bei HttpClient

Die Klasse HttpClient bietet seit .NET 8.0 auch Unterstützung für Proxies mit gesicherter Verbindung.

Golo Roden: Künstliche Intelligenz ist unser Untergang

KI spielt eine viel größere Rolle im Alltag, als die meisten Menschen annehmen. Doch sind wir als Gesellschaft wirklich bereit dafür?

Holger Schwichtenberg: Neu in .NET 8.0 [23]: Verbesserungen für ZipFile zur Arbeit mit Dateiarchiven

Die Klasse ZipFile besitzt nun Methoden, um ein ZIP-Archiv aus einem Dateisystemordner zu erstellen und Dateien in einen Zielordner zu entpacken.

Holger Schwichtenberg: Entwickler-Infotag online am 11. Juni 2024 zu .NET 9.0, C# 13.0 und KI

Der eintägige Online-Infotag widmet sich diversen Themen rund um die kommenden Versionen von C# und .NET sowie KI-unterstützte Softwareentwicklung.

Holger Schwichtenberg: Neu in .NET 8.0 [22]: Neues Steuerelement OpenFolderDialog für WPF

Microsoft liefert in .NET 8.0 nach vielen Jahren erstmals wieder ein neues Steuerelement für die Windows Presentation Foundation.

Code-Inside Blog: LLamaSharp: Run a ChatGPT like system on your hardware for dummies

TL;DR summary: Check out the LLamaSharp Quick Start and you will find everything that you need to know

ChatGPT (and all those Microsoft Copilots out there that were build on top of this) is currently the synonym for AI based chat systems. As a dev you can just use the Azure OpenAI Services and integrate this in your app - I blogged about this last year.

The only “downside” is, that you rely on a cloud system, that costs money and you need to trust the overall system and as a tech nerd it is always “cool” to host stuff yourself. Of course, there are a lot of other good reasons why hosting such a system yourself is a good idea, but we just stick with “it is cool” for this blogpost. (There are tons of reasons why this is a stupid idea as well, but we might do it anyway just for fun.)

Is there something for .NET devs?

My AI knowledge is still quite low and I’m more a “.NET backend developer”, so I was looking for an easy solution for my problem and found “LLamaSharp”.

This blogpost and my experiment was inspired by Maarten Balliauws blog post “Running Large Language Models locally – Your own ChatGPT-like AI in C#”, which is already a year old, but still a good intro in this topic.

LLamaSharp

From their GitHub Repo:

LLamaSharp is a cross-platform library to run 🦙LLaMA/LLaVA model (and others) on your local device. Based on llama.cpp, inference with LLamaSharp is efficient on both CPU and GPU. With the higher-level APIs and RAG support, it’s convenient to deploy LLM (Large Language Model) in your application with LLamaSharp.

Be aware: This blogpost is written with LLamaSharp version 0.12.0 - Maartens blogpost is based on version 0.3.0 and the model he was using is not working anymore.

This sounds really good - let’s checkout the quick start

The basic steps are easy: Just add the LLamaSharp and LLamaSharp.Backend.Cpu NuGet package to your project and then search for a model… but where?

The model

From the quick start:

There are two popular format of model file of LLM now, which are PyTorch format (.pth) and Huggingface format (.bin). LLamaSharp uses GGUF format file, which could be converted from these two formats. To get GGUF file, there are two options:

Search model name + ‘gguf’ in Huggingface, you will find lots of model files that have already been converted to GGUF format. Please take care of the publishing time of them because some old ones could only work with old version of LLamaSharp.

Convert PyTorch or Huggingface format to GGUF format yourself. Please follow the instructions of this part of llama.cpp readme to convert them with the python scripts.

Generally, we recommend downloading models with quantization rather than fp16, because it significantly reduce the required memory size while only slightly impact on its generation quality.

Okay… I ended up using the huggingface-search-approach and picked the Phi-3-mini-4k-instruct-gguf, because I heard about it somewhere.

Code

After the initial search and download I could just copy/paste the quick start code in my project and hit run:

using LLama.Common;
using LLama;

string modelPath = @"C:\temp\Phi-3-mini-4k-instruct-q4.gguf"; // change it to your own model path.

var parameters = new ModelParams(modelPath)
{
    ContextSize = 1024, // The longest length of chat as memory.
    GpuLayerCount = 2 // How many layers to offload to GPU. Please adjust it according to your GPU memory.
};
using var model = LLamaWeights.LoadFromFile(parameters);
using var context = model.CreateContext(parameters);
var executor = new InteractiveExecutor(context);

// Add chat histories as prompt to tell AI how to act.
var chatHistory = new ChatHistory();
chatHistory.AddMessage(AuthorRole.System, "Transcript of a dialog, where the User interacts with an Assistant named Bob. Bob is helpful, kind, honest, good at writing, and never fails to answer the User's requests immediately and with precision.");
chatHistory.AddMessage(AuthorRole.User, "Hello, Bob.");
chatHistory.AddMessage(AuthorRole.Assistant, "Hello. How may I help you today?");

ChatSession session = new(executor, chatHistory);

InferenceParams inferenceParams = new InferenceParams()
{
    MaxTokens = 256, // No more than 256 tokens should appear in answer. Remove it if antiprompt is enough for control.
    AntiPrompts = new List<string> { "User:" } // Stop generation once antiprompts appear.
};

Console.ForegroundColor = ConsoleColor.Yellow;
Console.Write("The chat session has started.\nUser: ");
Console.ForegroundColor = ConsoleColor.Green;
string userInput = Console.ReadLine() ?? "";

while (userInput != "exit")
{
    await foreach ( // Generate the response streamingly.
        var text
        in session.ChatAsync(
            new ChatHistory.Message(AuthorRole.User, userInput),
            inferenceParams))
    {
        Console.ForegroundColor = ConsoleColor.White;
        Console.Write(text);
    }
    Console.ForegroundColor = ConsoleColor.Green;
    userInput = Console.ReadLine() ?? "";
}

The result is a “ChatGPT-like” chat bot (maybe not so smart, but it runs quick ok-ish on my Dell notebook:

x

Summary

After some research which model can be used with LLamaSharp it went really smoothly (even for a .NET dummy like me).

Hope this helps!

Holger Schwichtenberg: Neu in .NET 8.0 [21]: Neue Code-Analyzer für ASP.NET Core

ASP.NET Core 8.0 führt Code-Analyzer ein, die vor potenziellen Fehlern warnen und Best Practices empfehlen.

Holger Schwichtenberg: Neu in .NET 8.0 [20]: Neue Code-Analyzer für .NET-Basisklassen

Die zusätzlichen Code-Analyzer bieten Verbesserungsvorschläge bei der Verwendung der .NET-Klassenbibliothek.

Holger Schwichtenberg: Neues Fachbuch: ".NET 8.0 Update" erklärt die Neuerungen gegenüber .NET 7.0

Das neue, kompakte Werk des DOTNET-DOKTORs zu .NET 8.0 richtet sich an Umsteigerinnen und Umsteiger von .NET 7.0.

Holger Schwichtenberg: Neu in .NET 8.0 [19]: Razor-HTML-Rendering in beliebigen .NET-Anwendungen

Das HTML-Rendern mit Razor-Komponenten ist in .NET 8.0 auch außerhalb von Blazor-Anwendungen möglich, beispielsweise für HTML-formatierte E-Mails.

Holger Schwichtenberg: Neu in .NET 8.0 [18]: Ein Zeitraffer mit eigenem FakeTimeProvider

Auf Basis der Klasse TimeProvider kann man sich in .NET 8.0 einen eigenen TimeProvider erstellen, der in Tests Uhrzeiten vorgaukelt.

Holger Schwichtenberg: Neu in .NET 8.0 [17]: Zeitabstraktion für Tests mit Zeitangaben

In .NET 8.0 existiert mit der abstrakten Klasse TimeProvider ein einfacher Weg, Zeitangaben inklusive Zeitzone beliebig im Rahmen von Tests vorzutäuschen.

Don't contact us via this (fleischfalle@alphasierrapapa.com) email address.