C# Emgu CV Gesichtserkennung

In diesem Beitrag zeige ich euch wie man in Visual Studio mit C# und Emgu CV eine Gesichtserkennungssoftware programmieren kann.

Dieses Programm kann nicht nur Gesichter erkennen, sondern es kann auch Gesichter wiedererkennen. Dieses wird oftmals verwechselt, aber es sind zwei unterschiedliche Dinge. So können am Ende mit dem Programm Gesichter erkannt werden und mit einem Namen versehen werden, damit sie danach vom Programm wiedererkannt werden.

Wenn ihr keine Zeit oder Lust habt das ganze Projekt nach zu programmieren, dann könnt ihr das fertige Projekt hier herunterladen: Win_FaceDetection.zip

Wichtig!!! Die Emgu.CV.UI.dll und Emgu.CV.World.dll müssen beim Öffnen und Bearbeiten des Projektes als Verweise neu hinzugefügt werden.

Als erstes müssen wir die neuste Version des Emgu CV Projekts als ZIP-Datei herunterladen:

Emgu CV

Als nächstes entpacken wir die ZIP-Datei auf dem Desktop. Nun erstellen wir ein neues Projekt in Visual Studio. Nach dem Erstellen des Projektes müssen nun einige Dateien von dem Emgu CV Projekt in unser Projekt hinzugefügt werden. Alle Dateien die in den nachfolgenden Schritten hinzugefügt werden, befinden sich in dem entpacktem Emgu CV Projekt auf dem Desktop.

Als erstes werden zwei DLL-Dateien als Verweise in unser Projekt mit aufgenommen.

  • bin\Emgu.CV.UI.dll
  • bin\Emgu.CV.World.dll

Um die DLLs als Verweise hinzuzufügen einfach auf “Projekt” > “Verweise hinzufügen…” klicken.

Als nächstes werden weitere DLLs und eine Klasse aus dem Emgu CV Projekt in unser Projekt hinzugefügt. Folgende DLLs werden hinzugefügt:

  • \libs\x86\concrt140.dll
  • \libs\x86\cvextern.dll
  • \libs\x86\msvcp140.dll
  • \libs\x86\opencv_ffmpeg341.dll
  • \libs\x86\vcruntime140.dll
  • \Emgu.CV.Contrib\Face\Recognizer.cs

Um Elemente in ein Projekt hinzuzufügen einfach auf “Projekt” >  “Vorhandenes Element hinzufügen…” klicken.

Als letztes wird noch eine XML-Datei zum Projekt hinzugefügt. Diese dient als Datenbank, um nachher Gesichter zu erkennen.

  • \opencv\data\haarcascades\haarcascade_frontalface_default.xml

Für diese Datei erstellen wir einen neuen Ordner im Projektmappen-Explorer. Dazu einfach auf  “Projekt” >  “Neuer Ordner” klicken. Der Name des Ordners lautet: “data“. In diesem Ordner wird nun die “haarcascade_frontalface_default.xml” hinzugefügt. Alle bei allen hinzugefügten Dateien (außer den Verweisen) muss die Eigenschaft “In Ausgabeverzeichnis kopieren” auf “Immer kopieren” eingestellt werden.

So sieht es aus wenn alle Dateien zum Projekt hinzugefügt wurden:

Um die Klasse “Recognizer.cs” und deren Methoden verwenden zu können, muss der “namespace” der Klasse geändert werden. Als Namespace wird dein Projektname eigetragen. So wird der Code in der Recognizer.cs von:

namespace EmguCVFace
{
    /// <summary>
    /// Face Recognizer
    /// </summary>
    public abstract class FaceRecognizer : UnmanagedObject
    {

in

namespace EmguCVFace
{
    /// <summary>
    /// Face Recognizer
    /// </summary>
    public abstract class FaceRecognizer : UnmanagedObject
    {

geändert. Als letzte Vorbereitung müsst ihr in eurem Projektordner einen neuen Ordner erstellen.

