Abou Chleih

{the magic lies between the brackets}

Menü Schließen

ASP.NET Core App via Apache bereitstellen #2 – Konfiguration Apache

Um eine weitere Apache Instanz zu erstellen, gibt es bereits ein Skript, welches einem einige Arbeit abnimmt.
Die grundsätzliche Idee dahinter ist jedoch einfach: Man kopiert die originale Instanz (apache2) , also Konfigurationsdateien, Binaries, etc. in einen zweiten Ordner (apache2-xxx).

Je nach System findet sich das Skript in
/usr/share/doc/apache2.2-common/examples/setup-instance xxx
oder
/usr/share/doc/apache2/examples/setup-instance xxx

xxx ist hierbei der Name der Instanz, die erstellt werden soll: /usr/share/doc/apache2/examples/setup-instance netcore

Dies erstellt also die entsprechenden Verzeichnis und Dateien /etc/apache2-netcore, /etc/logrotate.d/apache2-netcore, /var/log/apache2-netcore sowie das Init-Skript für den Boot /etc/init.d/apache2-netcore.

Um die entsprechenden Links zu aktivieren, also apache2-netcore als Service verfügbar zu machen. Führen wir nun ein update-rc.d apache2-netcore defaults aus.
Dies verlinkt die executables in /etc/rcX.d/, also dem entsprechenden Runlevel für den Boot Prozess.

Nun können wir den Service mit init.d oder service starten: /etc/init.d/apache2-netcore start oder service apache2-netcore start

Nun können wir uns an die Konfiguration de Apache2 Instanz NetCore machen. Dazu navigieren wir ins Verzeichnis /etc/apache2-netcore/sites-available/ und bearbeiten das file 000-default.conf (HTTP) oder default-ssl.conf (HTTPS).

Diese Dateien haben folgenden Aufbau (in diesem Beispiel hört die ASP.NET Core Application auf localhost:5000):

<VirtualHost *:8080>
     ServerName sub.mydomain.com 
     ErrorLog ${APACHE_LOG_DIR}/errorNetCore.log 
     CustomLog ${APACHE_LOG_DIR}/accessNetCore.log combined 
     ProxyPass / http://localhost:5000/ 
     ProxyPassReverse / http://localhost:5000/ 
     ProxyPreserveHost On
</VirtualHost>

ServerName: Hört auf Aufruf von sub.mydomain.com
ErrorLog: Schreibt Error Log in entsprechendes File, (Apache bspw. PHP Fehler kommen hier rein)
CustomLog: Schreibt alle Aufrufe in File (=AccessLog Config)
ProxyPass: Forward Proxy Config, leitet alle Anfragen von http://sub.mydomain.com:8080/ an http://localhost:5000/ weiter
/ steht hier für das Top Directory, ProxyPass /sub/ http://localhost:5000/ würde bspw. http://sub.mydomain.com:8080/sub/ an http://localhost:5000/ weiterleiten
ProxyPassReverse: Reverse Proxy, leitet Response um. Schreibt alle Urls in der Rückantwort um, bspw. sollte http://localhost:5000 zu http://sub.mydomain.com:8080 umgeschrieben werden.
ProxyPreserveHost: Header bleibt erhalten

Nun speichern wir die Seite und aktivieren sie mit a2ensite sub.mydomain.com und starten die Instanz neu service apache2-netcore restart.

Anschließend starten wir die ASP.NET Core Applikation: dotnet PFADZURDLL

ASP.NET Core App via Apache bereitstellen #1 – Compiling & Vorbereitung

Mit .NET Core ist es seit einiger Zeit problemlos möglich cross-plattform Applikationen zu erstellen.
Darunter fallen auch ASP.NET Core Web-Anwendungen.
Um diese Anwendungen allerdings allgemein bereitzustellen, müssen wir diese zuerst für den allgemeinen Zugriff aus dem Internet freigeben.
Dies geschieht auf Grund der Plattformunabhängigkeit natürlich ohne Microsoft IIS. In diesem Beispiel wird ein Apache2 Webserver in der Standardkonfiguration genutzt.
Voraussetzung sind daher ein installierter Server mit funktionaler Apache2 Installation und natürlich eine ASP.NET Core Anwendung.

