VBScript: Standard Pingabfrage mit WMI

Um zu überprüfen ob ein Host im Netzwerk erreichbar ist, kann man eine standard Pingabfrage verwenden.

Mit der “Win32_PingStatus WMI CLASS” bietet Microsoft die Möglichkeit eine solche standard Pingabfrage in einem VBScript zu verwenden.


Dim hostToPingFrom: hostToPingFrom= "localhost"
Dim targetIP: targetIP = 8.8.8.8

Dim cPingResults: Set cPingResults = GetObject("winmgmts:{impersonationLevel=impersonate}//" & _
hostToPingFrom & "/root/cimv2"). ExecQuery("SELECT * FROM Win32_PingStatus " & _
"WHERE Address = '" + targetIP + "'")

For Each oPingResult In cPingResults
    If oPingResult.StatusCode = 0 Then
       wscript.echo "Host is reachable"
    End if
Next

  • Zeilen 4,5,6: Verschickt die Pingabfrage
  • Zeile 8: Iterieren über die Ping-Resultate
  • Zeile 9: Ist der Statuscode 0 war das Pingkommando erfoglreich. Weitere Statuscodes werden in der Dokumentation zur “Win32_PingStatus class” beschrieben.

ping-checker.vbs

Ein kleines VBScript, das ein Ping sendet und bei einem Fehler eine Benachrichtigung als Email, über einen SMTP-Server, verschickt oder in der Windows Konsole anzeigt. Je nach Konfiguration. Dieses einfache Skript kann als Grundlage dienen, um sich ein eigenes, den Bedürfnissen angepasstes Skript zu erstellen.

ping-checker.vbs als 7zip herunterladen

ping-checker.vbs output
Der Konsolen-Output des Skriptes, da der Host 192.168.88.55 nicht erreichbar war.

Nützliche Links

Microsoft: Win32_PingStatus class
Wikipedia: Ping

Windows Installer XML (WiX)

Wurde eine neue Software entwickelt, muss diese Software noch paketiert werden. Mit Hilfe dieses Installationspaketes kann diese Software dann an die verschiedenen Windows-Clients verteilt werden. Um ein solches Installationspaket, auch Setup bezeichnet, zu erstellen gibt es verschiedene gratis und Open Source – Applikationen.

Zwei weitverbreitete Programme zum Erstellen von Windows Installationsprogramme sind NSIS und Inno Setup. Beide erstellen eine ausführbare EXE-Datei, um die Software zu installieren. Nachteil beider Installationsprogramme ist, dass sie kein standardisiertes Installationsformat verwenden. Somit ist vor der Installation nicht ersichtlich was genau installiert, beziehungsweise welche Einstellungen vorgenommen werden. Daher verwenden viele Grossfirmen lieber ein standardisiertes Format wie das „Windows Installer XML“ das durch den „Windows Installer“ bereitgestellt wird.

Der Windows Installer (vormals Microsoft Installer) stellt eine Laufzeitumgebung für Installationsroutinen unter Microsoft-Windows-Betriebssystemen bereit. Er besteht aus einem Windows-Systemdienst, welcher Paketdateien im msi-Format (Microsoft Software Installation), sowie Dateien mit den Dateiendungen mst für Transform-Dateien und msp für Patches interpretieren, entpacken und ausführen kann. [1]

Eine Programmsammlung zum Erstellen von MSI-Paketen wurde intern bei Microsoft entwickelt und später als erstes Open-Source Produkt der Firma veröffentlicht. Der Name dieser Programmsammlung ist „WiX-Toolset“. Das gesamte Installationspaket wird mit Hilfe von XML definiert. Die Einarbeitung in das „Windows Installer XML“ braucht zwar seine Zeit, wird aber durch ein praktisches GUI-Tool „WixEdit“ oder dem Visual Studio Template „Votive“ vereinfacht. Auch sehr nützlich ist das Buch von Nick Ramirez mit dem Titel „A Developer’s Guide to Windows Installer XML“.

Nützliche Links

Webseite des WiX Toolset
Webseite des WiX Edit GUI
Wikipedia: WiX
Webseite von Inno Setup
Webseite des NSIS Installer

Referenzen
[1] Wikipedia: Windows Installer