  • Win_FaceDetection\Win_FaceDetection\bin\Debug\Face Collection

In diesem Ordner erstellt ihr ein Testdokument mit dem Namen: “Datenbank“. Nun kann mit dem eigentlichen Programmieren begonnen werden ;). Ich zeige nun meinen ganzen Quellcode den ihr auch gerne in euren Projekt Optimieren und Weiterentwickeln könnt.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using Emgu.CV;
using Emgu.CV.Structure;
using Emgu.CV.CvEnum;
using System.IO;

namespace Win_FaceDetection
{
    public partial class frmFaceDetection : Form
    {

        Image<Bgr, byte> img;
        VideoCapture vid;
        int indexofSelectedFace = 0;
        FaceRecognizer recognizer = new EigenFaceRecognizer(80, double.PositiveInfinity);
        Bitmap[] detectedFaces;
        string[] faceNames;
        int[] faceIDs;

        public frmFaceDetection()
        {
            InitializeComponent();

            stopToolStripMenuItem.Enabled = false;
            btnZurück.Enabled = false;
            btnVor.Enabled = false;
            btnVerwerfen.Enabled = false;
            btnHinzufügen.Enabled = false;
        }  
        
        private void drawText(Image<Bgr, Byte> img, Rectangle rect, string text)
        {
            Font font = new Font("Arial", 12, FontStyle.Bold);
            Graphics g = Graphics.FromImage(img.Bitmap);

            int tWidth = (int)g.MeasureString(text, font).Width;
            int x;
            if (tWidth >= rect.Width)
                x = rect.Left - ((tWidth - rect.Width) / 2);
            else
                x = (rect.Width / 2) - (tWidth / 2) + rect.Left;

            g.DrawString(text, font, Brushes.Red, new PointF(x, rect.Top - 18));
        }

        public void GesichterErkennen()
        {
            Rectangle[] faceRectangles = null;
            detectedFaces = null;
            string facePath = Path.GetFullPath(@"data/haarcascade_frontalface_default.xml");
            CascadeClassifier classifierFace = new CascadeClassifier(facePath);
            var imgGray = img.Convert<Gray, byte>().Clone();
            faceRectangles = classifierFace.DetectMultiScale(imgGray, 1.1, 4);
            detectedFaces = new Bitmap[faceRectangles.Length];

            for (int i = 0; i < faceRectangles.Length; i++)
            {
                img.Draw(faceRectangles[i], new Bgr(255, 0, 0), 1);
                imgGray.ROI = faceRectangles[i];
                var detectedFace = imgGray.Copy();
                detectedFaces[i] = detectedFace.Resize(200, 200, Inter.Linear).ToBitmap();
            }
            pictureBoxInput.Image = img.ToBitmap();
        }

        public void GesichterWiedererkennen()
        {
            Rectangle[] faceRectangles = null;
            string facePath = Path.GetFullPath(@"data/haarcascade_frontalface_default.xml");
            CascadeClassifier classifierFace = new CascadeClassifier(facePath);
            var imgGray = img.Convert<Gray, byte>().Clone();
            faceRectangles = classifierFace.DetectMultiScale(imgGray, 1.1, 4);

            for (int i = 0; i < faceRectangles.Length; i++)
            {
                int foundfaceID = 0;
                imgGray.ROI = faceRectangles[i];
                var detectedFace = imgGray.Copy();
                detectedFace = detectedFace.Resize(200, 200, Inter.Linear);
                var result = recognizer.Predict(detectedFace);
                /*Die Dictance ist ein Wert, der angibt wie viel Ähnlichkeit das
                  aktuelle Gesicht mit allen anderen Gesichtern in der Datenbank
                  hat. Je kleiner der Wert desto ähnlicher ist das aktuelle Gesicht
                  zu einem anderem Gesicht in der Datenbank.*/
                var distance = result.Distance;
                foundfaceID = result.Label;

                if (distance < 3000)
                {
                    string foundfaceName = "";
                    for (int j = 0; j < faceIDs.Length; j++)
                    {
                        if (faceIDs[j] == foundfaceID)
                        {
                            foundfaceName = faceNames[j];
                            break;
                        }
                    }
                    /*Methode drawText wird aufgerufen um den Namen des 
                    wiedererkannten Gesichts in die PictureBox zu schreiben.*/
                    drawText(img, faceRectangles[i], foundfaceName);
                    img.Draw(faceRectangles[i], new Bgr(0, 255, 0), 1);
                }
            }
            pictureBoxInput2.Image = img.ToBitmap();
        }