Was werden wir hier nun genau machen?

  • Compilen der ASP.NET Core Anwendung
  • Konfigurieren einer eigenen Apache Instanz, die als Reverse Proxy fungiert
  • Bereitstellen der Applikation

Um die ASP.NET Anwendung bereitzustellen, müssen wir diese zuerst compilen, dies mache ich bevorzugt auf meiner Entwicklungsmaschine (hier: Windows).
Wir gehen als in das Projektverzeichnis ({Solutionpath}\src\{Projectpath}) und öffnen dort eine Kommandozeile oder PowerShell.

Mit dem Befehl dotnet publish -c Release (-c = –configuration) starten wir nun den Build Prozess (im Release Modus).
Sollten nun Fehler kommen, dass „bower“ nicht gefunden werden kann, so kann dies an zwei Dingen liegen.

  • Bower nicht installiert
  • Path-Variable nicht korrekt

Um Bower zu installieren, geben wir in der PowerShell einfach npm install bower ein, das entsprechende Node.js Projekt wird dann geladen und installiert.
Anschließend installieren wir noch Gulp via npm install gulp, eine weitere Abhängigkeit.

Sollte der Fehler immer noch erscheinen, so müssen wir die Path-Variable auf das Web Verzeichnis unserer Visual Studio Installation verweisen lassen:
PowerShell: $env:path = $env:path + ";C:\Program Files (x86)\Microsoft Visual Studio 14.0\Web\External"
Die VS Version entsprechend anpassen (hier: VS 2015).

Nun sollte das Projekt compilen und die lauffähige Version unter {Solutionpath}\src\{Projectpath}\bin\Release zu finden sein.

Diesen Ordner jetzt auf den Linux Server laden.

Um die Applikation jetzt ausführen zu können, benötigen wir die .NET Core Runtime auf dem Server (hier: Debian).
Um diese zu installieren, laden wir uns das Archiv (tar.gz) herunter und entpacken es:
Die Befehle dazu finden sich auf der entsprechenden Microsoft-Website:

Für v1.0.3:
sudo apt-get install curl libunwind8 gettext
curl -sSL -o dotnet.tar.gz https://go.microsoft.com/fwlink/?linkid=847105
sudo mkdir -p /opt/dotnet && sudo tar zxf dotnet.tar.gz -C /opt/dotnet
sudo ln -s /opt/dotnet/dotnet /usr/local/bin

Für v2.0.0:
deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-ubuntu-trusty-prod trusty main" > /etc/apt/sources.list.d/dotnetdev.list
apt-get update
apt-get install dotnet-sdk-2.0.0

Anschließend sollte man das Projekt starten können, zum Testen reicht hier: dotnet {Projektname}.dll im Pfad {App}\publish\.

Windows 10 – DVD Laufwerk wird nicht erkannt

Eigentlich braucht man – oder zumindest ich – kein DVD Laufwerk mehr. Da ich aber noch eines in einer verstaubten Schachtel fand und es nicht entsorgen wollte, ist es direkt in meinen PC gewandert.
Leider wurde das Gerät nicht von Windows erkannt.
„Alles klar“, dachte ich. Führe ich eben im Geräte-Manager eine manuelle Suche durch. Gesagt, getan – keine Änderung.
Anschließend überprüfte ich alle Kabel und Anschlüsse. Auch hier war es korrekt angeschlossen, ebenso wird es im UEFI System Browser meines Motherboards erkannt.

Das Problem liegt also bei Windows. Und da es schon einige Personen mit ähnlichen Problemen gibt, dachte sich Microsoft wohl, dass ein Support Eintrag angebracht ist.