C# .NET: Erstellen einer COM-Komponente

COM-Komponenten können sowohl in Form von Laufzeitmodulen (DLL’s) als auch als ausführbare Programme implementiert werden. Damit die Funktionen der Komponente für den COM-Client sichtbar sind, müssen folgende Punkte befolgt werden:

  • Die Klasse muss „public“ sein
  • Properties, Methoden und Events müssen „public“ sein
  • Properties und Methoden müssen im Klassen-Interface definiert sein
  • Events müssen im Event-Interface definiert sein

Erstellen:

Projekteinstellungen
Projekteinstellungen
  1. Zuerst muss das COM-Interface definiert werden (Definition der Schnittstelle)
  2. Als zweiter Schritt muss die Klasse implementiert werden. Die Klasse muss den Namespace “InteropServices” importieren (using System.Runtime.InteropServices;)
  3. In den Projekteinstellungen unter „Erstellen“ muss die Option „Für COM-Interop registrieren“ sowie unter „Anwendung->Assemblyinformationen“ die Option „Assembly COM-sichtbar machen“ aktiviert werden
  4. Am Schluss muss das Assembly noch signiert werden. Dies kann in den Einstellungen unter “Signierung” gemacht werden. Dazu wird eine neue Schlüsseldatei erstellt

3. „Für COM-Interop registrieren“ Komponente lokal installieren
3. „Für COM-Interop registrieren“ Komponente lokal installieren
3. „Assembly COM-sichtbar machen“
3. „Assembly COM-sichtbar machen“
4. Assembly signieren
4. Assembly signieren


COM-Komponente registrieren:

Um die COM-Komponente auf einem anderen Gerät zu verwenden muss diese zuerst registriert werden. Dazu wird das Programm “RegAsm.exe” verwendet.


RegAsm.exe sCOMDemo.dll /codebase /tlb:sCOMDemo.tlb

COM-Komponente deregistrieren:

Bevor eine neue Version installiert wird, sollte die alte Version unregistriert werden.


RegAsm.exe sCOMDemo.dll /unregister

Beispiel Code:

Klassendiagramm
Klassendiagramm

Das Interface:



namespace sCOMDemo
{
    public interface IsCom
    {
        string helloWorld();
    }
}

Die Klasse:


using System.Runtime.InteropServices;

namespace sCOMDemo
{
    public class sCom:IsCom
    {
        public string helloWorld()
        {
            return "hello world!";
        }
    }
}

Verwendung der COM-Komponente unter VBScript:


Dim objDemo: set objDemo = createObject("sCOMDemo.sCom")
wscript.echo objDemo.HelloWorld()

wscript - Ausgabe
Nützliche Links:

Component Object Model (COM)
COM Interop Part 1: C# Client Tutorial
System.Runtime.InteropServices Namespace
How to: Create COM Wrappers
How to: Raise Events Handled by a COM Sink
Creating a COM Visible C# Component
Assembly Registration-Tool (Regasm.exe)
Wikipedia: COM

C#: XML-Serialisierung mit dem XmlSerializer Teil 3

In den vorhergehenden Beiträgen Teil 1 & Teil 2 haben wir eine Adressklasse erstellt um B2B- und B2C-Adressen zu speichern. Nun werden wir diese Adressklasse erweitern, damit auch Kommunikationsdetails (Telefon, Email, usw.) gespeichert werden können.

Als Erstes erstellen wir die Klasse “CommunicationDetail” um damit die Kommunikationsdetails zu speichern:


namespace XML_Serialisierung
{
    public class CommunicationDetail
    {
        public enum CommunicationDetailType
        {
            PRIVATE_MOBILE,
            BUSINESS_MOBILE,
            PRIVATE_PHONE,
            BUSINESS_PHONE,
            PRIVATE_FAX,
            BUSINESS_FAX,
            PRIVATE_EMAIL,
            BUSINESS_EMAIL,
            SKYPE_MESSANGER
        }

        [XmlAttribute("Typ")]
        public CommunicationDetailType DetailType { get; set; }

        [XmlElement("Wert")]
        public string Value { get; set; }

        public CommunicationDetail()
        {
        }
        public CommunicationDetail(CommunicationDetailType detailType, string value)
        {
            this.Value = value;
            this.DetailType = detailType;
        }
    }
}