        private void öffnenToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "Image files (*.jpg, *.jpeg, *.jpe, *.jfif, *.png)" +
                " | *.jpg; *.jpeg; *.jpe; *.jfif; *.png";
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                img = new Image<Bgr, byte>(ofd.FileName);
                int index = tabControl1.SelectedIndex;
                
                //"Wiedererkennen" Tab im Fokus
                if (index == 1)
                {
                    pictureBoxInput2.Image = img.ToBitmap();
                    Trainieren();
                    GesichterWiedererkennen();
                }
                //"Erkennen" Tab im Fokus
                else
                {
                    pictureBoxInput.Image = img.ToBitmap();
                    GesichterErkennen();
                }
            }  
        }

        private void startToolStripMenuItem_Click(object sender, EventArgs e)
        {

            startToolStripMenuItem.Enabled = false;
            öffnenToolStripMenuItem.Enabled = false;
            stopToolStripMenuItem.Enabled = true;

            try
            {
                vid = new VideoCapture();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

            int index = tabControl1.SelectedIndex;
            //"Wiedererkennen" Tab im Fokus
            if(index == 1)
            {
                Trainieren();
                Application.Idle += ProcessFrameWiedererkennen;
            }
            //"Erkennen" Tab im Fokus
            else
            {
                Application.Idle += ProcessFrameErkennen;
            } 
        }

        private void ProcessFrameWiedererkennen(object sender, EventArgs e)
        {
            img = vid.QueryFrame().ToImage<Bgr, byte>();
            GesichterWiedererkennen();
        }

        private void ProcessFrameErkennen(object sender, EventArgs e)
        {
            img = vid.QueryFrame().ToImage<Bgr, byte>();
            GesichterErkennen();
        }

        private void stopToolStripMenuItem_Click(object sender, EventArgs e)
        {
            startToolStripMenuItem.Enabled = true;
            öffnenToolStripMenuItem.Enabled = true;
            stopToolStripMenuItem.Enabled = false;
            Application.Idle -= ProcessFrameWiedererkennen;
            Application.Idle -= ProcessFrameErkennen;
            vid.Dispose();         
        }

        private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
        {
            /*Wenn man bei einer laufenden Videoaufnahme den Tab wechselt, 
              wird die Videoaufnahme gestoppt.*/
            stopToolStripMenuItem.PerformClick();
        }

        private void btnExtrahieren_Click(object sender, EventArgs e)
        {
            if (pictureBoxInput.Image != null)
            {
                btnExtrahieren.Enabled = false;
                btnVerwerfen.Enabled = true;
                btnHinzufügen.Enabled = true;
                //Wenn Videostream noch läuft, wird dieser angehalten.
                stopToolStripMenuItem.PerformClick();
                /*Erstes erkanntes Gesicht wird in 
                  die kleine PictureBox geladen.*/
                if (detectedFaces.Length > 0)
                {
                    if (detectedFaces.Length >= 1)
                    {
                        btnVor.Enabled = true;
                    }
                    pictureBoxFace.Image = detectedFaces[0];
                }
            }    
        }

        private void btnVerwerfen_Click(object sender, EventArgs e)
        {
            /*Verworfenes Bild aus dem Bitmap Array entfernen und 
              das nächste Bild einblenden lassen.*/
            detectedFaces = detectedFaces.Skip(1).ToArray();
            textBoxName.Text = "";
            if (detectedFaces.Length-1 > 0)
            {              
                pictureBoxFace.Image = detectedFaces[0];
            }
            else if (detectedFaces.Length-1 == 0)
            {
                btnVor.Enabled = false;
                pictureBoxFace.Image = detectedFaces[0];
            }
            else
            {
                btnExtrahieren.Enabled = true;
                btnVerwerfen.Enabled = false;
                btnHinzufügen.Enabled = false;
                pictureBoxFace.Image = null;
                pictureBoxInput.Image = null;
            }
            
        }

        private void btnHinzufügen_Click(object sender, EventArgs e)
        {
            if (textBoxName.Text == "")
            {
                MessageBox.Show("Keinen Namen vergeben.");
            }
            else
            {
                //Abspeichern des ausgewählten Gesichts
                Random rand = new Random(DateTime.Now.Millisecond);
                int random = Math.Abs(rand.Next()*1000);
                pictureBoxFace.Image.Save(@"Face Collection\Face_" + 
                    (textBoxName.Text) +"_"+ random + ".bmp");
                textBoxName.Text = "";

                /*Abgespeichertes Bild aus dem Bitmap Array entfernen und 
                  das nächste Bild einblenden lassen.*/
                detectedFaces = detectedFaces.Skip(1).ToArray();
                if (detectedFaces.Length - 1 > 0)
                {
                    pictureBoxFace.Image = detectedFaces[0];
                }
                else if (detectedFaces.Length - 1 == 0)
                {
                    btnVor.Enabled = false;
                    pictureBoxFace.Image = detectedFaces[0];
                }
                else
                {
                    btnExtrahieren.Enabled = true;
                    btnVerwerfen.Enabled = false;
                    btnHinzufügen.Enabled = false;
                    pictureBoxFace.Image = null;
                    pictureBoxInput.Image = null;
                }
                
            }
        }

        private void btnZurück_Click(object sender, EventArgs e)
        {      
            indexofSelectedFace--;
            if (indexofSelectedFace == 0)
            {
                btnZurück.Enabled = false;
                btnHinzufügen.Enabled = true;
                btnVerwerfen.Enabled = true;
                pictureBoxFace.Image = detectedFaces[indexofSelectedFace];
            }
            else
            {
                btnVor.Enabled = true;
                pictureBoxFace.Image = detectedFaces[indexofSelectedFace];
            }
        }

        private void btnVor_Click(object sender, EventArgs e)
        {           
            indexofSelectedFace++;
            if (indexofSelectedFace == detectedFaces.Length-1)
            {
                btnVor.Enabled = false;
                pictureBoxFace.Image = detectedFaces[indexofSelectedFace];
            }
            else
            {
                btnZurück.Enabled = true;
                btnHinzufügen.Enabled = false;
                btnVerwerfen.Enabled = false;
                pictureBoxFace.Image = detectedFaces[indexofSelectedFace];
            }  
        }

        private void Trainieren()
        {
            string[] filePaths = Directory.GetFiles(@"Face Collection\", "*.bmp");
            var faceImages = new Image<Gray, byte>[filePaths.Count()];
            faceNames = new string[filePaths.Count()];
            faceIDs = new int[filePaths.Count()];
            if (filePaths.Count() == 0)
            {
                MessageBox.Show("Keine Bilder in der Datenbank vorhanden");
            }
            else
            {
                for (int i = 0; i < filePaths.Count(); i++)
                {
                    var faceImage = new Image<Gray, byte>(filePaths[i]);
                    string faceName = filePaths[i].Split('_')[1];

                    char[] charsToTrim = { '.', 'b', 'm', 'p' };
                    int faceID = Convert.ToInt32(filePaths[i].Split('_')[2].Trim(charsToTrim));

                    faceImages[i] = faceImage;
                    faceNames[i] = faceName;
                    faceIDs[i] = faceID;
                }
                /*Der EigenFaceRecognizer wird mit allen Bildern gefüttert 
                  die im Ordner "Face Collection" sind. Datenbank als Textdatei wird auch 
                  erstellt und danach wieder eingelesen.*/
                recognizer.Train(faceImages, faceIDs);
                recognizer.Write(@"Face Collection\database.txt");
                recognizer.Read(@"Face Collection\database.txt");
                MessageBox.Show("Algorithmus wurde mit den gespeicherten Bildern trainiert.");
            }
        }

    }
}

Visual Studio Offlineinstaller erstellen

In diesen Beitrag erkläre ich, wie man einen Offlineinstaller für Visual Studio 2019 erstellt.

Der Vorteil einer Offlineinstallation von Visual Studio ist die spezielle Auswahl der Pakete, die installiert werden sollen. So kann viel Speicherplatz eingespart werden.

Zuerst laden wir uns den Webinstaller von der Visual Studio 2019 Community Version herunter. Visual Studio 2019 Community

Im Download Ordner wird nun ein neuer Ordner mit dem Namen “vs2019” erstellt. Danach wird die Eingabeaufforderung mit Administratorrechten (cmd.exe) gestartet und es wird in den Download Ordner navigiert. Nun kann man folgenden Befehl eingeben um den Offlineinstaller zu erstellen.

vs_community.exe --layout "%userprofile%\Downloads\vs2019" --add Microsoft.VisualStudio.Workload.ManagedDesktop --lang de-DE

Parameter –layout: Dieser Parameter gibt an in welchen Order die Offlinedateien heruntergeladen werden sollen.

Parameter –add: Gibt die Pakete an, die heruntergeladen werden sollen. Liste aller Installationpakete.

Parameter –lang: Gibt an in welcher Sprache die Installationspakete heruntergeladen werden.

Liste der Sprachen:

Language-codeLanguage
cs-CZCzech
de-DEGerman
en-USEnglish
es-ESSpanish
fr-FRFrench
it-ITItalian
ja-JPJapanese
ko-KRKorean
pl-PLPolish
pt-BRPortuguese – Brazil
ru-RURussian
tr-TRTurkish
zh-CNChinese – Simplified
zh-TWChinese – Traditional

Nach dem herunterladen aller Pakete ist, alles bereit für die Offlineinstallation. Im Ordner “vs2017” befindet sich der Ordner “certificates“. In diesem Ordner befinden sich einige Zertifikate, die vor dem Ausführen der vs_setup.exe installiert werden müssen. Dazu werden alle Zertifikate markiert und mit dem Tastendruck “Enter” Installiet. Nun klickt solange auf den “Weiter” Knopf, bis alle Zertifikate installiert sind.

Danach kann man die vs_stup.exe ausführen um mit der Installation zu beginnen.

C# Beenden von Anwendung verhindern

In diesen Beitrag werde ich eine Anwendung programmieren, die das ungewollte schließen von Anwendungen verhindern soll.

Mechanismen um ungewolltes schließen der Anwendung zu verhindern:

  • Die Anwendung wird in Vollbildmodus gestartet
  • Anwendung verfügt über keine Statusleiste (kein Rahmen um das Fenster)
  • Alt+F4 und andere Tastenkombinationen werden außer Kraft gesetzt.
  • Beim Ausführen der Anwendung wird der Explorer beendet.
  • Strg+Alt+Entf um den Taskmanager aufzurufen wird verhindert.

Das fertige Projekt kann auch sofort Runtergeladen werden:

Win_Fullscreen.zip

!!!Wichtig: Um die Anwendung zu schließen einfach die Tasten Strg+Shift+Alt+Q gleichzeitig drücken.

Nachdem man ein neues Projekt erstellt hat, bearbeiten wir nun die Eigenschaften der Form, um den Rahmen und die Statusleiste der Form zu entfernen. Dazu wird die Eigenschaft FormBorderStyle auf None gesetzt.

Im nächsten Schritt werden wir dafür sorgen, dass die Anwendung sich im Vollbildmodus startet. Dazu wird die Eigenschaft WindowState auf Maximized gesetzt.

Nun brauchen wir noch 3 Events von der Form. Wir brauchen das Load, FormClosing und KeyDown Event. Jedes Event wird mit einem Doppelklick in den Code implementiert.

Einige Bibliotheken werden noch gebraucht:

using System.Diagnostics;

Nun widmen wir uns den Code zu, der im Load Event ausgeführt werden soll.

private void frmFullscreen_Load(object sender, EventArgs e)
        {
            //Verhindern, dass man den Task Manager bedienen kann. Beim Öffnen wird dieser in den Hintergrund gelegt. 
            ProcessStartInfo psii = new ProcessStartInfo(System.IO.Path.Combine(Environment.SystemDirectory, "taskmgr.exe"));
            psii.RedirectStandardOutput = false;
            psii.WindowStyle = ProcessWindowStyle.Hidden;
            psii.UseShellExecute = true;
            var processTaskMgr = Process.Start(psii);
            this.SendToBack();

            //Explorer abschalten. Startmenü erscheint nach dem beenden von explorer.exe auch nicht mehr. 
            var psi = new ProcessStartInfo("taskkill", "/IM explorer.exe /f");
            psi.CreateNoWindow = true;
            psi.UseShellExecute = false;
            Process.Start(psi);
        }

Im KeyDown Event wird folgender Code hinzugefügt:

private void frmFullscreen_KeyDown(object sender, KeyEventArgs e)
        {
            //Mit der Tastenkombination Strg+Shift+Alt+Q kann diese Anwendung geschlossen werden.
            if (e.KeyCode == Keys.Q && e.Control && e.Shift && e.Alt)
            {
                tastenkombinationerkannt = true;
                this.FormBorderStyle = FormBorderStyle.FixedToolWindow;
            }
        }

Im FormClosing Event wird dann folgender Code hinzugefügt:

private void frmFullscreen_FormClosing(object sender, FormClosingEventArgs e)
        {
            /*Daran hindern, dass die Form geschlossen werden kann. Außer man klickt auf den "Herunterfahren" Button 
oder die Tastenkombination Strg+Shift+Alt+Q wird ausgeführt.*/
            if (tastenkombinationerkannt == true)
            {
                //Explorer wieder einschalten. Startmenü erscheint nach dem start von explorer.exe auch wieder. 
                Process process = new Process();
                process.StartInfo.FileName = "C:\\Windows\\explorer.exe";
                process.Start();

                //Taskmanager freigeben
                var psi = new ProcessStartInfo("taskkill", "/IM Taskmgr.exe /f");
                psi.CreateNoWindow = true;
                psi.UseShellExecute = false;
                Process.Start(psi);
            }
            else
            {
                e.Cancel = true;
            }
        }

Der komplette Quellcode:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using System.Diagnostics;

namespace Win_Fullscreen
{
    public partial class frmFullscreen : Form
    {
        public bool tastenkombinationerkannt = false;
        public frmFullscreen()
        {
            InitializeComponent();
        }