Diesen arbeitete ich ab, jedoch funktionierte bei mir nur Resolution 5 des Eintrags.

Also wie löste ich das Problem? 

Wir gehen in die Registry per Registry Editor (Win+R und regedit) und navigieren zum Pfad HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\atapi.
Hier erstellen wir einen neuen Schlüssel (Ordner) Controller0 (ist eine Null) per Rechtsklick auf den Schlüssel atapi.
Anschließend navigieren wir in den Schlüssel und erstellen dort ein DWort mit 32-bit Länge:
Name: EnumDevice1
Wert: 1

Schlussendlich starten wir den Rechner einmal neu, das Laufwerk wird dann ordnungsgemäß erkannt.

Signieren von Visual Studio for Office Add-Ins (autom. Installation)

Bei normalen Windows Desktop oder Windows Phone Applikationen ist ein Signieren der Applikation nicht dringend nötig bzw. nur wenn die Herkunft des Executables verifiziert werden soll um lästige Abfragen zu vermeiden.
Auch bei sogenannten Visual Studio for Office Add-Ins (kurs: vsto) ist dies normalerweise nicht erforderlich.
Es sei denn, man will die Add-Ins nicht manuell per Registry Eintrag oder Bestätigungdialogen installieren, sondern automatisiert.
Egal welchen Fall man bevorzugt, man benötigt zu allererst die Visual Studio for Office Runtime (VSTOR).

Nach der Installation können wir nun mit einem Doppelklick auf die .vsto-Datei das Add-In installieren, allerdings bisher nur mit folgender Warnung:
warn_install_addin

Bei einer Automatisierung des Installationsprozesses soll dies nicht mehr passieren und der Prozess insgesamt im Hintergrund ausgeführt werden (silent install).
Dies funktioniert mit Hilfe der VSTOR – siehe Link oben – und der darin enthaltenen VSTOInstaller.exe.
Diese befindet sich nach der Installation im Verzeichnis C:\Program Files (x86)\Common Files\Microsoft Shared\VSTO\10.0.

Ein Start des Programms gibt uns direkt alle verfügbaren Parameter zurück (Ein Doppelklick auf eine ,vsto-Datei ruft übrigens auch nur dieses Programm mit dem Parameter /i <.vsto-Pfad> auf)

VSTOInstaller.exe [[/install <URL> ] | [/uninstall <URL>]] [/silent] [/help]

/install, /i: Projektmappe installieren. Nach dieser Option muss der vollqualifizierte Pfad eines Bereitstellungsmanifests im Format „http://“, „https://“ oder „\\Servername\Ordnername“ angegeben werden.

/uninstall, /u: Projektmappe deinstallieren. Nach dieser Option muss der vollqualifizierte Pfad eines Bereitstellungsmanifests im Format „http://“, „https://“ oder „\\Servername\Ordnername“ angegeben werden.

/silent, /s: Ohne Eingabeaufforderungen oder Informationseingaben installieren oder deinstallieren.

Nun wissen wir, dass der Aufruf für unsere Add-In Installation wie folgt aussehen muss:
VSTOInstaller.exe /i "<PFADZURVSTODATEI>" /s

Führen wir dies nun aus, werden wir merken, dass das Add-In nicht installiert ist.
Der Grund ist ganz einfach: Eine silent Installation lässt sich nur durchführen, wenn das Programm/Add-In mit einem validen Zertifikat signiert ist.

Natürlich könnten wir uns jetzt für viel Geld ein ordentliches Zertifikat von einer Authority kaufen, allerdings kostet das viel Zeit und Geld.
Zumal wir unsere Software meist nicht verkaufen, sondern nur intern nutzen.

Lösung: Eigenes Zertifikat mit Kette

