2016-04-30 18 views
8

Tôi tình cờ gặp một vấn đề trong khi gỡ lỗi một tính năng trong một thay thế Notepad mã nguồn mở được gọi là Notepad2 (cụ thể hơn, một ngã ba gần đây gọi là Notepad2-mod).STARTUPINFO.wShowWindow là 0 khi chạy từ Visual Studio

Nó có cờ /u khiến ứng dụng tự khởi động lại dưới quyền Quản trị (sử dụng runas động từ với ShellExecute). Mã này trông như thế này (snipped cho ngắn gọn):

STARTUPINFO si; 
SHELLEXECUTEINFO sei; 

si.cb = sizeof(STARTUPINFO); 
GetStartupInfo(&si); 

ZeroMemory(&sei,sizeof(SHELLEXECUTEINFO)); 
sei.cbSize = sizeof(SHELLEXECUTEINFO); 
... 
sei.lpVerb = L"runas"; 
sei.lpFile = lpArg1; 
sei.lpParameters = lpArg2; 
sei.nShow = si.wShowWindow; 

ShellExecuteEx(&sei); 

Đối với một số lý do, nếu tôi đưa ra điều này từ Visual Studio (có hoặc không có một trình gỡ lỗi đính kèm), quá trình con cao cửa sổ chính sẽ chỉ không hiển thị! Nó sẽ xuất hiện trong Process Explorer, nhưng không có cửa sổ hiển thị.

Khi điều tra, tôi nhận thấy rằng nCmdShow được chuyển đến quy trình con 'WinMain là 0 (tương ứng với SW_HIDE) khi được bắt đầu từ Visual Studio! Giá trị này sau đó được chuyển đến ShowWindow và đó là lý do tại sao nó không hiển thị.

Khi cố gắng để khởi động điều này từ một vỏ cmd, mọi thứ hoạt động tốt.

Sau khi điều tra thêm, nó bật ra rằng giá trị của si.wShowWindow, thu được bằng một cuộc gọi đến GetStartupInfo là 0 khi chạy trong VS, nhưng 1 khi bắt đầu từ một cmd:

Launched from a cmd

Theo STARTUPINFO MSDN entry, giá trị cho wShowWindow phải khớp với giá trị nCmdShow nếu dwFlagsSTARTF_USESHOWWINDOW trong đó. Tuy nhiên, trong cả hai trường hợp (khởi chạy từ VS và cmd), giá trị cho dwFlags là 0.

Vì vậy, đây có phải là vấn đề với VS hoặc tôi chỉ giữ sai?

+0

Ngẫu nhiên, tôi không biết, tại sao nó thậm chí còn tạo ra sự khác biệt giá trị nào được truyền qua đối số 'STARTUPINFO' hoặc' wShowWindow'. Nó bị bỏ qua, lần đầu tiên một ứng dụng gọi [ShowWindow] (https://msdn.microsoft.com/en-us/library/windows/desktop/ms633548.aspx). Tôi cho rằng Notepad2 làm điều gì đó "bất thường", tức làgọi 'ShowWindow' nhiều lần cho cửa sổ ứng dụng chính của nó. – IInspectable

+0

Giá trị của 'wShowWindow' được chuyển vào' sei.nShow', và sau đó vào trong WinMain của tiến trình con. Vì giá trị là 0, tham số 'nCmdShow' của WinMain cũng là 0. Tham số này sau đó được truyền cho CreateWindow, vì vậy nó được gọi một cách hiệu quả với SW_HIDE. Với những gì @HansPassant đã nói dưới đây, có thể là một thực tế tồi tệ khi sử dụng nCmdShow trực tiếp, nhưng đó là những gì Notepad2 đã làm. –

+1

Vì không có ánh xạ trực tiếp giữa [Kiểu cửa sổ] (https://msdn.microsoft.com/en-us/library/windows/desktop/ms632600.aspx) và các giá trị cho * nCmdShow * có sẵn cho [ShowWindow] (https://msdn.microsoft.com/en-us/library/windows/desktop/ms633548.aspx), tôi muốn nói lỗi thực sự là trong Notepad2 (và Visual Studio, nhưng đó là hơi không liên quan). Trừ khi có một lý do nổi bật cho Notepad2 để sử dụng cờ cho những gì nó không phải là nghĩa vụ phải được sử dụng, tôi muốn đề nghị thay đổi điều đó. – IInspectable

Trả lời

8

Tôi sẽ viết cái này lên, đây là một lỗi khá tuyệt vời. Nó là cụ thể cho các công cụ gỡ lỗi VS2015, nó là khá nổi tiếng vì có khá nhiều lỗi. Một cái gì đó bạn có thể nhìn thấy cho chính mình bằng cách vô hiệu hóa nó. Công cụ> Tùy chọn> Gỡ lỗi> Chung> chọn tùy chọn "Sử dụng chế độ tương thích gốc". Điều đó buộc một công cụ gỡ lỗi cũ hơn được sử dụng, bây giờ bạn luôn nhận được STARTUPINFO.nCmdShow == SW_SHOWNORMAL.

Có trường hợp góc cận cảnh để giải thích rằng điều này là cố tình, một cách mù quáng theo lời khuyên nCmdShow không được khuyến khích. Nó là một vector tấn công phần mềm độc hại, cho phép nó bắt đầu một chương trình mà không cần người dùng nhận thấy. Nhiều chương trình cố ý bỏ qua SW_HIDE, không phải là một điều rất trực quan để làm và rất dễ bỏ qua. Tuy nhiên, bạn cần một chiếc kính quá nửa đầy đủ để thực hiện việc giải thích đó, đối số nCmdShow cho WinMain() là cái được sử dụng bình thường và nó là chính xác.

Đó cũng là giải pháp thay thế mà bạn có thể sử dụng. Tất nhiên trong trường hợp cụ thể này, bạn không bao giờ nên dựa vào giá trị khởi động và vượt qua SW_SHOWNORMAL hoặc SW_SHOWMAXIMIZED tùy thuộc vào trạng thái hiện tại của cửa sổ chính của Notepad ++.

Vì vậy, tôi bỏ phiếu cho lỗi, sử dụng connect.microsoft.com để báo cáo. Đặt một liên kết đến bài viết phản hồi trong một bình luận và chúng tôi sẽ bỏ phiếu cho nó.

+0

Giải thích tuyệt vời! Bạn cũng có thể sử dụng tùy chọn Gửi phản hồi trong VS, tùy chọn này thường xuyên được xem! –

+0

Chờ đã, tôi bối rối. điều tốt nhất để làm là gì? Tôi nghĩ rằng thời gian chạy tính toán 'nCmdShow' thành' WinMain() 'bằng cách sử dụng' STARTUPINFO', mặc định là 'SW_SHOWDEFAULT' nếu bit cờ tương ứng không được thiết lập. Tôi biết tài liệu 'ShowWindow()' nói về việc sử dụng 'SW_SHOWDEFAULT' hoặc giá trị chính xác bị bỏ qua, vì vậy bây giờ tôi đã nhầm lẫn điều thực sự chính xác là gì, cả cửa sổ ban đầu lẫn bất kỳ phần tử không thuộc sở hữu nào khác trong chương trình... – andlabs

Các vấn đề liên quan