        private void frmFullscreen_Load(object sender, EventArgs e)
        {
            //Verhindern, dass man den Task Manager bedienen kann. Beim Öffnen wird dieser in den Hintergrund gelegt. 
            ProcessStartInfo psii = new ProcessStartInfo(System.IO.Path.Combine(Environment.SystemDirectory, "taskmgr.exe"));
            psii.RedirectStandardOutput = false;
            psii.WindowStyle = ProcessWindowStyle.Hidden;
            psii.UseShellExecute = true;
            var processTaskMgr = Process.Start(psii);
            this.SendToBack();

            //Explorer abschalten. Startmenü erscheint nach dem beenden von explorer.exe auch nicht mehr. 
            var psi = new ProcessStartInfo("taskkill", "/IM explorer.exe /f");
            psi.CreateNoWindow = true;
            psi.UseShellExecute = false;
            Process.Start(psi);
        }

        private void frmFullscreen_KeyDown(object sender, KeyEventArgs e)
        {
            //Mit der Tastenkombination Strg+Shift+Alt+Q kann diese Anwendung geschlossen werden.
            if (e.KeyCode == Keys.Q && e.Control && e.Shift && e.Alt)
            {
                tastenkombinationerkannt = true;
                this.FormBorderStyle = FormBorderStyle.FixedToolWindow;
            }
        }

