Zum Inhalt springen

Gateway_man

Mitglieder
  • Gesamte Inhalte

    1.162
  • Benutzer seit

  • Letzter Besuch

Alle Inhalte von Gateway_man

  1. Hi, sry :upps. Wie sollt ihr mir helfen können wenn ich die Fehler nicht poste. Wobei das mit der Kristallkugel wäre bestimmt auch interessant geworden . Ich kopiere mal die Liste. Bei nähere Betrachtung habe ich selbst schon ein paar Theorien aufgestellt. Beispielsweise: Kann es sein das das installierte Win7 Sdk über eigene Gdi Header verfügt er jetzt zwei mal die Gdi header eingebunden werden?! lg Gateway
  2. Hi, Beispiel das ich meinte. Zum anderen hab ich das bereits probiert. Es ändert sich nichts. Es sind immernoch 204 Fehler. #include<Windows.h> #include <GdiPlus.h> lg Gateway
  3. Hallo leute, ich wollte mich mal etwas vertrauter machen mit den Gdi Klassen die Systemseitig schon bereitgestellt werden. Aus diesem Grunde hab ich mir mal ein paar beispiele reingezogen. Überall wird für den Einstieg lediglich der Header GdiPlus importiert. Aber immer wenn ich das File Include kassiere ich 200 Fehler wegen falschen Klammer und sonstigen Syntaktischen schmarn. Ich versteh das jetzt nicht wirklich. Ich hab noch nichtmal was anderes getippt. #include <GdiPlus.h> #pragma once class GdiTest { public: GdiTest(void); ~GdiTest(void); }; Schon hagelt es 204 Fehler. Zu den Projekteinstellungen. Ich verwende weder Atl noch MFC und auch nicht die Clr. Weiß jemand warum das so ist. Fehlen vielleicht noch ein paar Includes vor GdiPlus? Aber wenn ja warum soll es dann in den Tutorials angeblich funktionieren. lg Gateway
  4. Genau das mach ich momentan Deswegen funktionierts jetzt ja auch . So sieht ein beispielaufruf in C# aus. Image result = null; IntPtr ptr = GetDesktopImageExt(biPlanes, biBitCount, (int)compression, biSizeImage, biXPelsPerMeter, biYPelsPerMeter, biClrUsed, biClrImportant); if (ptr != IntPtr.Zero) { result = (Image)Image.FromHbitmap(ptr).Clone(); ReleaseHBitmap(ptr); if (includeCursor) result = Utility.ImageUtil.CaptureScreen.IncludeCurrentCursor(result); } return result; Lg und Danke Gateway
  5. Sry ich meinte den Stack Frame der Funktion die ich aufrufe . Die Bitmap daten befinden sich auf dem Heap das ist schon klar. Bist du dir da sicher? Ich hab nämlich doch einen AccessViolation Exception erhalten. Nur wird die in System.Drawing gehandelt. Steht also lediglich im Output fenster. Das habe ich bereits versucht. Jedoch habe ich dann eine Null Reference Exception seitens .NET bekommen. Ist ja auch irgendwo klar. Wenn ich innerhalb der Cpp Funktion das Bitmap erstelle um es am Ende der Funktion wieder freizugeben und das .NET dann versuch mit dem Pointer die Bitmap daten abzugreifen muss es ja unweigerlich krachen. lg Gateway
  6. Hi, hat sich erledigt. Es verhält sich so wie ich es mir dachte. Ich hätte es doch testen sollen bevor ich den Thread verfasste. Aber trotzdem sehr lehrreich. Es sieht wie folgt aus: Das Bitmap wird innerhalb des Stack Frames der Cpp Funktion erstellt. Dieser Stack Frame befindet sich natürlich innerhalb des Stack Frames der Cpp Library. Das .NET greift den Pointer ab. Mit der .NET Funktion Image.FromHBitmap wird die Struktur Image gefüllt mit den referenzierten Daten die immernoch innerhalb des Stack Frames der Cpp Funktion liegen. Wenn ich ein nun im .NET ein Dispose() auf das Image Objekt absetzte passiert nichts, da das Framework keine Zugriffsberechtigung auf den Speicherbereich meiner Cpp Library hat. Jetzt habe ich der Cpp Library noch eine Funktion spendiert die ein HBITMAP als parameter verlangt. Innerhalb dieser Funktion mach ich nun ein DeleteObject(BitmapPointer). Diese Funktion pInvoke ich im .Net nachdem ich das Image geklont habe. Und siehe da keine Problem mehr ...... lg Gateway
  7. Hi leute, da mir der Winapi Wrapper im .NET an sich zu langsam war beziehungsweise ich an die performance grenzen vom .NET gestoßen bin, habe ich mich entschieden das ganze innerhalb einer Cpp dll abzuwickeln und im .NET mit dem Result zu arbeiten. Das heißt der "Screenshot" sowie diverse algorithmen zum verkleinern und konvertieren wurden in die Cpp dll ausgelagert. Die C# dll ruft dann die entsprechende Funktion auf und bekommt einen Pointer (HBITMAP) zurück der auf das Bild zeigt. Den erhaltenen Performanceschub will ich nichtmehr missen (pure .NET 20 fps / Cpp 30 fps). Allerdings bringt mir das kein Stück wenn ich nach 10 Sekunden im .NET ne Out of Memory Fehlermeldung erhalte. Jetzt bin ich mir aber nicht so ganz sicher woran das liegt. Da das Image innerhalb des StackFrames meiner cpp dll generiert wird, vermute ich das das .NET dieses Objekt nicht freigeben kann. Aber wenn das stimmen würde, hätte ich ja längt eine MemoryViolation Exception erhalten. Was denkt ihr woran das liegen kann? Hier mal eine simple Funktion zum generieren eines normalen Bitmaps (auch hier tritt der fehler auf) in der cpp dll. _extern HBITMAP GetDesktopImageExt(){ HWND capture = GetDesktopWindow(); if(!IsWindow(capture)) return NULL; RECT rect; GetWindowRect(capture, &rect); size_t dx = rect.right - rect.left; size_t dy = rect.bottom - rect.top; BITMAPINFO info; info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); info.bmiHeader.biWidth = dx; info.bmiHeader.biHeight = dy; info.bmiHeader.biPlanes = 1; info.bmiHeader.biBitCount = 24; info.bmiHeader.biCompression = BI_RGB; info.bmiHeader.biSizeImage = 0; info.bmiHeader.biXPelsPerMeter = 0; info.bmiHeader.biYPelsPerMeter = 0; info.bmiHeader.biClrUsed = 0; info.bmiHeader.biClrImportant = 0; HBITMAP bitmap = 0; BYTE* memory = 0; HDC device = GetDC(capture); bitmap = CreateDIBSection(device, &info, DIB_RGB_COLORS, (void**)&memory, 0, 0); ReleaseDC(capture, device); if(!bitmap || !memory) return NULL; HDC winDC = GetWindowDC(capture); HDC memDC = CreateCompatibleDC(winDC); SelectObject(memDC, bitmap); //HGDIOBJ obj = SelectObject(memDC, bitmap); BitBlt(memDC, 0, 0, dx, dy, winDC, 0, 0, SRCCOPY); //DeleteObject(obj); DeleteDC(memDC); ReleaseDC(capture, winDC); return bitmap ; } Möglicherweise hab ich auch einfach ein Release/Delete vergessen... Ich steh grad ein wenig auf dem Schlauch. Ich hatte mir kurzeitig üblegt ob ich eine externe Funktion definiere, welcher ich den Pointer übergebe und das HBITMAP wieder innerhalb der Cpp dll release. Ach keine Ahnung irgendwie ist grad alles leer im oberstübchen... lg Gateway
  8. Hi, super danke dir. Der Aufruf liefert keinen Fehler mehr zurück. Jetzt hab ich nurnoch das Problem das das HBITMAP falsch ist. Aber gut das ist vermutlich ein Fehler in der cpp lib. lg Gateway
  9. Hi, ich verzweifle grade an einem Pinvoke und hab schon diverse Dinge ausprobiert. Aktuell sieht das so aus. Funktion aus der dll die Invoked werden soll: extern "C" __declspec(dllexport) HBITMAP GetSubRect(int x, int y, int witdh, int height) { //ein paar Dinge... } Das ist der letzte stand der C# Signatur. Die auch Fehlschlägt... private static extern IntPtr GetSubRect([MarshalAs(UnmanagedType.I4)] int x, [MarshalAs(UnmanagedType.I4)] int y, [MarshalAs(UnmanagedType.I4)] int witdh, [MarshalAs(UnmanagedType.I4)] int height); Der Fehler der beim Aufruf auftritt sieht wie folgt aus: Leider mach ich das verhältnismäßig selten und kenne mich daher nicht so gut aus. Sieht einer von euch den Fehler? lg Gateway
  10. Ich will da jetzt nicht zu sehr ins Detail gehen da es zu lange dauern würde. Es ist Verwaltungsprogramm. Nein weil das Programm zusätzlich über Serverfunktionalitäten verfügt. Das heißt Client XY verbindet sich mit der Anwendung und holt/sendet Informationen. Letztendlich könnte man jetzt sagen, warum hast du das ganze nicht strikter getrennt und die Server Funktionen in ein eigenes Projekt ausgelagert. Ich kann nur eines sagen.Im Nachhinein ist man immer schlauer . Zumal ist diese Komponente extrem klein und ich hatte ehrlich gesagt keine Lust extra für die zwei Klassen noch ein ein neues Projekt anzulegen das ich dann immer weiter mitpflegen muss. Ich wusste jetzt nicht wie ich es nennen sollte. Ich meine vergleichbare Funktionalitäten wie rdp. Das heißt ein Modul des Programm ermöglicht mir Remote Eingaben und überträgt mir den Bildschirm. Ich wollte eigentlich das gleiche Verhalten wie bei Remote Desktop. Das heißt: Du gibts die Daten ein und verbindest dich. Dann öffnet sich ein Dialog in dem der User den Windows Benutzer sowie das Passwort einträgt. Dann wird auf der Remote Maschine eine Session gestartet und du siehst/steuerst dann die Session. Ich weiß. Remote Desktop läuft als Service. Jedoch ist diese Funktionalität nur ein bruchteil des Programmes und wie schon gesagt. Das umschreiben würde mich mind. zwei Wochen kosten. Diese Zeit habe ich nicht. Deswegen habe ich gefragt ob jemand eine Funktion im .NET Framework kennt die mir das ermöglicht. Letztendlich ist es doch eine Win32 Funktion gewesen und das Problem ist so gelöst wie es mir am besten gefällt . Jetzt wird geprüft ob der Rechner gesperrt oder abgemeldet ist. Ist das der Fall, sendet das Servermodul dem Clientmodul eine Authentifizierungsanfrage. Der User tippt das brav ein, überträgt das dem Servermodul und das Servermodul setzt ein Logonuser ab und prüft das handle das es bekommt. Wenn es gültig ist, war die Anmeldung erfolgreich und schon kanns weitergehn. Um die Sicherheit muss ich mir kein Kopf machen da die komplette Kommunikation mit einer Symmetrischen 128 bit Verschlüsselung gesichert wurde. lg Gateway
  11. So ich hab gefunden wonach ich gesucht habe. advapi32.logonuser Die WinApi ist in der Tat ein Geschenk des Himmels . lg Gateway
  12. Dann geh ich mal genauer drauf ein. Ich habe eine Anwendung. Diese Anwendung wird immer unter dem selben Benutzer ausgeführt. Nehmen wir mal an es läuft auf meinem Rechner. Es kommt hin und wieder vor das ich unterwegs bin und den Rechner aus diesen gründen Sperre. Nun möchte ich von unterwegs kurz mit der Instanz des Programmes auf meinem Rechner arbeiten. Aus diesem Grund verfügt das Programm über Rdp Funktionalitäten. Was ich machen will ist folgendes. Ich verbinde mich per Client mit meiner Anwendung die auf meinem Rechner läuft. Diese soll prüfen ob der Rechner gesperrt ist. Wenn das der Fall ist soll diese den Rechner entsperren bevor die rdp session initialisiert wird. Ich weigere mich zu glauben das nur ein Service in der Lage ist einen Userlogin zu starten. Irgendwo in den untiefen der Windows Api gibt es sicherlich eine Funktion die ich dazu invoken kann. Ich könnte mich sogar vorstellen das das .Net Framework schon Funktionen dafür bereitstellt. Es soll natürlich auch funktionieren wenn der User abgemeldet ist. Ich hab das schon getestet. Wenn ich abgemeldet bin läuft die Anwendung im Hintergrund weiter. (Sie ist über Netzwerk erreichbar). Lg Gateway
  13. Ich habe nicht gesagt, das das Programm ohne Interaktion auskommt. Es soll per direkter Interaktion sowie Remote Steuerbar sein. Aus diesem Grunde verfügt das Programm über Remote Desktop funktionalitäten. Nun muss ich jetzt nurnoch das obige Problem lösen. lg Gateway
  14. Meinst du Windows Service? Wenn ja, das ist kein Service Projekt. Und es umzuschreiben ist keine Option, da es schon sehr umfangreich ist. Zumal ist die GUI unabdinglich und soweit ich weiß haben Windows Services keine Oberfläche. Es zu ändern würde mich zwei Wochen kosten die ich nicht investieren kann und auch nicht möchte. lg Gateway
  15. Hi leute, weiß einer von euch wie man einer Benutzer Session über code startet. Das programm bekommt quasi die Windows benutzerdaten während kein Windows user angemeldet ist. Jetzt soll das Programm den erhaltenen Benutzer anmelden. Ich hab schonmal gesucht und fand nur "skurile" Registry Lösungen. Gibts da keine native WinApi Funktion oder möglicherweise sogar eine managed .NET Funktion? Lg Gateway
  16. Ah okay. Kennst du zufällig eine ApiFunktion mit der ich den kompletten Bildschirmbereich für das bild erfassen kann? Ich kann ja dannach mit BitBlt den entsprechend relevanten Bereich herauskopieren. Alternativvorschläge sind auch erwünsch . Wichtig für mich ist, das das ganze über pInvoke geschieht. lg Gateway
  17. Hi leute, gleich noch ein zweites Problem. Ich möchte Screenshots über die WinApi machen. Beim dem Primary Screen ist das kein Problem. Für diesen hol ich mir das Handle über GetDesktopWindow aus der User32.dll. Das klappt auch wunderbar. Allerdings möchte ich auch weitere Screens supporten. Ich bin dann auf EnumDisplayMonitors gestoßen. Die Funktion liefert mir im Grunde schon alle Screens zurück, jedoch ist das Handle Invalid. Ich hab das Handle meines Hauptbildschirmes das ich mit EnumDisplayMonitors mit dem Handle verglichen, das ich mit GetDesktopWindow bekomme. Sie sind unterschiedlich (aber kein Zero). Und wenn ich dann natürlich ein Screenshot machen möchte sagt mir GetLastError das das Handle Invalid ist. Das ist die Klasse die mir die Informationen über alle MonitorDevices geben soll: public sealed class MonitorIdentifier { #region Fields private int counter = 0; private int maxDevices = System.Windows.Forms.Screen.AllScreens.Count(); private CloneableList<ScreenDevice> availableScreens = null; private AsyncStateChanged asyncResult = null; USER32.MonitorEnumDelegate med; #endregion public MonitorIdentifier() { med = new USER32.MonitorEnumDelegate(EnumDisplayMonitorsCallBack); } public MonitorIdentifier(AsyncStateChanged result) { med = new USER32.MonitorEnumDelegate(EnumDisplayMonitorsCallBack); asyncResult = result; if (asyncResult == null) throw new InvalidOperationException("AsyncResult can't be null!"); } #region Public Functions public bool BeginEnumMonitors() { if (AsyncResult == null) throw new InvalidOperationException("AsyncResult can't be null!"); else return USER32.EnumDisplayMonitors(IntPtr.Zero, IntPtr.Zero, med, IntPtr.Zero); } #endregion #region Properties public AsyncStateChanged AsyncResult { get { return asyncResult; } set { asyncResult = value; } } #endregion #region Private Functions private bool EnumDisplayMonitorsCallBack(IntPtr hMonitor, IntPtr hdcMonitor, ref NativeStructures.RECT lprcMonitor, IntPtr dwData){ counter++; IntPtr ptr = Utillity.WinApi.USER32.GetDesktopWindow(); NativeStructures.MonitorInfo mi = new NativeStructures.MonitorInfo(); mi.size = (uint)Marshal.SizeOf(mi); bool success = USER32.GetMonitorInfo(hMonitor, ref mi); if (availableScreens == null) { availableScreens = new CloneableList<ScreenDevice>(); } if (success) { ScreenDevice dev = new ScreenDevice(); dev.mInfo = mi; dev.hMonitor = hMonitor; dev.dwData = dwData; dev.hdcMonitor = hdcMonitor; availableScreens.Add(dev); } if (counter == maxDevices) { asyncResult.Invoke(this, new object[] { availableScreens.Clone() }); counter = 0; availableScreens.Clear(); availableScreens = null; } return success; } #endregion } Das ist die ScreenDevice Structure: public struct ScreenDevice { #region Fields public Utillity.NativeStructures.MonitorInfo mInfo; public IntPtr hMonitor; public IntPtr hdcMonitor; public NativeStructures.RECT Rect; public IntPtr dwData; #endregion }; Das ist die MonitorInfo Structure: [StructLayout(LayoutKind.Sequential)] public struct MonitorInfo { public uint size; public RECT monitor; public RECT work; public uint flags; }; Die User32 Signaturen sehen bei mir so aus: [DllImport("user32.dll")] public static extern bool EnumDisplayMonitors(IntPtr hdc, IntPtr lprcClip, MonitorEnumDelegate lpfnEnum, IntPtr dwData); [DllImport("user32.dll")] public static extern bool GetMonitorInfo(IntPtr hmon, ref NativeStructures.MonitorInfo mi); Definition des MonitorEnumDelegate: public delegate bool MonitorEnumDelegate(IntPtr hMonitor, IntPtr hdcMonitor, ref NativeStructures.RECT lprcMonitor, IntPtr dwData); Das AsyncStateChanged Delegate ist eigentlich nicht relevant aber falls es jemand wissen möchte wie es definiert wurde: public delegate void AsyncStateChanged(object sender, object[] data); Ein Beispielaufruf sieht so aus: public partial class Form1 : Form { private ScreenDevice dev = new ScreenDevice(); private Utillity.Templates.CloneableList<Utillity.Devices.ScreenDevice> screens = null; private Utillity.Devices.MonitorIdentifier monitoridentifier = null; public Form1() { InitializeComponent(); monitoridentifier = new Utillity.Devices.MonitorIdentifier(new Utillity.AsyncStateChanged(AsyncFinished)); monitoridentifier.BeginEnumMonitors(); } private void AsyncFinished(object sender, object[] data) { if (data != null) { screens = (Utillity.Templates.CloneableList<Utillity.Devices.ScreenDevice>)data[0]; //dev = screens.Where(P => P.mInfo.monitor.Left > 0).ToList()[0]; dev = screens[1]; } private void CaptureScreen() { Bitmap bmp; if (dev.hMonitor != IntPtr.Zero) bmp = (Bitmap)Utillity.ImageUtil.CaptureScreen.CaptureWindow(dev.hMonitor); else bmp = Utillity.ImageUtil.CaptureScreen.GetDesktopImage(); if (bmp != null) { pictureBox1.Image = bmp; } } } Um das Wertetechnisch hier mal zu erfassen. Laut GetDesktopWindow hat mein Primärer Desktop das handle 65552. Laut EnumDisplayMonitors hat mein Primärer Desktop das handle 65537. Das handle das ich über GetDesktopWindow() ist gültig, hingegen EnumDisplayMonitors ein ungültiges Handle zurückgibt. Hat jemand eine Idee? lg Gateway
  18. Vielen Dank, aber ich werd mir was saueres Überlegen .
  19. Hi, Syntax highlighting wäre eine cooles Future . Da Ihr das Forum aber nicht selbst geschrieben habt, weiß ich nicht ob das ein schnell umzusetztendes Ziel wäre. Beziehungsweise ob Ihr da überhaupt selbst Hand anlegen dürft... Ich glaube mich daran erinnern zu können, das hier mal jemand was von kostenpflichtiger Forensoftware gesagt hat. Wenn die Lizenz Änderungen zulässt bin ich mir eigentlich auch fast sicher, das Ihr Hilfe von einigen Usern erhalten würdet . lg Gateway
  20. Ich dachte eigentlich das es beim Using so geregelt ist, das nach dem Codeblock-Ende des Usings der Stream automatisch freigegeben wird. Daher hab ich das ja auch nicht gemacht, da die Konvertierungsfunktion als Result das Image Objekt liefert. Verstehst du was ich meine? public static Image ConvertTo(ImageFormat format, Bitmap bmp) { Image result = null; try { if (bmp != null) { using (MemoryStream mem = new MemoryStream()){ bmp.Save(mem, format); result = Image.FromStream(mem); mem.Flush(); //Innerhalb ist der MemoryStream gültig } //Außerhalb ist er nichtmehr gültig und wird freigegeben //Da ich aber mit dem ResultImage arbeiten möchte ist das ungünstig. } } catch { } return result; } So jetz habe ich Gewissheit. lg Gateway
  21. Okay das ist kurios. Ich hab den Memory Stream mal nicht geschlossen und siehe da es funktioniert?!? Warum diese Abhängigkeiten existieren weiß ich nicht aber naja gut es funktioniert, auch wenn ich nicht glücklich darüber bin den MemoryStream offen lassen zu müssen.
  22. Guten Morgen, ich konvertiere momentan Bilder und will mir letztendlich das byte[] Array der konvertierten Bilder krallen um diese zu verarbeiten. Allerdings bekomme ich bei der Save Methode immer eine System.Runtime.InteropServices.ExternalException. Unglücklicherweise wird die Exception in der Image Klasse abgefangen und somit bekomme ich keine richtigen Informationen darüber was falsch lief. Es steht lediglich im Output: Eine Ausnahme (erste Chance) des Typs "System.Runtime.InteropServices.ExternalException" ist in System.Drawing.dll aufgetreten. Ich finde das sehr seltsam. Die Formatänderungen an den Bildern funktionieren aber. Das habe ich bereits überprüft. Hier sind die Funktionen die ich für die Konvertierung nutze: public static Image ConvertTo(ImageFormat format, Bitmap bmp) { Image result = null; try { if (bmp != null) { MemoryStream mem = new MemoryStream(); bmp.Save(mem, format); result = Image.FromStream(mem); mem.Flush(); mem.Close(); mem.Dispose(); } } catch { } return result; } Für die gleichzeitige Änderung der Bildquallität nutze ich folgende Funktion: public static Image ConvertTo(ImageFormat format, long quallity, Bitmap bmp) { Image result = null; MemoryStream mem = new MemoryStream(); EncoderParameters para = new EncoderParameters(1); EncoderParameter spara = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quallity); ImageCodecInfo info = GetEncoder(format); if (info != null) { try { para.Param[0] = spara; bmp.Save(mem, info, para); result = Image.FromStream(mem); mem.Flush(); mem.Close(); mem.Dispose(); } catch { } } return result; } Um das ByteArray zu erhalten nutze ich folgende Funktion: public static byte[] Image2Byte(Image img) { byte[] result = null; if (img != null) { try { MemoryStream mem = new MemoryStream(); img.Save(mem,img.RawFormat); //Nach img.Save steigt er aus und //im Output Fenster wird die Exception protokolliert. result = mem.GetBuffer(); mem.Flush(); mem.Close(); mem.Dispose(); } catch { } } return result; } Ich habe auch bereits andere Überladungen von Save() ausprobiert. Das Ergebnis ist das selbe . Ebenfalls hab ich es mit unterschiedlichen Format auspropiert. Alles ohne Erfolg. Kennt jemand das Verhalten? lg Gateway
  23. Danke Klotzkopp. Das hatte ich völlig vergessen. Jetzt funktionierts. lg Gateway
  24. Ich würde so einiges an der Software ändern, allerdings umfasst dieses Programm eine exe und 350 dll's deren Abhängigkeiten ich nur erahnen kann. Und letzendlich will es keiner bezahlen xD. Das ist das tolle am Scrum Prozess. Der Entwickler hat ein minimales Mitspracherecht. Ich bekomme von den PM's (Product Manager) die Userstories die sich die Kunden wünschen bzw. wofür diese bereit sind Geld auszugeben und dann muss ich das realisieren. Es gibt hier keine Spielraum zumal das dann mindestens eine Task wäre, die in etwa 30 Manntage kosten würde (und kann dann nichtmal als Future neu verkauft werden...). Ja so ist das . lg Gateway PS: Nochmal zurück zum Thema. Sieht da jemand nen Fehler?

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...