Was braucht man für ein valides Zertifikat?

  • Eine gültige Certificate Chain, zu deutsch: Zertifikatskette, kurz: eine höherwertige Zertifizierungsstelle (Authority) muss das Zertifikat des Clients bestätigen.
  • Eine .pfx-Datei, mit welcher wir das Visual Studio Projekt signieren
  • Eine GPO, mit der wir die Zertifikate in unserem Netzwerk bekannt machen (wir selbst sind schließlich keine zertifizierte Authority, sonst könnten wir ja einfach Zertifikate von google.de erstellen und uns dafür ausgeben 😉 )

Fangen wir also an.
Wir müssen ein Zertifikat erstellen – für eine Authority (wir fangen ganz oben in der Hierarchie an).
Was wir benötigen, ist also ein Programm, welches uns Zertifikate erstellt: MakeCert.exe – Documentation/Parameter Specification

Dieses Programm finden wir abhängig von der Visual Studio Version und den SDKs in einem der folgenden Pfade:

  • C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\makecert.exe
  • C:\Program Files (x86)\Windows Kits\8.0\bin\x86\makecert.exe

Wenn man sich die Dokumentation des Tools durchliest, kann man schnell entdecken, wohin die Reise nun geht:

makecert
-n "CN=MeinAuthorityName" #CN= muss immer voranstehen; specifies a name for the certificate.
-cy authority #Defines Certificate type (here: authority)
-a sha1 #Hash algorithm
-sv "MeinPrivateKeyFileFuerDieAuthority.pvk" #Name of the subject's .pvk file. Wird erstellt, wenn nicht vorhanden
-r "MeinAuthorityZertifikat.cer" #Creates a self-signed certificate.

Nun werden wir aufgefordert ein Passwort für das Private Key File zu erstellen (dies sollte ein kompliziertes Passwort sein).

Nun haben wir folgende Dateien:

  • MeinPrivateKeyFileFuerDieAuthority.pvk
  • MeinAuthorityZertifikat.cer

Diese benötigen wir nun, um ein Client Zertifikat zu erstellen, welches von unserer Authority ausgestellt ist (Chain).

makecert 
-n "CN=MeinClientZertifikatName" #specifies name of certificate
-ic "MeinAuthorityZertifikat.cer" #Location of the issuers certificate.
-iv "MeinPrivateKeyFileFuerDieAuthority.pvk" #Issuers (Aussteller = Authority) private key file.
-a sha1 #Hash algorithm
-sky exchange #Für Zertifikate nutzt man exchange (KeyExchange)
-pe #Marks the private key as exportable.
-sv "MeinPrivateKeyFileFuerDasClientZertifikat.pvk" #Erstellt ein .pvk file, falls nicht vorhanden für das Client Zertifikat &nbsp; 
"MeinClientZertifikat.cer" #Erstellt das Zertifikat mit angegebenem Namen

Nun werden wir entsprechend aufgefordert die Passwörter für das Authority Key File einzugeben, das Kennwort für das ClientZertifikatKeyFile zu definieren.
Als Ergebnis haben wir nun unser Client Zertifikat mit Private Key file.

  • MeinPrivateKeyFileFuerDasClientZertifikat.pvk
  • MeinClientZertifikat.cer

Die Zertifikatskette ist nun komplett, fehlt noch das .pfx File.

Um unsere Zertifikate in das .pfx Format zu konvertieren, bietet uns Microsoft ein Tool namens pvk2pfx.exe  an.

pvk2pfx.exe 
-pvk MeinPrivateKeyFileFuerDasClientZertifikat.pvk #Verweis auf das Private Key File des Clients
-spc MeinClientZertifikat.cer #Verweis auf das Cleint Zertifikat
-pfx MeinPfxZertifikat.pfx #Erstellt ein .pfx File 
-pi PasswortDesPrivateKeyFiles #Optional! Dialog kann ebenfalls genutzt werden 

Nun haben wir unser .pfx-File mit dem wir unsere Visual Studio Projekt signieren können.
Dazu einfach in das entsprechende

 Projekt -> Rechtsklick -> Eigenschaften -> Signierung -> Aus Datei wählen

und das entsprechende Zertifikat (.pfx) auswählen.

