extern gestartete Anwendung in Vordergrund holen

  • VB.NET

Es gibt 24 Antworten in diesem Thema. Der letzte Beitrag () ist von VaporiZed.

    extern gestartete Anwendung in Vordergrund holen

    Moin!

    ich habe eine eigenständige Anwendung die läuft.

    Nun habe ich ein anderes Programm das über einen Aufruf diese Anwendung startet. Intern werden dann einige Parameter geprüft und dann wird ein Dialog geöffnet.

    Jetzt soll diese Anwendung in Vordergrund geholt werden.

    Mit TopMost=true in der Form habe ich es schon versucht. Ebenso mit

    VB.NET-Quellcode

    1. AppActivate("EBL GSE Dokumenten-Historie")


    in der der Form. Als Wert habe ich den Namen der Anwendung mal versucht, wie auch den oben geschriebenen Form-Titel.

    Alles leider erfolglos!

    Kann mir einer von Euch weiterhelfen?

    Gruß Jan
    @jan99 Gugst Du

    VB.NET-Quellcode

    1. SetForegroundWindow(hWnd As IntPtr)
    pinvoke.net/default.aspx/user32/setforegroundwindow.html
    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!
    Hallo Rod,

    danke für die Info. Das Problem ist nun nur, wie komme ich an hWnd. Ich habe mal in den Link von Dir geschaut und dabei ein Beispiel gefunden. Das habe ich dann auch nach vb.net konvertiert.

    Das Shared habe ich dann noch entfernt und bin jetzt bei diesem Code:

    VB.NET-Quellcode

    1. Public Function BringWindowToTop(ByVal windowName As String, ByVal wait As Boolean) As Boolean
    2. Dim hWnd As Integer = FindWindow(windowName, wait)
    3. If hWnd <> 0 Then
    4. Return SetForegroundWindow(CType(hWnd, IntPtr))
    5. End If
    6. Return False
    7. End Function
    8. Public Function FindWindow(ByVal windowName As String, ByVal wait As Boolean) As Integer
    9. Dim hWnd As Integer = FindWindow(Nothing, windowName)
    10. While wait AndAlso hWnd = 0
    11. System.Threading.Thread.Sleep(500)
    12. hWnd = FindWindow(Nothing, windowName)
    13. End While
    14. Return hWnd
    15. End Function


    Zusätzlich habe ich in der Form noch die Zeile

    VB.NET-Quellcode

    1. Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As IntPtr


    eingebaut. Egal was ich mache - es gibt nur Fehlermeldungen wie diese:



    ????

    Gruß Jan
    @jan99 Ohne dass ich jetzt alles ausprobiere:
    Überzeuge Dich zunächst, dass Deine Deklarationen korrekt sind.
    pinvoke.net ist da die richtige Adresse.
    API.FindWindow() hat da nen IntPtr als Rückgabewert.
    Wenn es sich bei Dir um ein externes Fenster handelt, klickere doch lieber die Prozesse durch:

    VB.NET-Quellcode

    1. Dim pr() = Process.GetProcessByName("Notepad")
    2. If pr.Length > 0 Then
    3. Label1.Text = pr(0).ToString()
    4. ' was mit pr(0) tun
    5. End If
    Und:
    In welcher Zeile Deines Codes kommt denn dieser Fehler?
    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!
    Deine Deklaration der Funktion FindWindow(...)

    jan99 schrieb:

    VB.NET-Quellcode

    1. hWnd = FindWindow(Nothing, windowName)
    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!
    Moin!

    langsam verlassen sie mich...

    Meines sieht jetzt komplett so aus:

    VB.NET-Quellcode

    1. Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    2. Public Function BringWindowToTop(ByVal windowName As String, ByVal wait As Boolean) As Boolean
    3. 'Dim hWnd As Integer = FindWindow(windowName, wait)
    4. Dim hWnd As Long = FindWindow()
    5. If hWnd <> 0 Then
    6. Return SetForegroundWindow(CType(hWnd, IntPtr))
    7. End If
    8. Return False
    9. End Function


    FindWindow wird jetzt aber noch mit



    angemerkt.

    Gruß Jan
    @jan99 Beratungsresistent?

    RodFromGermany schrieb:

    API.FindWindow() hat da nen IntPtr als Rückgabewert.
    ===========
    Was ist mit

    RodFromGermany schrieb:

    VB.NET-Quellcode

    1. Dim pr() = Process.GetProcessByName("Notepad")
    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!
    Hallo Rod,

    keines wegs Beratungsresistent - vielmehr nicht verstehen!

    API.Findwindow habe ich nicht eingesetzt, weil API angemerkt wurde und da hattest Du mir gesagt, dass es in meiner Deklaration steht. Das habe ich verstandne als die Zeile die auf das System zugreift.

    Das mit dem GetProcessByName habe ich auch ausprobiert. Auch schon ohne den richtigen Anwendungsnamen bekomme ich diese Meldung



    Nun verstehe ich noch weniger als vorher.

    Gruß Jan
    Ich gehe einen anderen Weg, um ein Programm in den Vordergrund zu holen.

    In meiner Sub Main():

    VB.NET-Quellcode

    1. Using mtex As Mutex = New Mutex(True, "Programmname")
    2. If mtex.WaitOne(TimeSpan.Zero, True) = True Then
    3. Application.Run(New frmMain())
    4. mtex.ReleaseMutex()
    5. Else
    6. NativeMethods.PostMessage(CType(NativeMethods.HWND_BROADCAST, IntPtr), NativeMethods.WM_SHOWME, IntPtr.Zero, IntPtr.Zero)
    7. End If
    8. End Using


    in meiner Hauptform:

    VB.NET-Quellcode

    1. ​Protected Overrides Sub WndProc(ByRef msg As Message)
    2. If msg.Msg = NativeMethods.WM_SHOWME Then
    3. ShowMe()
    4. End If
    5. MyBase.WndProc(msg)
    6. End Sub
    7. Private Sub ShowMe()
    8. If Me.WindowState = FormWindowState.Minimized Then
    9. Visible = True
    10. Me.WindowState = FormWindowState.Normal
    11. End If
    12. Me.TopMost = True
    13. Me.TopMost = Not Me.TopMost
    14. End Sub


    VB.NET-Quellcode

    1. Imports System.Runtime.InteropServices
    2. Public Class NativeMethods
    3. Public Const HWND_BROADCAST As Integer = &HFFFF
    4. Public Shared ReadOnly WM_SHOWME As Integer = RegisterWindowMessage("WM_SHOWME")
    5. Public Shared ReadOnly WM_OPEN As Integer = RegisterWindowMessage("WM_OPEN")
    6. <DllImport("user32")>
    7. Shared Function PostMessage(hwnd As IntPtr, msg As Integer, wparam As IntPtr, lparam As IntPtr) As Boolean
    8. End Function
    9. <DllImport("user32", CharSet:=CharSet.Unicode)>
    10. Shared Function RegisterWindowMessage(message As String) As Integer
    11. End Function
    12. End Class​


    Vielleicht hilft dies ja.

    jan99 schrieb:

    diese Meldung
    Bei mir unter WinForm läuft das.
    Was hast Du für ein Framework?
    Was hast Du für einen Projekt-Typ?
    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!
    Moin!
    ich dachte nun, dass ich einen ganz einfachen Weg gefunden hatte zum Ziel:

    VB.NET-Quellcode

    1. Private Sub frm_GrundstDoku_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    2. Me.MaximizeBox = True
    3. End Sub


    Aber das hat nur funktioniert, wenn ich vorher eine Msgbox anzeigen lasse.

    VB.NET-Quellcode

    1. Private Sub frm_GrundstDoku_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    2. ' Dialog in den Vordergrund bringen - wichtig für die Verbindung mit MapEdit
    3. MsgBox("adadf")
    4. Me.MaximizeBox = True
    5. End Sub


    Kann mir das einer erklären oder bin ich vielleicht auf dem richtigen Weg und habe nur etwas noch falsch gemacht?

    Muss ich das vielleicht nur noch in ein anderes Ereignis legen?

    Gruß Jan
    @jan99 Was ist das für ein anderes Programm?
    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!
    hi !

    das andere Programm, wenn ich die richtige Stelle meinst auf die Du Dich beziehst, ist eine GIS-Programm das über

    VB.NET-Quellcode

    1. Me.Application.External.ShellExecute(Function(result As Boolean) Nothing, Command)


    Meine Konsolenanwendung, von der wir hier die ganze Zeit "sprechen" aufrufen.

    Gruß Jan
    @jan99 Lass mal etwas mehr Information gucken.
    Hast Du das Handle auf das Programm oder eine Process-Instanz?
    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!
    @jan99 Dein Programm A will, dass Dein Console-Programm B in den Vordergrund kommt.
    "Dein Programm" bedeutet, dass Du von diesem Programm die Quellen hast.
    =======
    Wissen die Programme während der Laufzeit was voneinander?
    Hat Programm A Programm B gestartet?
    usw.
    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!
    So kann man es beschreiben.
    Der Source von beiden ist verfügbar.
    Mein Ziel ist eigentlich "nur", dass Programm B bei seiner Ausführung in Vordergrund kommt und nicht nur in der Task-Liste erscheint. Deswegen kam ich auf den Gedanken mit Me.Maxi...

    Gruß Jan
    Auch für den Fall, dass ich jetzt querschieße, aber ich hadere bei Post#3. Die Fehlermeldung dürfte dadurch bedingt sein, dass Du eine eigene Function FindWindow geschrieben hast, die ebenfalls 2 Parameter nimmt und bei der Du den 1. Parameter auf Nothing setzt. Da könnte der Compiler ins Straucheln geraten. Probier es mal ohne Deine eigene Function. Oder besser: benenn sie um. Denn wenn Du notepad ohne Dokument öffnest, muss mit folgendem Code was in hWndAsText stehen:

    VB.NET-Quellcode

    1. Imports System.Runtime.InteropServices
    2. Public Class Form1
    3. <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> Private Shared Function FindWindow(ClassName As String, WindowName As String) As IntPtr : End Function
    4. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    5. Dim hWnd = FindWindow(Nothing, "Unbenannt - Editor")
    6. Dim hWndAsText = hWnd.ToString
    7. Stop
    8. End Sub
    9. End Class

    Effektiv Dein Fensterhandle. Und das wird dann für SetForegroundWindow genutzt.

    ##########

    Bei Post#7 verwendest Du FindWindow ohne Parameter. Da kann nix gefunden werden. Und Deine Deklaration jener Function ist auch ... suboptimal, weil Du z.B. den Funktionsrückgabewert am Ende als Long deklarierst. Das ist VB6. Du musst IntPtr nehmen (so wie ich jetzt).
    Bilder
    • FindWindow.png

      13,14 kB, 1.219×183, 228 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.

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