سؤال

وأنا باستخدام أسلوب ShowWindow من USER32 لإخفاء نافذة (CMD.EXE) من المستخدم (أساسا لمنعهم من إغلاقه). عندما يفتح المستخدم النموذج، يتم تشغيل هذه العملية، واختبأ، ثم عندما شكل تضيق قتل هذه العملية. ومع ذلك، عند فتح النموذج مرة أخرى، فإنه لا يخفي نافذة (وأحيانا لا أول مرة) يمكن للشخص أن يساعدني في هذا؟

    [DllImport("User32")]
    private static extern int ShowWindow(int hwnd, int nCmdShow);   //this will allow me to hide a window

    public ConsoleForm(Process p) {
        this.p = p;
        p.Start();
        ShowWindow((int)p.MainWindowHandle, 0);   //0 means to hide the window. See User32.ShowWindow documentation SW_HIDE

        this.inStream = p.StandardInput;
        this.outStream = p.StandardOutput;
        this.errorStream = p.StandardError;

        InitializeComponent();

        wr = new watcherReader(watchProc);
        wr.BeginInvoke(this.outStream, this.txtOut, null, null);
        wr.BeginInvoke(this.errorStream, this.txtOut2, null, null);
    }

    private delegate void watcherReader(StreamReader sr, RichTextBox rtb);
    private void watchProc(StreamReader sr, RichTextBox rtb) {
        string line = sr.ReadLine();
        while (line != null && !stop && !p.WaitForExit(0)) {
            //Console.WriteLine(line);
            line = stripColors(line);
            rtb.Text += line + "\n";

            line = sr.ReadLine();
        }
    }

    public void start(string[] folders, string serverPath) {

        this.inStream.WriteLine("chdir C:\\cygwin\\bin");
        //this.inStream.WriteLine("bash --login -i");
        this.inStream.WriteLine("");
    }

    private void ConsoleForm_FormClosed(object sender, FormClosedEventArgs e) {
        this.stop = true;
        try {
            this.p.Kill();
            this.p.CloseMainWindow();
        } catch (InvalidOperationException) {
            return;
        }
    }
هل كانت مفيدة؟

المحلول

وسيكون من الأسهل بكثير لهذه:

public ConsoleForm(Process p) {
        this.p = p;
        p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
        p.StartInfo.CreateNoWindow = true;
        p.Start();

        this.inStream = p.StandardInput;
        this.outStream = p.StandardOutput;
        this.errorStream = p.StandardError;

        InitializeComponent();

        wr = new watcherReader(watchProc);
        wr.BeginInvoke(this.outStream, this.txtOut, null, null);
        wr.BeginInvoke(this.errorStream, this.txtOut2, null, null);
    }

نصائح أخرى

هل راجعت سواء p.MainWindowHandle هو مقبض صالحة؟ يجب أن يكون غير صفرية، على أقل تقدير. حاول الاتصال IsWindow للتأكيد.

MSDN يقترح داعيا <ل أ href = "http://msdn.microsoft.com/en-us/library/system.diagnostics.process.waitforinputidle.aspx" يختلط = "نوفولو noreferrer"> WaitForInputIdle قبل التحقق MainWindowHandle. قد يكون الوصول إلى العقار قبل العملية الجديدة خلقت الإطار الخاص. الخاصية غير مستقرة بطبيعتها على أي حال، وذلك لأن العمليات لا يملك في الواقع فكرة نافذة "الرئيسي". يتم التعامل مع جميع النوافذ على حد سواء. إطار صافي ببساطة يعين الإطار الأول كما هو الرئيسي، ولكن العملية نفسها لا تحتاج للنظر في الامور بهذه الطريقة.

وأيضا، هل تعتبر ببساطة إخفاء عملية في البداية، بدلا من البدء بتشغيله ثم الاختباء بعد وقوعها؟ تعيين StartInfo خصائص عملية ل<أ href ل = "https://stackoverflow.com/questions/444517/user32s-showwindow-doesnt-act-as-expected#444527"> كما Scotty2012 يدل .

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top