Nun werden wir die Address-Klasse mit einer Liste vom Typ “CommunicationDetail” erweitern. Damit beim Serialisieren der Liste, die einzelnen Details auch richtig im XML-Abgebildet werden, verwenden wir das Attribut [XmlArray(“”)] um den Namen des Hauptelementes festzulegen und [XmlArrayItem(“”)] um damit den Namen der Unterknoten zu bestimmen.


namespace XML_Serialisierung
{
    public class Address
    {
        [XmlAttribute("Adressenummer")]
        public int AddressNumber { get; set; }
        
        [XmlElement("Strasse")]
        public string Street { get; set; }

        [XmlElement("Hausnumer")]
        public string HouseNumber { get; set; }

        [XmlElement("Land")]
        public string Country { get; set; }

        [XmlElement("Postleitzahl")]
        public string ZIP { get; set; }

        [XmlElement("Stadt")]
        public string City { get; set; }

        [XmlArray("Kommunikation")]
        [XmlArrayItem("Kommunikationsdetail")]
        public List CommunicationNumbers;


        public Address()
        {
            this.CommunicationNumbers = new List();
        }
    }
}

Klasse mit dem XmlSerializer serialisieren

Nun haben wir die Möglichkeit die Adresse mit Kommunikationsdetails zu erweitern:


/*b2c addresse*/
AddressB2C addressB2C_2 = new AddressB2C();
addressB2C_2.AddressNumber = 123456789;
addressB2C_2.Firstname = "Max";
addressB2C_2.Lastname = "Mustermann";
addressB2C_2.Street = "Musterstrasse";
addressB2C_2.HouseNumber = "77a";
addressB2C_2.City = "Musterhausen";
addressB2C_2.ZIP = "1234";
addressB2C_2.Country = "In einem fernen Land";

CommunicationDetail mobile = new CommunicationDetail(CommunicationDetail.CommunicationDetailType.PRIVATE_MOBILE, "079 123 45 67");
addressB2C_2.CommunicationNumbers.Add(mobile);

CommunicationDetail email = new CommunicationDetail(CommunicationDetail.CommunicationDetailType.PRIVATE_EMAIL, "meine@email.ch");
addressB2C_2.CommunicationNumbers.Add(email);

XmlSerializer xmls3 = new XmlSerializer(typeof(AddressB2C));
StreamWriter mwriter3 = new StreamWriter("b2cAddressWithNumbers.xml");
xmls3.Serialize(mwriter3, addressB2C_2);
mwriter3.Close();

Und als Ergebniss erhalten wir folgendes XML:




  
    
      079 123 45 67
    
    
      meine@email.ch
    
  
  Musterstrasse
  77a
  In einem fernen Land
  1234
  Musterhausen
  Max
  Mustermann

Nützliche Links:

C#: XML-Serialisierung mit dem XmlSerializer Teil 1
C#: XML-Serialisierung mit dem XmlSerializer Teil 2
msdn: xml.serialization
msdn: List

C#: XML-Serialisierung mit dem XmlSerializer Teil 2

Im vorhergehenden Beitrag haben wir aus einer einfachen Adressklasse eine XML-Datei generiert. In diesem Beitrag werden wir eine Kundenklasse erstellen, die entweder eine B2B- oder B2C-Adresse enthält und dann in eine XML-Datei geschrieben wird. Dazu erstellen wir zuerst eine Kundenklasse:


using System.Xml.Serialization;

namespace XML_Serialisierung
{
    [XmlRoot("Kunde")]
    public class Customer
    {
        [XmlAttribute("Kundennummer")]
        public int CustomerID { get; set; }

        [XmlElement("Adresse")]
        public Address CustomerAddress { get; set; }
        
        public Customer(bool b2c)
        {
            if (b2c == true)
            {
                this.CustomerAddress = new AddressB2C();
            }
            else
            {
                this.CustomerAddress = new AddressB2B();
            }
        }
        /*default constructor*/
        public Customer() {
            this.CustomerAddress = new AddressB2C();
        }
    }
}

Wird jetzt versucht diese Klasse zu serialiseren wird eine Exception geworfen:


System.InvalidOperationException wurde nicht behandelt.
  Message="Beim Generieren des XML-Dokuments ist ein Fehler aufgetreten."
  Source="System.Xml"
  StackTrace:
       bei System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id)
       bei System.Xml.Serialization.XmlSerializer.Serialize(TextWriter textWriter, Object o)
       bei XML_Serialisierung.Program.Main(String[] args) in D:\data\Projects\intern\blog\src\XML-Serialisierung\Program.cs:Zeile 59.
       bei System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
       bei Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       bei System.Threading.ThreadHelper.ThreadStart()
  InnerException: System.InvalidOperationException
       Message="Der Typ XML_Serialisierung.AddressB2B wurde nicht erwartet. Verwenden Sie das XmlInclude- oder das SoapInclude-Attribut, um Typen anzugeben, die nicht statisch sind."
       Source="uwky4mcz"
       StackTrace:
            bei Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterCustomer.Write2_Address(String n, String ns, Address o, Boolean isNullable, Boolean needType)
            bei Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterCustomer.Write3_Customer(String n, String ns, Customer o, Boolean isNullable, Boolean needType)
            bei Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterCustomer.Write4_Kunde(Object o)

Da das Property “CustomerAddress” vom Typ Address ist, beim serialisieren jedoch als Typ AddressB2B oder AddressB2C erscheint, weiss der XmlSerializer nicht, wie er diesen Datentyp verarbeiten soll. Damit der XmlSerializer damit korrekt umgehen kann, müssen wir ihn mit den möglichen Datentypen bekannt machen. Dazu wird das Attribut [XmlInclude(“”)] verwendet.


using System.Xml.Serialization;

namespace XML_Serialisierung
{
    [XmlInclude(typeof(AddressB2C))]
    [XmlInclude(typeof(AddressB2B))]

    [XmlRoot("Kunde")]
    public class Customer
    {
        [XmlAttribute("Kundennummer")]
        public int CustomerID { get; set; }

        [XmlElement("Adresse")]
        public Address CustomerAddress { get; set; }
        
        public Customer(bool b2c)
        {
            if (b2c == true)
            {
                this.CustomerAddress = new AddressB2C();
            }
            else
            {
                this.CustomerAddress = new AddressB2B();
            }
        }
        /*default constructor*/
        public Customer() {
            this.CustomerAddress = new AddressB2B();
        }
    }
}

Klasse mit dem XmlSerializer serialisieren

Starten wir nun nochmals einen Versuch, wird das Serialsieren funktionieren.


/*create a customer object*/
Customer customer = new Customer(false);
customer.CustomerID = 175;

AddressB2B b2bAddress = ((AddressB2B)(customer.CustomerAddress));
b2bAddress.AddressNumber = 123456789;
b2bAddress.CompanyName = "Muster AG";
b2bAddress.Division = "Musterkreation";
b2bAddress.Street  = "Musterstrasse";
b2bAddress.HouseNumber = "77a";

b2bAddress.City = "Musterhausen";
b2bAddress.ZIP = "1234";
b2bAddress.Country = "In einem Land";


XmlSerializer xmls2 = new XmlSerializer(typeof(Customer));
StreamWriter mwriter2 = new StreamWriter("CustomerWithb2bAddress.xml");
xmls2.Serialize(mwriter2, customer);
mwriter.Close();

Und als Ergebnis erhalten wir:




Musterstrasse
77a
In einem Land
1234
Musterhausen
Muster AG
Musterkreation




Nützliche Links:

C#: XML-Serialisierung mit dem XmlSerializer Teil 1
msdn: xml.serialization

C#: XML-Serialisierung mit dem XmlSerializer Teil 1

Mit dem XmlSerializer können auf einfache Weise XML-Dokumente erstellt werden. Zum Beispiel wollen wir eine XML-Datei mit Adressdaten generieren, die folgendermassen aussehen soll:




    Musterstrasse
    77a
    In einem Land
    1234
    Musterhausen
    Max
    Mustermann

Dazu erstellen wir zuerst einmal eine einfache Adressklasse, in der die Adressdaten gespeichert werden können:


namespace XML_Serialisierung
{
    public class Address
    {
        public int AddressNumber { get; set; }        
        public string Street { get; set; }
        public string HouseNumber { get; set; }
        public string Country { get; set; }
        public string ZIP { get; set; }
        public string City { get; set; }
    }
}