Signierung_VisualStudio

Nun müssen wir die Zertifikate und damit die Kette noch per GPO bekannt/valide machen.
Dies ist aber ein Thema für einen anderen Tag.

Check_MK Überwachungs-Skript für EMC VNXe Maschinen (Unisphere CLI)

Zur Überwachung von VNXe Storage Systemen (NAS) innerhalb von Check_MK gab es keine ordentlichen Funktionen.
Im Netz findet man auch nicht viel zu diesem Thema.
Allerdings bieten die VNXe Systeme eine Remote Möglichkeit zur Konfiguration via Shell, die sog. Unisphere CLI; kurz: UEMCLI.
Diese wird für die verschiedensten Systeme angeboten, allerdings für Linux Systeme nur in Form ein .rpm Datei (Red Hat Package).
Auf Debian Systemen steht man jetzt etwas blöd da, also konvertierte ich das Paket mit alien in das .deb Format.

faviconunispherecli-linux-64-x86-en-us_3.0.0.1.16-2_amd64.deb

Nach der Installation finden sich die Binaries der uemcli im Pfad /opt/emc/uemcli/bin.

vnxe_check

Das Skript, welches wir in Check_MK aufrufen werden, müssen wir nun in einen für den Check_MK user verfügbaren Pfad packen (hier: /opt/omd/sites/monitor/local/share/check_mk) und via chmod -x ausführbar machen. Die Rechte müssen evtl. auch angepasst werden.
Im Anschluss können wir einen Legacy oder Classical Check in Check_MK anlegen, welcher das Programm ausführt.
Davor allerdings noch die Security Level der UEMCLI via /opt/emc/uemcli/bin/setlevel.sh -l auf low setzen, damit die Zertifikate nicht mehr manuell akzeptiert werden müssen.

Nun können wir das Programm mit folgendem Befehl ausführen: /opt/omd/sites/monitor/local/share/check_mk/vnxe_check <HOST> <USER> <PW> <PATH> <COL> <OPTIONAL REGEX>
Es gibt die entsprechenden Codes zurück. Die Fehlercodes von Degraded/Minor failure/Major failure werden als CRITICAL angezeigt (Returnvalue 1), bei einem Programmfehler oder leerer Response (timeout) wird UNKNOWN zurückgegeben (Returnvalue 2), bei einem Fehlercode OK_BUT wird WARNING angezeigt (Returnvalue 2)

First parameter: IP/Domainname
Second parameter: username and domain in the following structure: <DOMAIN>/<USER>
Third parameter: password
Fourth parameter: directory or file which is queried (see manual inside the bash file)
Fifth parameter: column index of health status (see manual inside the bash file)
Sixth parameter is optional: grep filter which looks for the beginning of a line and returns the whole line  | grep \“.*$6.*\“

Der letzte Parameter wird von mir verwendet, um einzelne Geräte innerhalb eines Arrays anzusprechen, bspw. eine einzelne Platte im Disk Array

Observer Pattern (Beobachter-Muster) in Java und C#

Wie benachrichtige ich mehrere Clients möglichst ohne Zeitverlust und ohne das Rad neu zu erfinden?
Eine weitverbreitete Möglichkeit ist das Observer Pattern (und erweitert, das Subscriber Pattern).
Es ist push-basiert, der Beobachtete gibt also allen Beobachtern Bescheid, was eine Benachrichtigung an die Beobachter in kürzester Zeit ermöglicht.

ObserverPattern

Was wir in Java dafür brauchen sind folgende Klassen und Interfaces, welche wir im Code referenzieren. In C# gibt es keine äquivalenten Klassen, wir müssen etwas selber schreiben.

Java
import java.util.Observable;
import java.util.Observer;

Erstellen wir nun die Klasse, welche später beobachtet werden soll.
In C# nutzen wir EventHandler für eine asynchrone Benachrichtigung:

JavaC#
public class Beobachteter extends Observable
public class Observable
	{
		private bool changed;
		event EventHandler notifier;
		
		public void addObserver(Observer obs)
		{
			notifier += obs.update;
		}
	
		private void notifyObservers(dynamic obj)
		{
			if (this.changed) {
				if(notifier != null)
					 notifier(obj, EventArgs.Empty);
			}
			this.changed = false;
		}
		
		public void setChanged()
		{
			this.changed = true;
		}
		
		public void doIt(){
			setChanged();
			notifyObservers(32123);
		}
		
	}

Wir lassen unseren Beobachteten die Klasse Observable im Namespace java.util.* erben. (Siehe oben)
Dadurch bekommt die Klasse u.A. folgende Methode vererbt, welche wir im Folgenden nutzen:

JavaC#
public void AddObserver(){
       Beobachteter.addObserver(Observer o);
}
 Durch die eigene Implementierung, stehen uns die identischen Methoden zur Verfügung. 

Wie man auf dem Bild sieht, muss man nun die Beobachter (Observer) einem Beobachtbaren (Observable) hinzufügen, im Folgenden nenne ich diesen dann Beobachteten.
Wir erstellen verschiedene Beobachter und fügen diese nun einem Objekt der Klasse Beobachteter zu, welche – der Einfachheit halber – direkt in den Beobachtern erstellt wird.
Die Beobachter implementieren das Interface von java.util.Observer.

JavaC#
public class Beobachter implements Observer{
    public Beobachter(){
         Beobachteter observable = new Beobachteter();
         observable.addObserver(this); //fügt dem Beobachteten mich als Beobachter hinzu.
    }
}
 	public class Observer
	{
		string name;
		
		public Observer()
		{
		}
		
		public Observer(string name){
			this.name = name;
		}
	
		public void update(object message, EventArgs args){
			//Console.WriteLine(this + "received: "+message+obs);
		}
		
		public override string ToString()
		{
			return "{Observer,"+this.name+"}";
		} 
	}

Nun haben wir einen oder mehrere Beobachter und einen Beobachteten.
Wie lassen wir die Beobachter nun wissen, wenn sich etwas ändert?
Die Klasse Observable bietet hier einige passende Methoden. Ich fokussiere mich hier allerdings auf folgende zwei:

JavaC#
 setChanged(); 
 notifyObservers(message);
setChanged();  
notifyObservers(message);

Durch das dynamic keyword können wir dem EventHandler „notifier“ jegliche Daten als Parameter durchreichen, diese Implementierung vereinfacht das Handling der Daten extrem.

setChanged() ist von Nöten, da ein Beobachter auch nur benachrichtigt wird, wenn sich auch etwas geändert hat.
In Java ist es zudem sehr praktisch, dass man jede Art von Daten in der Methode

notifyObservers();

versenden kann. Mit dieser werden die Beobachter auch benachrichtigt.

Im Java Observer wird nun die Methode

update(Observable _ob, Object message)

, welche wir durch das Interface implementierten, ausgeführt.
In C# rufen der EventHandler die Observer-Methode

 update(dynamic message, EventArgs empty) 

aus.

Im Anhang befindet sich das C# Test Projekt, als .sln Solution:
ObserverPattern

Intel I218-LM Treiber für Windows PE in Enteo DSM (HP 840 G2)

Windows 8 ist in den meisten Betrieben noch nicht sehr verbreitet. Ultrabooks werden dennoch meist mit diesem OS und bald auch mit Windows 10 ausgeliefert.
Um einen neuen Rechner in Enteo DSM zu betanken, importiert man alle Treiber vom Laptop (hier: HP Ultrabook 840 G2) in die Enteo DSM Umgebung.
Es werden automatisch die aktuellen Treiber als Driver Package erstellt.
Leider gibt es hier einige Probleme mit der Boot Environment, welche auf WinPE 3.x und 4.x basiert.
Die Treiber sind nicht kompatibel und so können entsprechende Pakete von der Boot Environment nicht mehr aus dem Netzwerk geladen werden.
Auf der Suche nach den passenden Treibern, findet man viele User mit gleichen Problemen, allerdings sind die dortig verlinkten Websites meist nicht mehr verfügbar.
Die Lösung für WinPE 3.0 x64 ist hier wie folgt:

Für x32 Boot Environments sollte man einfach in den x64 durch x32 ersetzen, das sollte dann ebenso funktionieren!

Die passenden Treiber bekommt man in einer Intel I218-LM Treibersammlung von Intel.
Hier entpackt man zuerst das Paket und navigiert in den Ordner PRO1000\Winx64\NDIS63. Dort findet man nun eine Sammlung versch. Treiber für die Netzwerkkarten.
Anhand der .inf-Dateien kann man den passenden Treiber finden. Im Fall des HP 840 G2 Ultrabooks lautet die ID der NIC VEN_8086&DEV_15A2&SUBSYS_2216103C.
Der wichtige Teil ist hier die DEV-ID, also die 15A2.
In den .inf-Dateien finden wir nun versch. IDs und suchen nach folgendem Part:

%E15A2NC.DeviceDesc% = E15A2.6.2.1, PCI\VEN_8086&DEV_15A2
%E15A2NC.DeviceDesc% = E15A2.6.2.1, PCI\VEN_8086&DEV_15A2&SUBSYS_00008086
%E15A2NC.DeviceDesc% = E15A2.6.2.1, PCI\VEN_8086&DEV_15A2&SUBSYS_00011179

Quelle: e1d63x64.inf

Wie die Quelle vermuten lässt, ist die Datei die e1d63x64.inf. Nun haben wir den passenden Treiber.
Da Enteo bereits ein passendes Driver Package erstellt hat, legen wir eine neue Revision dessen an und löschen die alten Treiber aus Extern$/drv/{XY…..-….-….-ABCD}.
Nun kopieren wir den Treiber in den Ordner.
Anschließend müssen wir noch die projconf.inf anpassen, welche in Extern$/drv/ liegt. Enteo beschreibt hier die benötigten Treiber. Die Werte passen aber nicht mehr!

;Please do not edit anything manually in this luxurious file.

[Version] Signature=“$Windows NT$“

[Hardware IDs] PCI\VEN_8086&DEV_15A2&SUBSYS_2216103C

[PCI\VEN_8086&DEV_15A2&SUBSYS_2216103C] File=drv\{XY….-…-…-ABCD}\e1d63x64.inf
Friendly=“Intel(R) Ethernet Connection (3) I218-LM“

Nun das Paket neu distributen, in die Boot Environment aufnehmen und verteilen lassen. Der Treiber wird dann automatisch von Enteo geladen.