        private void frmFullscreen_FormClosing(object sender, FormClosingEventArgs e)
        {
            /*Daran hindern, dass die Form geschlossen werden kann. Außer man klickt auf den "Herunterfahren" Button 
oder die Tastenkombination Strg+Shift+Alt+Q wird ausgeführt.*/
            if (tastenkombinationerkannt == true)
            {
                //Explorer wieder einschalten. Startmenü erscheint nach dem start von explorer.exe auch wieder. 
                Process process = new Process();
                process.StartInfo.FileName = "C:\\Windows\\explorer.exe";
                process.Start();

                //Taskmanager freigeben
                var psi = new ProcessStartInfo("taskkill", "/IM Taskmgr.exe /f");
                psi.CreateNoWindow = true;
                psi.UseShellExecute = false;
                Process.Start(psi);
            }
            else
            {
                e.Cancel = true;
            }
        }
    }
}

C# Maus bewegen lassen

In diesen Beitrag zeige ich euch, wie man in C# und mit der Programmierumgebung Visual Studio ein kleines Programm schreiben kann, um die Maus auf eine gewünschte Position bewegen zu lassen. Dazu braucht man grundlegende Kenntnisse wie man mit Visual Studio arbeitet.

Wer das fertige Projekt runterladen möchte kann dies auch tun: Win_MoveMouse.zip

Der wichtigste Part im Code ist das Initialisieren und Importieren aus der user32.dll.

[DllImport("user32.dll")] 
public static extern void mouse_event(int dwFlags, int dx, int dy); 
private const int MOUSEEVENTF_LEFTDOWN = 0x02; 
private const int MOUSEEVENTF_LEFTUP = 0x04; 
private const int MOUSEEVENTF_RIGHTDOWN = 0x08; 
private const int MOUSEEVENTF_RIGHTUP = 0x10;

Um die Maus dann zu bewegen muss man nun nur noch ein Objekt vom Typen Cursor erstellen und ihm einen Punkt geben um den Mauszeiger zu der gewünschten Position bewegen zu lassen.

this.Cursor = new Cursor(Cursor.Current.Handle);
Cursor.Position = new Point(x, y);

Um  ein Mausklick auszuführen muss man folgenden Codeschnipsel verwenden.

mouse_event(MOUSEEVENTF_RIGHTDOWN, x, y);
mouse_event(MOUSEEVENTF_RIGHTUP, x, y);

Das erste Argument beschreibt welcher Button auf der Maus gedrückt oder losgelassen werden soll werden.
Das zweite und dritte Argument dient dazu auf welcher X- und Y-Position der folgende Mausklick ausgeführt erden soll.

Hier sieht man den ganzen Quellcode:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using System.Runtime.InteropServices;


namespace Win_MoveMouse
{
    public partial class frmMoveMouse : Form
    {
        public frmMoveMouse()
        {
            InitializeComponent();
        }
        //Inizalisierung um Mausklicks durchzuführen
        [DllImport("user32.dll")]
        public static extern void mouse_event(int dwFlags, int dx, int dy);
        private const int MOUSEEVENTF_LEFTDOWN = 0x02;
        private const int MOUSEEVENTF_LEFTUP = 0x04;
        private const int MOUSEEVENTF_RIGHTDOWN = 0x08;
        private const int MOUSEEVENTF_RIGHTUP = 0x10;

