لا يعمل ShowWindow USER32 كما هو متوقع
-
22-07-2019 - |
سؤال
وأنا باستخدام أسلوب 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 يدل .