[C#] Transponieren einer Matrix

Eine Matrix wird transponiert indem man ihre Spalten gegen ihre Zeilen tauscht.
Eine Matrix A der Ordnung 3×2 wird somit eine Matrix ATrans mit der Ordnung 2×3

Die allgemeine Definition lautet:
Für die Matrix A

Quelle: Wikipedia

ist die transponierte Matrix AT definiert als

Quelle: Wikipedia

Somit ergäbe sich für folgende Matrix A mit der Ordnung 2 Zeilen x 3 Spalten

Matrix_A_2R3C_123_456

die folgende transponierte Matrix AT mit der Ordnung 3 Zeilen x 2 Spalten

Matrix_ATrans_3R2C_14_25_36

Die Umsetzung des Transponierens lässt sich in C# mit folgendem Code bewerkstelligen,

int m, n;
Console.Write("Ordnung der Matrix angeben: \r\n");
Console.Write("Zeilen: ");
m = Convert.ToInt16(Console.ReadLine());
Console.Write("Spalten: ");
n = Convert.ToInt16(Console.ReadLine());
int[,] A = new int[m, n];
int[,] Atrans = new int[n, m];

Console.Write("Elemente der Matrix eingeben: ");
for (int i = 0; i < m; i++)
{
	for (int j = 0; j < n; j++)
	{
		A[i, j] = Convert.ToInt16(Console.ReadLine());
	}
}

Console.WriteLine("\nMatrix A: ");
for (int i = 0; i < m; i++)
{
	for (int j = 0; j < n; j++)
	{
		Console.Write(A[i, j] + "\t");
		Atrans[j, i] = A[i, j];
	}
	Console.WriteLine();
}

Console.WriteLine("Transponierte (ATrans) Matrix : ");
for (int i = 0; i < n; i++)
{
	for (int j = 0; j < m; j++)
	{
		Console.Write(Atrans[i, j] + "\t");
	}
	Console.WriteLine();
}
Console.Read();

Programmiertechnisch Windows Forms-Anwendungen erstellen

In C# gibt es verschiedene Techniken, GUIs zu erzeugen:

  • winforms
  • wpf

In Windows Forms (kurz meist winforms) ist das relativ einfach, da man hier komplett in C# arbeiten muss und nicht im „Backend-Code“ (C#) und im „Frontend-Code“ (XAML), wie in WPF.

Zu Beginn müssen wir zuerst einen Frame (hier: Form), der alle Controls (Textboxen, Labels, etc.) hält, erstellen und soweit vorbereiten.
Dazu legen wir eine Klasse MyForm an, welche von Form erbt:

 public partial class MyForm:Form 

Nun müssen wir noch die Attribute, wie bspw. Größe und Art des Rahmens anpassen. Dazu greifen wir auf die Properties der Klasse zu und setzen diese:

this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; //Setzt den Rahmen auf einen nicht vergrößerbaren, schmalen Rahmen ohne Min./Max-Boxen
this.ClientSize = new Size(Breite, Höhe);
this.Name = "Meine Form"; //Setzt den Namen der Form
this.ResumeLayout(false); //Unterdrückt Änderungen an der GUI
this.PerformLayout(); //Lässt Änderungen an der GUI zu und lädt diese 

Nun erstellen wir ein Objekt dieser Form:

 MyForm myFrmObj = new MyForm(); 

Um jetzt Controls (hier werden wir eine Textbox hinzufügen) zur Form hinzuzufügen, müssen wir ein Objekt dieses Controls erstellen:

 TextBox txtContent = new TextBox(); 

Anschließend greifen wir wieder auf die Attribute zu und ändern diese zu unseren Wünschen ab.

 txtContent.Size = new Size(Width, Height);
txtContent.Location = new Point(X,Y); 

Achtung die Position (Location) ist relativ, d.h. X = 0, Y = 0 sind im linken oberen Eck der Form, nicht des Bildschirms.

Nun fügen wir das Control zu unserer Form hinzu:

myFrmObj.Controls.Add(txtContent);

Natürlich kann man auch andere Attribute setzen, hier verweise ich auf das MSDN von Microsoft, in dem die Attribute von Klassen erklärt sind.
Aber auch IntelliSense hilft hier weiter.

Was jetzt noch wichtig ist, ist die Option

txtContent.AutoSize = true;

. Diese lässt Controls automatisch abhängig vom Content wachsen.

Um nun noch Events hinzuzufügen, erstellen wir die entsprechende Methode private void myMethod(object sender, EventArgs e) und fügen den Handler diesem Event zu:

this.txtContent.Click += new System.EventHandler(this.myMethod);

Zu guter letzt muss man die Controls beim Aufruf der Form initialisieren lassen, sodass man Zugriff während der Laufzeit bekommt.
Hierzu fügt man im Konstruktor der Form den Befehl InitializeComponent(); ein:

public MyForm()
{
     InitializeComponent();
}

Mehr Informationen zum Handlern und Events findet man im MSDN.

Generelle Infos findet man auf der Supportseite von Microsoft.

© 2018 Abou Chleih. Alle Rechte vorbehalten.

Thema von Anders Norén.