Würden man diese Klasse jetzt serialisieren, hätten die XML-Tags nicht die gewünschten Namen. Der XmlSerializer würde die Namen der Properties verwenden.

Mit Hilfe von Attributen kann man die Ausgabe der XML-Datei steuern. Im obigen XML ist die Adressnummer ein Attribut des Wurzelelment Adresse. Um dies zu erreichen, wird das Attribut [XmlAttribute] verwendet. Das Attribut [XmlElement(“”)] wird verwendet um den Namen des XML-Tag festzulegen.


using System.Xml.Serialization;

namespace XML_Serialisierung
{
    public class Address
    {
        [XmlAttribute("Adressenummer")]
        public int AddressNumber { get; set; }
        
        [XmlElement("Strasse")]
        public string Street { get; set; }

        [XmlElement("Hausnumer")]
        public string HouseNumber { get; set; }

        [XmlElement("Land")]
        public string Country { get; set; }

        [XmlElement("Postleitzahl")]
        public string ZIP { get; set; }

        [XmlElement("Stadt")]
        public string City { get; set; }
    }
}

In unserer Adressklasse fehlen uns aber noch ein paar Angaben wie Name, Vorname, Firmenname.. usw. Dazu werden wir 2 neue Klassen erstellen. Eine Klasse für Firmenadressen (B2B) und Privatadressen (B2C).


using System.Xml.Serialization;

namespace XML_Serialisierung
{
    [XmlRoot("Adresse")]
    public class AddressB2C: Address
    {
        [XmlElement("Vorname")]
        public string Firstname { get; set; }

        [XmlElement("Nachname")]
        public string Lastname { get; set; }
    }
}

Das Attribut [XmlRoot(“”)] wird verwendet um den Namen des Wurzelelements (Rootelement) festzulegen.


using System.Xml.Serialization;

namespace XML_Serialisierung
{
    [XmlRoot("Adresse")]
    public class AddressB2B:Address
    {
        [XmlElement("Firmenname")]
        public string CompanyName { get; set; }

        [XmlElement("Abteilung")]
        public string Division { get; set; }

        [XmlElement("Kontaktperson")]
        public string ContactPerson { get; set; }
    }
}

Klasse mit dem XmlSerializer serialisieren

Das serialisieren der erstellten Adressklassen kann nun mit sehr wenig Code-Zeilen erledigt werden.
Dazu wird zuerst das gewünschte Objekt AddressB2B oder AddressB2C erstellt und dann die Werte zugewiesen. Damit der XmlSerializer den Typ der zu serialsierenden Klasse kennt, muss dieser beim Instanziieren des XmlSerializer mitgegeben werden.


/*********************************************************/
//example 1
/*********************************************************/
/*b2c addresse*/
AddressB2C addressB2C = new AddressB2C();
addressB2C.AddressNumber = 123456789;
addressB2C.Firstname    = "Max";
addressB2C.Lastname     = "Mustermann";
addressB2C.Address1     = "Musterstrasse";
addressB2C.HouseNumber  = "77a";
addressB2C.City         = "Musterhausen";
addressB2C.ZIP          = "1234";
addressB2C.Country      = "In einem Land";

/*Create a XmlSerializer from type AddressB2C*/
XmlSerializer xmls = new XmlSerializer(typeof(AddressB2C));
StreamWriter mwriter = new StreamWriter("b2cAddress.xml");
xmls.Serialize(mwriter, addressB2C);
mwriter.Close();

Als Ergebnis erhalten wir in der Datei “b2cAddress.xml” die gewünschte XML-Struktur.

Nützliche Links:

msdn: xml.serialization
C#: XML-Serialisierung mit dem XmlSerializer Teil 2

VBScript: Windows Service remote starten und stoppen

Dank der WMI-Schnittstelle ist es möglich ein Skript zu schreiben, das auf einem remote System einen Service überwacht und bei Bedarf auch neu starten oder stoppen kann.


Dim objWMIService
Dim lServices
Dim strService: strService = "MeinService"
Dim strComputer: strComputer ="."