        private void btnBewegen_Click(object sender, EventArgs e)
        {
            int x;
            int y;
            int BildschirmHoehe;
            int BildschirmBreite;
            this.Cursor = new Cursor(Cursor.Current.Handle);

            //Werte in der TextBoxen von den X und Y-Koordinaten in Variablen speichern.
            x = Convert.ToInt32(txtXKoordinate.Text);
            y = Convert.ToInt32(txtYKoordinate.Text);

            //Bildschirmhöhe und Bildschirmbreite erkennen und in Variablen speichern.
            BildschirmHoehe = Screen.PrimaryScreen.Bounds.Height;
            BildschirmBreite = Screen.PrimaryScreen.Bounds.Width;

            if (x < 0 || x > BildschirmBreite)
            {
                MessageBox.Show("X Koordinate darf nicht kleiner als 0 oder größer als " + BildschirmBreite + " sein.");
            }
            else if (y < 0 || y > BildschirmHoehe)
            {
                MessageBox.Show("Y Koordinate darf nicht kleiner als 0 oder größer als " + BildschirmHoehe + " sein.");
            }
            else
            {
                //Cursor wird an die die zuvor eingetragenen X- und Y-Koordinaten verschoben.
                Cursor.Position = new Point(x, y);
                mouse_event(MOUSEEVENTF_RIGHTDOWN, x, y);
                mouse_event(MOUSEEVENTF_RIGHTUP, x, y);
            }
            
        }

        private void btnBeenden_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }
    }
}