Laden...

Beim Starten Fenster verstecken, aber später anzeigen?

Erstellt von -Hades- vor 15 Jahren Letzter Beitrag vor 15 Jahren 7.705 Views
-
-Hades- Themenstarter:in
171 Beiträge seit 2007
vor 15 Jahren
Beim Starten Fenster verstecken, aber später anzeigen?

Hallo,

ich setze einen Prozess per StartInfo.WindowStyle = ProcessWindowStyle.Hidden auf hidden. Das funktioniert auch, nur habe ich bis jetzt keinen Weg gefunden den Prozess wieder auf normal zu setzen ohne Ihn neu starten zu müssen, was natürlich totaler kappes ist.

Ich habe es dann mit der showwindow-Funktion aus der user32.dll versucht. Das Problem dabei ist, dass ich nicht genau abfangen kann wann der Prozess soweit ist versteckt zu werden. Das geht nur recht ömmelig per Thred.sleep() und wenn ich den Wert zu niedrig ansetze schlägt es manchmal fehl und der Hide-Befehl läuft ins leere. Also auch nichts gescheites.

Ich weiß nicht genau warum es anscheinend nicht vorgesehen ist einen einmal als hidden gestarteten Prozess nicht wieder sichtbar machen zu können (vielleicht Sicherheit) aber ich bin guten Mutes das hier jemand eine Lösung gefunden hat.
Ich wäre auf jeden Fall sehr dankbar.

Mit freundlichem Gruß -Hades-

Gelöschter Account
vor 15 Jahren

was genau willst du denn erreichen? das es ohne fenster startet und dann auf befehl ein fenster erscheint?

-
-Hades- Themenstarter:in
171 Beiträge seit 2007
vor 15 Jahren

Ja ganz genau, es soll versteckt starten, dann gebe ih ihm etwas Zeit und dann soll das Fenster erscheinen.
Also mit etwas Zeit geben meine ich schon das ich es auf einen Befehl hin erscheinen lasse.

Gruß -Hades-

Gelöschter Account
vor 15 Jahren

dann schau dir doch mal die Main methode deiner applikation an. dort musßt du ansetzen.

der weg, den du dir ausgedacht hast, ist der falsche.

-
-Hades- Themenstarter:in
171 Beiträge seit 2007
vor 15 Jahren

Hmm mich beschleicht das Gefühl das ich es nicht detailliert genug erklärt habe. Ich befürchte du meinst jetzt, dass ich eine Form meiner eigenen Applikation verstecken will. Der Prozess um den es sich handelt ist ein externes Programm.
Wenn ich jedoch falsch mit dieser Vermutung liege darfst du mir gerne einen Schubs in die richtige Richtung geben, da ich jetzt zwar nicht sehr lange drüber nachgedacht habe aber dennoch keine Ahnung habe was du andeutest...

Gruß -Hades-

Gelöschter Account
vor 15 Jahren

ch du willst das fenster einer externen anwendung verstecken?

das wird schwieriger. evtl was für pinvoke?

-
-Hades- Themenstarter:in
171 Beiträge seit 2007
vor 15 Jahren

Hmm ja habe direkt bei pinvoke geguckt. Wie gesagt ist da die Lösung es mit der showwindow Funktion der User32.dll zu machen. Das funktioniert ja auch, ich kann das Fenster auf Befehl verstecken und wieder sichtbar machen usw., nur muss ich dann wenn der Prozess zum ersten mal gestartet wird per Thred.sleep lange genug warten bis der Prozess soweit ist, ansonsten läuft der Befehl ins leere und der Befehl zum z.B. verstecken des Prozesses schlägt fehl. Und da es sich so verhält, dass manchmal 10 Millisekunden ausreichen und der PC manchmal noch soviel im Hintergrund macht das 200 Millisekunden nicht ausreichen, ist es schon eine eher naive Lösung.

Ich könnte naürlich einfach 5 Sekunden jedesmal warten aber dann habe ich ja das, was ich erreichen wollte verloren. Ich möchte ja das das Fenster von Anfang an unsichtbar ist. So wäre es dann immer für eine unbestimmte Zeitspanne sichtbar und wird dann unsichtbar.

Gelöschter Account
vor 15 Jahren

welche methoden hast du denn von pinvoke verwendet?

-
-Hades- Themenstarter:in
171 Beiträge seit 2007
vor 15 Jahren
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

Die habe ich benutzt.

Gelöschter Account
vor 15 Jahren

ich meinte eher, welchen weg du gegangen bist, um das fenster erstmal zu verstecken.

1.200 Beiträge seit 2007
vor 15 Jahren

Vielleicht hilft dir dieser Artikel weiter: How to: Make a Startup Windows Form Invisible

Shift to the left, shift to the right!
Pop up, push down, byte, byte, byte!

