Win 10 - Command-Window positionieren

  • C#
  • .NET (FX) 4.0

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Win 10 - Command-Window positionieren

    Moin Leute,
    ich habe ein Batch-Programm, das eine Console an der Windos Default Position öffnet.
    Dieses Console-Fenster möchte ich verschieben, dazu habe ich im Net diesen Code gefunden, um das HWND der Console zu bekommen.
    Zum Test habe ich "cmd" aufgerufen.

    Problem:
    Ich bekomme ein Handle zurück, aber das Fenster reagiert nicht, weder als x86 noch als x64.
    Ich nehme an, dass das wieder so ein W10 Effekt ist.
    Könnt Ihr den Code vielleicht mal unter W7 und W8 / W8.1 probieren?
    Weiß jemand von Euch, wie ich unter W10 das Handle auf die Console bekomme?
    Dies ist der Code, keine der eingebauten Möglichkeiten funktioniert:
    Spoiler anzeigen

    C#-Quellcode

    1. using System;
    2. using System.Runtime.InteropServices;
    3. using System.Windows.Forms;
    4. namespace WindowsFormsApplication1
    5. {
    6. public partial class Form1 : Form
    7. {
    8. class NativeMethods
    9. {
    10. internal const int SWP_NOSIZE = 0x1;
    11. internal const int SWP_NOMOVE = 0x2;
    12. internal const int SWP_NOZORDER = 0x4;
    13. [DllImport("user32.dll")]
    14. internal static extern IntPtr FindWindow(string hwndParent, string hwndChildAfter);
    15. [DllImport("user32.dll")]
    16. internal static extern IntPtr FindWindow(IntPtr hwndParent, IntPtr hwndChildAfter);
    17. [DllImport("user32.dll")]
    18. internal static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
    19. [DllImport("user32")]
    20. internal static extern int SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, int wFlags);
    21. }
    22. public Form1()
    23. {
    24. this.InitializeComponent();
    25. }
    26. private void button1_Click(object sender, EventArgs e)
    27. {
    28. this.SetWindowPos();
    29. }
    30. private void SetWindowPos()
    31. {
    32. string windowClass = "ConsoleWindowClass";
    33. string name = "Administrator: Eingabeaufforderung";
    34. #if true//false//
    35. IntPtr hWnd = NativeMethods.FindWindow(windowClass, name);
    36. #else
    37. IntPtr ptrHWnd = Marshal.StringToHGlobalAnsi(windowClass);
    38. IntPtr ptrName = Marshal.StringToHGlobalAnsi(name);
    39. IntPtr hWnd = NativeMethods.FindWindow(ptrHWnd, IntPtr.Zero);
    40. Marshal.FreeHGlobal(ptrHWnd);
    41. Marshal.FreeHGlobal(ptrName);
    42. #endif
    43. if (hWnd != IntPtr.Zero)
    44. {
    45. NativeMethods.MoveWindow(hWnd, 5, 5, 500, 350, false);
    46. //NativeMethods.SetWindowPos(hWnd, IntPtr.Zero, 5, 5, 0, 0, NativeMethods.SWP_NOSIZE | NativeMethods.SWP_NOZORDER);
    47. }
    48. }
    49. }
    50. }
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Auch wenn es Deine Win7/8-Frage nicht beantwortet: Habe Deinen Code unter Win10 probiert.
    Musste zwar die Zeile 41 in IntPtr hWnd = NativeMethods.FindWindow("ConsoleWindowClass", null); abwandeln, aber es ergab sich der gewünschte Effekt.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    VaporiZed schrieb:

    aber es ergab sich der gewünschte Effekt.
    Bewegung der Console?
    32 und oder 64 Bit?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Konsole wurde bewegt und in der Fenstergröße geändert.
    64 Bit
    Bilder
    • NachDemKlick.png

      104,73 kB, 1.440×900, 194 mal angesehen
    • VorDemKlick.png

      105,47 kB, 1.440×900, 180 mal angesehen
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @VaporiZed Das ist sehr merkwürden, ich hab das auf zwei Rechnern mit W10 nicht am funktionieren, egal, ob ich da die Titelzeile oder null übergebe. ;(
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    VaporiZed schrieb:

    Musste zwar die Zeile 41 in IntPtr hWnd = NativeMethods.FindWindow("ConsoleWindowClass", null); abwandeln, aber es ergab sich der gewünschte Effekt.

    Kann ich bestätigen - geht so.

    Getestet mit Windows 10 64Bit, Build 1607
    VisualStudio 2017
    AnyCPU / 23Bit / 64Bit
    Framework 4 und 4.62
    @VaporiZed @simpelSoft Danke fürs Testen.
    Offensichtlich gibt es "mehrere Arten von Consolen".
    • mit cmd im Startmenü Ausführen gestartet, da funktioniert das.
    • mit Shortcut in meinem Salamander als Administrator gestartet, Titelzeile "Administrator: Eingabeaufforderung" - geht nicht
    • von meinem Programm über Process. Start("ffmpg") - geht auch nicht.
    OK, muss ich mal ein wenig rumspielen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Bei Process.Start sollte man einen Rückgabewert erhalten.
    Dieser ist ein System.Diagnostics.Process welcher das Handle und auch die ID des gestarteten Prozesses enthält!
    Darüber sollte das finden und ansprechen des Fensters möglich sein!

    msdn.microsoft.com/de-de/libra….diagnostics.process.aspx

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Option Strict On
    2. Public Class Form1
    3. Dim _proc As Process
    4. Private Declare Function MoveWindow Lib "user32.dll" (ByValhWnd As IntPtr, ByVal X As Int32, ByVal Y As Int32, ByVal Width As Int32, ByVal Height As Int32, ByVal Repaint As Boolean) As Boolean
    5. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    6. _proc = Process.Start("cmd.exe")
    7. Debug.WriteLine("Handle: " & _proc.Handle.ToString & " - ID: " & _proc.Id.ToString & " - MainWindowHandle: " & _proc.MainWindowHandle.ToString)
    8. MoveWindow(_proc.MainWindowHandle, 200, 200, 400, 400, True)
    9. End Sub
    10. End Class

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Morrison“ ()

    @Morrison Die Console hat in diesem Sinne kein MainWindowHandle.

    C#-Quellcode

    1. Process pr = new Process();
    2. pr.StartInfo.FileName = "cmd.exe";
    3. pr.Start();
    4. MessageBox.Show(pr.MainWindowHandle.ToString());
    ==> "0"

    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „RodFromGermany“ ()

    Ich hab die Lösung gefunden:
    Spoiler anzeigen

    C#-Quellcode

    1. Process pr;
    2. private void button1_Click(object sender, EventArgs e)
    3. {
    4. pr = new Process();
    5. pr.StartInfo.FileName = "cmd.exe";
    6. pr.StartInfo.UseShellExecute = false;
    7. pr.StartInfo.RedirectStandardInput = true;
    8. pr.Start();
    9. System.Threading.Thread.Sleep(250);
    10. string command = @"C:\FFMPEG\bin\ffmpeg.exe ###"; // der Befehl halt
    11. pr.StandardInput.WriteLine(command);
    12. SetWindowPos(); // von oben
    13. }
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @Morrison Jou. :!:
    Nur funktioniert bei der Console das WaitForInputIdle() nicht, da muss man ein Sleep() reinbauen und schon redet die Nachbarin wieder mit mir.

    C#-Quellcode

    1. Process pr = new Process();
    2. pr.StartInfo.FileName = "cmd.exe";
    3. pr.Start();
    4. Sleep(250);
    5. MessageBox.Show(pr.MainWindowHandle.ToString());
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!