Set objWMIService = objSWbemLocator.ConnectServer("10.0.200.33", "root\cimv2", _
"Benutzer", _
"Passwort", _
"","")


Set lServices = objWMIService.ExecQuery("Select * from Win32_Service Where Name='" & strService & "'")
For Each objService In lServices
    Select Case objService.State
     case "Stopped" 'start service
          errReturn = objService.StartService()
     case "Paused" 'resume service
          errReturn = objService.ResumeService()
     case "Running" 'nothing todo
          wscript.echo objService.Name & " with ID " & objService.ProcessId & " is already started."
     End Select
Next

Anmerkung zu den Codezeilen:

  • 03 Achtung: bei der Definition des Servicenamen handelt es sich nicht um den Anzeigenamen sondern um den Dienstnamen
  • 06 Remote WMI Service initiieren (auch lokaler möglich)
  • 12 Mit einer WQL Abfrage wird der gesuchte Dienst selektiert um dann mit diesem Arbeiten zu können
  • 14 Status des Dienstes abfragen (Mögliche Werte sind: “Stopped”, “Start Pending”, “Stop Pending”, “Running”, “Continue Pending”, “Pause Pending”, “Paused”, “Unknown”)
Eigenschaften des Dienstes Anwendungsverwaltung
Bei der WQL-Abfrage den Dienstnamen verwenden und nicht den Anzeigenamen

Nützliche Links:

Managing Windows with WMI
WMI Query Language (WQL)
Win32_Service Class Proberties

WMI Scripting Primer: Part 1
WMI Scripting Primer: Part 2
WMI Scripting Primer: Part 3

Qt: Thumbnails von Webseiten erstellen

Thumbnail des monsterli.ch Blog
Thumbnail das mit Hilfe von QWebpage und QPainter erstellt wurde

Das Qt Framework bietet mit dem Modul QtWebKit eine vollständige “Browser-Engine”, welche das Anzeigen und Bearbeiten von Webseiten ermöglicht. Dieses Modul ermöglicht auf einfache Weise Thumbnails von Webseiten zu erstellen. In der Dokumentation zu der Klasse QWebPage befindet sich auch eine Beispielklasse zum Erstellen von Thumbnails ohne Widgets zu verwenden. Muss also ein “Command Line Tool” erstellt werden, ist das der ideale Startpunkt.

Thumbnailer Beispielklasse

Die Header-Datei der Thumbnailer-Klasse:


#ifndef THUMBNAILER_H
#define THUMBNAILER_H
#include 
#include 
#include 

class Thumbnailer : public QObject
 {
     Q_OBJECT

 public:
     Thumbnailer(const QUrl &url);

 signals:
     void finished();

 private slots:
     void render();

 private:
     QWebPage page;

 };

#endif // THUMBNAILER_H

Die Thumbnailer-Klasse:


#include "thumbnailer.h"

Thumbnailer::Thumbnailer(const QUrl &url)
{
    page.mainFrame()->load(url);
    connect(&page, SIGNAL(loadFinished(bool)),
        this, SLOT(render()));
}

void Thumbnailer::render()
{
    page.setViewportSize(page.mainFrame()->contentsSize());
    QImage image(page.viewportSize(), QImage::Format_ARGB32);
    QPainter painter(&image);

    page.mainFrame()->render(&painter);
    painter.end();

    QImage thumbnail = image.scaled(400, 300);
    thumbnail.save("thumbnail.png");

    emit finished();
}

Die main-Klasse:


#include "thumbnailer.h"
#include 

int main(int argc, char *argv[])
{
    QApplication a( argc, argv);
    Thumbnailer myThumb(QUrl("https://www.google.com"));
    QObject::connect(&myThumb, SIGNAL(finished()), QApplication::instance(), SLOT(quit()));

    return a.exec();
}

 

Verwenden von Browser Plugins wie Adobe Flash

Verwendung von Plugins aktiviert
Verwendung von Plugins aktiviert
Verwendung von Plugins deaktiviert
Verwendung von Plugins deaktiviert

Damit auch die Flash-Elemente einer Webseite auf dem Thumbnail dargestellt werden, muss das Flash-Plugin bereits auf dem System installiert sein und das QWebSetting “PluginsEnabled” aktiviert werden:


page.settings()->setAttribute(QWebSettings::PluginsEnabled, true);

 

Nützliche Links

QT Beispiel Projekt
WebScreenie is small qt command-line utility to create snapshot of webpages.
QT-Code websnap

VBScript: Microsoft DNS-Server Einträge bearbeiten

Mit Hilfe der “DNS WMI Services” kann der Microsoft DNS Server verwaltet werden. Dies ermöglicht das Erstellen von Skripts zum Hinzufügen, Löschen oder Editieren von Zonen und Records.

Um mit den “DNS WMI Klassen” zu arbeiten sind folgende Schritte notwendig:

  1. WMI Service initiieren (remote oder lokal)
  2. Mit Hilfe des WMI Service kann dann die benötigte “DNS WMI Klasse” instanziiert werden

Lokalen WMI Service initiieren:


Dim objWMIService: Set objWMIService = GetObject("winmgmts:\\" & "." & "\root\MicrosoftDNS")

Remote WMI Service initiieren:


Dim objSWbemLocator: Set objSWbemLocator = CreateObject("WbemScripting.SWbemLocator") 
Dim objWMIService: Set objWMIService = objSWbemLocator.ConnectServer(hostIP, _ 
		"root\MicrosoftDNS", _ 
		username, _ 
		password, _ 
		"", _ 
		"") 	

Die Parameter:

  • hostIP = IP des DNS-Server
  • username = Benutzername
  • password = Passwort

Neue “Primary-Zone” erstellen:


Dim objDNSZone: Set objDNSZone = objWMIService.Get("MicrosoftDNS_Zone")
objDNSZone.CreateZone(zoneName,0)

Bedeutung der Parameter:

  • zoneName = Name der neuen Zone (monsterli.ch, switch.ch, usw.)
  • 0 = Zone des Typs: “primary zone”

Neue “Secondary-Zone” erstellen:


Dim objDNSZone: Set objDNSZone = objWMIService.Get("MicrosoftDNS_Zone")
objDNSZone.CreateZone(zoneName,1,false,zoneName & "dns",array(nsMasterIP))

Dabei sind die Parameter:

  • zoneName = Name der neuen Zone (Domain)
  • 1 = Zone des Typs: “secondary zone”
  • false = keine “AD integrated zone”
  • zoneName & “dns” = Name der Zonendatei
  • array(nsMasterIP) = Array mit der IP des primären Server dieser Zone

Neuer A-Record erstellen:


Dim objItem: Set objItem = objWMIService.Get("MicrosoftDNS_AType")
objItem.CreateInstanceFromPropertyData(masterDNSServer, zoneName, subZoneName , 1, 600, hostIP)

Die Parameter:

  • masterDNSServer = IP des primären Server
  • zoneName = Name der Zone (Domain)
  • subZoneName = gewünschter Hostname (www, mail, ftp… usw.)
  • 1 = Record Class IN (Internet)
  • 600 = TTL in Sekunden
  • hostIP = IP-Adresse des Hosts

Um weitere Records wie NS, MX, CNAME, usw. zu erstellen, muss einfach die “DNS WMI Class” geändert werden.

Zone löschen:

Um eine bestehende Zone zu löschen wird mit Hilfe der “.Get” Funktion des WMI-Service die Zone selektiert und gelöscht.


