Montag, 20. April 2015

Ping: Blockade durch Windows-Firewall aufheben

Es kann unter Umständen vorkommen, dass Pings an einen Rechner im lokalen Netzwerk mit einem Timeout enden, obwohl es keine weiteren offensichtlichen Probleme gibt diesen zu erreichen. Auch kann er andersherum selbst andere Rechner problemlos anpingen und hat auch sonst keine weiteren Netzwerkprobleme.
Die Vermutung, dass die Windows-Firewall eingehende Echo-Anfragen blockiert liegt einerseits nahe, klingt andererseits aber auch sehr unwahrscheinlich, wenn man vermeintlich keine Einstellungen an der Firewall geändert hat. Leider ist dies aber der Fall und hier eine kurze Anleitung zur Aufhebung dieser Blockade (gilt nur für die Windows-Firewall):
  1. Systemsteuerung öffnen und zu "Windows-Firewall" wechseln
  2. "Erweiterte Einstellungen" öffnen und auf "Eingehende Regeln" klicken
  3. Nach "Datei- und Druckerfreigabe (Echoanforderung - ICMPv4 eingehend)" suchen und die Regel aktivieren
Ist die Regel aktiviert und es kommt trotzdem zu oben genannten Timeouts, so liegt das Problem wohl leider an anderer Stelle. Bei zusätzlich installierten Firewalls wird die Regel vermutlich einen anderen Namen haben, falls sie überhaupt existiert.
Wie man am Namen der Regel schon erahnen kann, ist die Ursache für die Deaktivierung der Regel die Einstellung "Datei- und Druckerfreigabe" in den erweiterten Freigabeeinstellungen im "Netzwerk- und Freigabecenter". Auch wenn es aus dem Namen und der Beschreibung nicht ersichtlich ist, haben die Einstellungen  teilweise offensichtlich größere Nebeneffekte, als man erwarten würde.

Dienstag, 14. April 2015

Kurzanleitung: Boost installieren

Um nicht Zehntausende an Dateien auf dem Repository zu haben, muss jeder die Boost Bibliotheken bei sich selbst unter dem Standardpfad installieren, um möglichst wenig Anpassungen machen zu müssen.
Hier daher kurz die wichtigsten Infos:

Boost Hompage: http://www.boost.org/

Download: http://sourceforge.net/projects/boost/files/boost-binaries/1.57.0/
    -> 64-bit: boost_1_57_0-msvc-12.0-64.exe

Installation: Alles auf Standardeinstellungen lassen und einfach durchklicken
    -> Installationspfad: sollte "C:\local\boost_1_57_0" sein


Falls auf C zu wenig Platz ist oder ihr Boost aus anderen Gründen an einem anderen Ort installieren , aber nicht die Projekteinstellungen anpassen wollt, hier eine kleine Abhilfe:
  1. Boost an beliebigen Ort installieren
  2. Ordner "C:\local" anlegen
  3. Konsole in "C:\local" öffnen (Shift+Rechtsklick -> Eingabeaufforderung hier öffnen)
  4. Ordnerverknüpfung anlegen: mklink /j boost_1_57_0 <Pfad zu Boostordner>

Donnerstag, 9. April 2015

Konsole für Win32 GUI Anwendungen

Anwendungen mit Fenstern sind ja echt schön anzuschauen und bei Spielen auch wohl der sinnvollste Einstiegspunkt, aber oft kommt man doch recht schnell an den Punkt, an dem man sich denkt: Jetzt wäre so eine Konsole echt nicht schlecht, um den Inhalt von Variable AB anzuzeigen oder mal schnell Fehlermeldung XY auszugeben (rein zu Debugzwecken versteht sich).
Leider muss man aber schon bei Projekterstellung festlegen, ob es sich um eine Konsolen- oder um eine GUI-Anwendung handelt.

Mein erster Versuch, ein bestehendes Vektoria-Projekt in ein Konsolen-Projekt umzuwandeln, indem ich einfach das SubSystem im Linker auf Console setze und den Einstiegspunkt manuell angebe, sah erstmal erstaunlich vielversprechend aus. Allerdings nur bis der erste Speicher von einer externen Bibliothek allokiert wird: Das beendete das kleine Experiment sehr deutlich mit einem Assert wegen Heapproblemen. Vermutlich kann man das ganze trotzdem irgendwie noch so hinbiegen, dass es funktioniert, aber das Ziel sollte ja eigentlich sein, möglichst einfach noch eine Konsole zu öffnen, auf der die Standardausgabe schreibt.

Nach einigem suchen bin ich dann auf einen, zugegebenermaßen schon etwas älteren, Artikel aus dem Windows Developer Journal gestoßen. Dieser enthält, neben einer Beschreibung des Vorgehens zum Öffnen einer Konsole und anschließendem Umleiten der Standard Ein- und Ausgaben auf diese, auch ein vollständiges Codebeispiel.

Hier ist der gekürzte Kerncode, um den Grundablauf (anhand von stdout) zu zeigen:

#include <windows.h>
#include <fcntl.h>
#include <io.h>
#include <fstream>

using namespace std;

void RedirectIOToConsole() {

    int hConsoleHandle;
    long lStdHandle;
    CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
    FILE* pFile;

    // allocate a console for this app
    AllocConsole();

    // set the screen buffer to be big enough to let us scroll text
    GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &consoleInfo);
    consoleInfo.dwSize.Y = 500;
    SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), consoleInfo.dwSize);

    // redirect unbuffered STDOUT to the console
    lStdHandle = (long) GetStdHandle(STD_OUTPUT_HANDLE);
    hConsoleHandle = _open_osfhandle(lStdHandle, _O_TEXT);
    pFile = _fdopen(hConsoleHandle, "w");
    *stdout = *pFile;
    setvbuf(stdout, NULL, _IONBF, 0);
}

Zuerst wird eine neue Konsole mit AllocConsole erzeugt, wobei zu beachten ist, dass pro Prozess immer nur eine Konsole auf diese Weise bereitgestellt werden kann. Aber mehr als das wollen wir ja auch nicht.
Als nächstes wird der Buffer der Konsole vergrößert, sodass mehr Text angezeigt werden kann. Hierbei entspricht X der Zeichen pro Zeile und Y der Anzahl der Zeilen. Natürlich kann die Konsole noch anderweitig angepasst werden, z.B. die Zeichenfarbe, aber das ist jedem selbst überlassen.
Zum Schluss kommt dann der eigentlich interessante Teil: Hier wird zuerst das Output Handle für die Konsole geholt, mit einem C File Descriptor verknüpft und anschließend dieser wiederum mit einem Stream. Weist man diesen nun dem Standard Output Stream zu, wird jede Ausgabe, z.B. über cout, an die Konsole weitergeleitet und dort angezeigt. Setvbuf setzt nur noch fest, dass stdout unbuffered sein soll, damit alles sofort geschrieben wird.

Natürlich kann man auf diese Weise auch andere Streams wie z.B. stderr oder auch stdin umleiten. Es muss nur der ensprechende Stream und das zugehörige Handle angegeben werden (siehe Artikel).

Vermutlich gibt es noch verschiedene andere Möglichkeiten um eine einfache Ausgabenumleitung zu erreichen (vielleicht auch mit weniger C Anteilen), aber dies ist auf jeden Fall eine nicht allzu umfangreiche Variante ohne dass man auf externe Bibliotheken zugreifen muss.

Quelle: Windows Developer Journal, December 1997 (Artikel auf Andrew Tucker's Home Page)