YARRRRRR!

-
-Hades- Themenstarter:in
171 Beiträge seit 2007
vor 15 Jahren

Also zunächst habe ich es wie gesagt mit den System.Diagnostics.Process-Mitteln versucht, also prozess.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;

Das klappt nur kann ichs nicht wieder erscheinen lassen (auch nicht mit der Windows API).

Und als zweites halt mit der ShowWindow aus der User32.dll

Ich glaube ich weiß nicht genau worauf du hinaus willst.

@GMLOD: Der Artikel hat mir leider nicht weitergeholfen, da es sich um ein externes Programm handelt welches ich verstecken möchte.

Gelöschter Account
vor 15 Jahren

du holst dir erstmal den process mit der Process-klasse.

da gibt es eine property MainwindowHandle.

darauf kannst du bauen und es einfach hidden machen mithilfe von pinvoke. dann klappt das show auhc.

-
-Hades- Themenstarter:in
171 Beiträge seit 2007
vor 15 Jahren

Aha, dicken Dank im voraus, werd ich direkt mal testen!

Ich meld mich was dabei rauskommt.

-
-Hades- Themenstarter:in
171 Beiträge seit 2007
vor 15 Jahren

Ach Quatsch, moment mal, jetzt bin ich zu früh in Euphorie verfallen 😁
Genau das abe ich ja schon getan. Mithilfe von pinvoke habe ich ja immer das MainwindowHandle versteckt und wieder angezeigt. Das löst leider nicht das Problem das ich nicht genau abfangen kann wann der Prozess soweit ist.

Gelöschter Account
vor 15 Jahren

ja aber wie bist du bei deiner lösung zu diesem handle gekommen?

-
-Hades- Themenstarter:in
171 Beiträge seit 2007
vor 15 Jahren

Ja über das MainWindowHandle Property vom Prozess...

-
-Hades- Themenstarter:in
171 Beiträge seit 2007
vor 15 Jahren

Also ich nehme an es hat wirklich niemand eine Lösung für das Problem...?

4.931 Beiträge seit 2008
vor 15 Jahren

Doch, ich -)


using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;

namespace ProcessTest
{
    class Program
    {
        [DllImport("user32.dll")]
        static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

        static readonly int SW_HIDE = 0;
        static readonly int SW_NORMAL = 1;

        static void Main(string[] args)
        {
            ProcessStartInfo startInfo = new ProcessStartInfo("Notepad.exe");
            startInfo.WindowStyle = ProcessWindowStyle.Minimized;

            Process process = Process.Start(startInfo);

            process.WaitForInputIdle();
            ShowWindow(process.MainWindowHandle, SW_HIDE);

            Thread.Sleep(3000);

            bool b = ShowWindow(process.MainWindowHandle, SW_NORMAL);
        }
    }
}

Wichtig ist WaitForInputIdle, da sonst das MainWindowHandle immer 0 ist!
(Hidden funktioniert nicht, da sonst immer das Handle 0 ist).

Als Test habe ich einfach den Thread für 3 Sekunden schlafen gelegt, ehe ich das Fenster dann anzeige, aber das kannst du natürlich auch auf Knopfdruck erledigen lassen.

Die weiteren ShowWindow-Konstanten (falls du noch mehr Aktionen mit dem Fenster machen möchtest) findest du unter http://www.pinvoke.net/default.aspx/user32/ShowWindow.html

-
-Hades- Themenstarter:in
171 Beiträge seit 2007
vor 15 Jahren

Hi Th69,

erstmal danke für die Antwort. Habs gerade getestet. Leider ist WaitForInputIdle nur für Programme zulässig die eine grafische Oberfläche haben. Das Programm was ich da starte hat leider nur eine Console...
Da bekomme ich dann eine Exception.

-
-Hades- Themenstarter:in
171 Beiträge seit 2007
vor 15 Jahren

Ich denke ich werde jetzt mit einem Kompromiss leben müssen.
Habe jetzt folgendes gemacht, mit Hilf der showwindow Funktion der user32 :


while (FindWindow("ConsoleWindowClass", null) == IntPtr.Zero)
{
       Thread.Sleep(10);
}
ShowWindow(meinprocess.MainWindowHandle, (uint)WindowShowStyle.Hide);

Das Fenster blitzt ganz kurz auf und ist dann unsichtbar bis ich es wiederhole.
Ich habe mit den Millisekunden etwas getestet. Bei 1 Millisekunde ist es schon öfters vorgekommen das das Fenster sichtbar blieb, bei 5 war es sehr selten und bei 10 ist es keinmal (aus 50 Testläufen) sichtbar geblieben.

Sollte dennoch jemand eine saubere Lösung für mich haben immer her damit 🙂

Gruß -Hades-