Dim objServer: set objServer = objWMIService.Get("MicrosoftDNS_Server.name="".""")
Dim objItem: Set objItem = objWMIService.Get("MicrosoftDNS_Zone.ContainerName=""" & zoneName & """,DnsServerName=""" & objServer.name & """,Name=""" &  zoneName & """")
if isObject(objItem) then
	objItem.delete_
end if

Benutzte Parameter:

  • zoneName = Name der Zone die gelöscht werden soll
  • objServer.name = Name des verwendeten DNS-Server
  • zoneName = Name der Zone die gelöscht werden soll

Nützliche Links

DNS WMI Provider Samples—Managing DNS Zones
Scripts to manage DNS Server

Multicast Sender & Empfänger mit Python

Die Kommunikation über eine Punkt-zu-Punkt-Verbindung ist in den meisten Anwendungen der richtige Weg. Was aber wenn mehrere Empfänger die gleichen Informationen erhalten wollen? Da zeigt sich dann ein grosser Nachteil der Punkt-zu-Punkt-Verbindungen. Pro Empfänger muss eine Verbindung hergestellt werden um dann die gleichen Informationen mehrfach zu verschicken, was zu Engpässen in der Bandbreite führen kann. Um dies zu vermeiden, kann mit Hilfe von Multicast eine sogenannte Punkt-zu-Gruppe-Verbindung hergestellt werden. Der Sender verschickt eine einzige Nachricht an eine ganze Gruppe von Empfängern und die Netzwerkinfrastruktur sorgt dafür, dass jeder interessierte Empfänger die Informationen auch erhält. Die Kommunikation geschieht über eine spezielle Multicast-Adresse (Multicast-Group) die aus dem IPv4-Bereich 224.0.0.0 bis 239.255.255.255 stammen muss. Dieser IP-Bereich ist für Multicast reserviert und wird von Routern und Switches speziell behandelt. Die Multicast-Pakete werden über UDP versendet.

Ein gutes Beispiel eines Multicast Senders und Empfänger habe ich auf der Webseite von Doug Hellmann gefunden.

Der Multicast Sender
In diesem Beispiel müssen sich die Empfänger nicht beim Sender anmelden, daher kann der Sender nicht wissen wie viele Antworten zu erwarten sind. Aus diesem Grund wartet der Sender solange auf eine Antwort bis der festgelegte Socket-Timeout erreicht wurde.

Hier die wichtigsten Code-Zeilen:


# Create the datagram socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# Set a timeout so the socket does not block indefinitely when trying
# to receive data. (in sec flaot)
sock.settimeout(1.0)

# Set the time-to-live for messages to 1 so they do not go past the
# local network segment.
ttl = struct.pack('b', 1)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl)

try:        
	# Send data to the multicast group
	print >>sys.stderr, 'sending "%s"' % message
	sent = sock.sendto(message, multicast_group)

	# Look for responses from all recipients
	while True:
		print >>sys.stderr, 'waiting to receive'
		try:
			data, server = sock.recvfrom(16)
		except socket.timeout:
			print >>sys.stderr, 'timed out, no more responses'
			break
		else:
			print >>sys.stderr, 'received "%s" from %s' % (data, server)        
finally:
	print >>sys.stderr, 'closing socket'
	sock.close()

Der Multicast Empfänger
Der Empfänger lauscht auf allen Netzwerkinterfaces auf Daten seiner Multicast-Gruppe und schickt eine Empfangsbestätigung zurück.

Hier die wichtigsten Code-Zeilen:


# The first step to establishing a multicast receiver is to create 
# the UDP socket.
server_address = ('', 10000)

# Create the socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# Bind to the server address
sock.bind(server_address)

# Tell the operating system to add the socket to 
# the multicast group on all interfaces.
group = socket.inet_aton(multicast_group)
mreq = struct.pack('4sL', group, socket.INADDR_ANY)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)


# Receive/respond loop
while True:
	print >>sys.stderr, '\nwaiting to receive message'
	data, address = sock.recvfrom(1024)
	
	print >>sys.stderr, 'received %s bytes from %s' % (len(data), address)
	print >>sys.stderr, data

	print >>sys.stderr, 'sending acknowledgement to', address
	sock.sendto('ack', address)

Source Code-Dateien:

Die 7zip-Datei enthält die Dateien:
– MulticastServer.py (Sender)
– MulticastClient.py (Empfänger)
Python – Source Code

Eine ausführbare Version (exe) der Dateien, welche eine vorhandene Installation von Python 2.7.2 erfordert:
– MulticastServer.exe (Sender)
– MulticastClient.exe (Empfänger)
Kompilierte Multicast Beispiele (x64)

Starten des Clients:
(Client empfängt Daten der Multicast-Gruppe 224.0.1.2)


>MulticastClient.exe 224.0.1.2

Starten des Servers und gleichzeitiges verschicken von Daten:
(Server verschickt ein “Hallo Multicast!” an die Multicast-Gruppe 224.0.1.2)


>MulticastServer.exe "Hallo Multicast!" 224.0.1.2

Multicast Server und Client
Multicast Server und Client


– Python: Socket-Dokumentation
– Wikipedia: Multicast