Làm cách nào để chỉ định mã thoát của ứng dụng bảng điều khiển trong .NET?


471

Tôi có một ứng dụng giao diện điều khiển tầm thường trong .NET. Nó chỉ là một phần thử nghiệm của một ứng dụng lớn hơn. Tôi muốn chỉ định "mã thoát" của ứng dụng bảng điều khiển của mình. Làm thế nào để tôi làm điều này?

Câu trả lời:


599

3 tùy chọn:

  • Bạn có thể trả lại từ Mainnếu bạn khai báo Mainphương thức của bạn để trả về int.
  • Bạn có thể gọi Environment.Exit(code).
  • Bạn có thể đặt mã thoát bằng các thuộc tính : Environment.ExitCode = -1;. Điều này sẽ được sử dụng nếu không có gì khác đặt mã trả về hoặc sử dụng một trong các tùy chọn khác ở trên).

Tùy thuộc vào ứng dụng của bạn (bảng điều khiển, dịch vụ, ứng dụng web, v.v.) các phương pháp khác nhau có thể được sử dụng.


12
Đối với những người bạn thắc mắc tại sao điều này không hoạt động trong trường hợp của họ, hãy đảm bảo rằng dự án của bạn được biên dịch dưới dạng "ứng dụng Console" chứ không phải là "ứng dụng Windows".
Marcel Gosselin

9
Điều gì xảy ra nếu tôi có một ứng dụng WinForms mà với một số đối số tôi muốn nó hoạt động như một ứng dụng console?
sebagomez

5
Bạn cũng có thể chỉ cần gõ chương trình maine là int (thay thế void bằng int) và sử dụng ví dụ "return -1;" để trở về từ chương trình chính. Cái này dễ mang theo hơn môi trường.Exit () (phụ thuộc vào môi trường).
Werner

14
@DannyBeckett Theo quy ước, mã thoát 0có nghĩa là thành công và khác không có nghĩa là thất bại. return;chỉ ra thành công thông qua mã thoát 0return -1;chỉ ra thất bại.
allonhadaya

6
Bạn cũng có thể đặt mã thoát bằng các thuộc tính: Môi trường.ExitCode = -1;
t3b4n

270

Ngoài các câu trả lời về sự trở lại của int ... một lời cầu xin sự tỉnh táo. Xin vui lòng, vui lòng xác định mã thoát của bạn trong một enum, với Cờ nếu thích hợp. Nó giúp việc gỡ lỗi và bảo trì dễ dàng hơn rất nhiều (và, như một phần thưởng, bạn có thể dễ dàng in ra các mã thoát trên màn hình trợ giúp của mình - bạn có một trong số đó không?).

enum ExitCode : int {
  Success = 0,
  InvalidLogin = 1,
  InvalidFilename = 2,
  UnknownError = 10
}

int Main(string[] args) {
   return (int)ExitCode.Success;
}

46
Bạn có thể muốn thêm rằng giá trị "0" cho "Thành công" không phải là tình cờ, mà thực sự là giá trị "tiêu chuẩn" cho tình huống đó.
Christian.K

39
ĐIỀU NÀY. Đây là lý do tại sao SO là trang web lớn nhất trong lịch sử của Internet. Lời khuyên này không có sẵn trong bất kỳ sách giáo khoa nào và chỉ có thể được lượm lặt bằng cách nói chuyện với một chuyên gia dày dạn. CẢM ƠN BẠN.
Daniel Szabo

17
Bạn nói rằng 0 là giá trị tiêu chuẩn để thành công và khi chuyển đổi 0/1 thành boolean, 0 là sai và 1 là đúng! Có thể chính xác hơn để nói rằng mã thoát 0 có nghĩa là "không có lỗi", thay vì "thành công", vì mã thoát là ErrorResult không chỉ đơn giản là Kết quả.
Đánh dấu Shapiro

11
Để biết danh sách đầy đủ về quy ước microsoft, hãy xem msdn.microsoft.com/en-us/l Library / windows /desktop / . Một số anh chàng đã tạo ra một danh sách lớn các consts và sử dụng nó trong trường hợp chuyển đổi trong các bình luận bên dưới.
nawfal

5
@MarkShapiro, tôi đoán 0 = Successxuất phát từ thực tế là chỉ cần một mã thành công, nhưng nhiều mã lỗi, như 0, không có + hoặc - trong các số nguyên Máy tính, có thể được sử dụng để xác định thành công duy nhất
Sebastian

49

Có ba phương pháp mà bạn có thể sử dụng để trả về mã thoát khỏi ứng dụng bảng điều khiển.

  1. Sửa đổi Mainphương thức trong ứng dụng của bạn để nó trả về một intthay vì void(một hàm trả về Integerthay vì Subtrong VB.Net) và sau đó trả về mã thoát khỏi phương thức đó.
  2. Đặt thuộc tính Môi trường.ExitCode thành mã thoát. Lưu ý rằng phương thức 1. được ưu tiên - nếu Mainphương thức trả về bất kỳ thứ gì khác ngoài void(là Subtrong VB.Net) thì giá trị của thuộc tính này sẽ bị bỏ qua.
  3. Truyền mã thoát cho phương thức Môi trường . Điều này sẽ chấm dứt quá trình ngay lập tức trái ngược với hai phương pháp còn lại.

Một tiêu chuẩn quan trọng cần được quan sát là 0đại diện cho 'Thành công'.

Về một chủ đề liên quan, hãy xem xét sử dụng một bảng liệt kê để xác định mã thoát mà ứng dụng của bạn sẽ trả về. Các FlagsAttribute sẽ cho phép bạn quay trở lại một sự kết hợp của mã.

Ngoài ra, đảm bảo rằng ứng dụng của bạn được biên dịch dưới dạng 'Ứng dụng Bảng điều khiển'.


1
Điều này mang đến một điểm thú vị. Cài đặt Environment.ExitCodekhông đóng chương trình ngay lập tức nhưng Environment.Exitphương thức sẽ đóng chương trình ngay lập tức
PsychoData

1
Mã thoát cũng hoạt động trên các ứng dụng Windows. Nếu ứng dụng sẽ được khởi động từ c #, thông qua một Processđối tượng, bạn có thể yêu cầu đối tượng WaitForExit()đó và sau đó yêu cầu mã thoát khỏi nó.
Nyerguds

43

Nếu bạn định sử dụng phương pháp do David đề xuất, bạn cũng nên xem thuộc tính [Cờ].

Điều này cho phép bạn thực hiện các thao tác bit khôn ngoan trên enums.

[Flags]
enum ExitCodes : int
{
  Success = 0,
  SignToolNotInPath = 1,
  AssemblyDirectoryBad = 2,
  PFXFilePathBad = 4,
  PasswordMissing = 8,
  SignFailed = 16,
  UnknownError = 32
}

Sau đó

(ExitCodes.SignFailed | ExitCodes.UnknownError)

sẽ là 16 + 32. :)


3
Điều này ngụ ý rằng một chương trình sẽ nói 'mật khẩu của bạn sai', sau đó tiếp tục thử và ký bất cứ thứ gì nó ký và chỉ dừng lại nếu thất bại. Bạn nên trở lại một khi bạn đã thất bại; bất cứ điều gì khác là một cảnh báo và chương trình vẫn sẽ trở về 0.
Pete Kirkham

3
Thực tế ít ai biết là [Cờ] không có gì để kích hoạt hoặc vô hiệu hóa các hoạt động theo bit. Tất cả những gì nó làm là ghi đè phương thức ToString để đầu ra đại diện cho các cờ bitwise. Có hoặc không có nó, bạn vẫn có thể thực hiện các thao tác bitwise.
Steven

3
@Steven thật tuyệt khi biết nhưng tôi vẫn khuyên bạn nên trang trí các enum dành cho "sử dụng cờ" với thuộc tính đó, nếu không có gì khác thì nó truyền đạt ý định.
MarioDS



11

Chỉ cần trả lại mã chiếm dụng từ chính.

int main(string[] args)
{
      return 0; //or exit code of your choice
}

2
Ứng dụng bảng điều khiển C # mặc định hoàn toàn không khai báo chính. Nó tuyên bố static void Main(string[] args);
Mark Lakata

19
@Mark Lakta: Sau đó thay đổi nó, không?
Esteban Araya

11

Sử dụng ExitCode nếu chính của bạn có chữ ký trả về khoảng trống, nếu không bạn cần "đặt" nó theo giá trị bạn trả về.

Môi trường.ExitCode Thuộc tính

Nếu phương thức Main trả về void, bạn có thể sử dụng thuộc tính này để đặt mã thoát sẽ được trả về môi trường gọi. Nếu Main không trả về void, thuộc tính này sẽ bị bỏ qua. Giá trị ban đầu của tài sản này bằng không.


8

Như một cập nhật cho câu trả lời của Scott Munro :

  • Trong C # 6.0 và VB.NET 14.0 (VS 2015), một trong hai Environment.ExitCode hoặc Environment.Exit (exit code) được yêu cầu phải trả lại một khác không mã từ một ứng dụng console. Thay đổi loại trả lại Mainkhông có hiệu lực.
  • Trong F # 4.0 (VS 2015), giá trị trả về của mainđiểm vào được tôn trọng.

Điểm 1 của bạn về C # 6 có thể được xác minh không? Tôi dường như không thể tìm thấy bất cứ điều gì trực tuyến. Giá trị trả về từ hàm Main được gắn vào mã thoát của tiến trình (ít nhất là trong tất cả các trình biên dịch trước đó), tại sao chúng phải thay đổi điều đó?
Arman McHitarian

Bằng chứng hoàn toàn là giai thoại, nhưng tôi chỉ chạy vào đây trong thư viện của riêng mình, nơi chỉ cần trả lại mã kết quả / lỗi của tôi từ Main()việc không đặt Process.ExitCodeứng dụng gọi điện.
Marcus Mangelsdorf

MSDN int Mainvẫn có thể được sử dụng như là một thay thế cho Môi trường.ExitCode. liên kết
Arman McHitarian

Tôi có một ứng dụng chạy nhiều chủ đề. Trong một số trường hợp nhất định, tôi cần ghi đè một số luồng thông qua Thread.Abort (), trước khi thoát khỏi ứng dụng. Trong những trường hợp này, int Main () {... thread.Abort (); ... return 0;} KHÔNG dẫn đến mã thoát quy trình là 0: mã thoát quy trình là -1. Dường như trong một số trường hợp nhất định, MS đã quyết định rằng quy ước sử dụng giá trị trả về của luồng chính để đặt mã thoát của quy trình, không đủ tốt cho chúng. Nói một cách công bằng, đó có thể là một vấn đề thời gian: việc hủy bỏ chuỗi có thể đang đặt mã thoát rất muộn trong trò chơi.
David I. McIntosh

7

Tùy chọn liệt kê là tuyệt vời tuy nhiên có thể được cải thiện bằng cách nhân các số như trong:

enum ExitCodes : int
{
  Success = 0,
  SignToolNotInPath = 1,
  AssemblyDirectoryBad = 2,
  PFXFilePathBad = 4,
  PasswordMissing = 8,
  SignFailed = 16,
  UnknownError = 32
}

Trong trường hợp có nhiều lỗi, việc cộng các số lỗi cụ thể lại với nhau sẽ cho bạn một số duy nhất biểu thị sự kết hợp của các lỗi được phát hiện.

Ví dụ: một lỗi 6 chỉ có thể bao gồm các lỗi 4 và 2, 12 chỉ có thể bao gồm các lỗi 4 và 8, 14 chỉ có thể bao gồm 2, 4 và 8, v.v.


2
Đó là nếu bạn bận tâm kiểm tra các lỗi tiếp theo sau khi gặp phải một lỗi. Hầu hết các ứng dụng không.
Nyerguds

3

2 xu của tôi:

Bạn có thể tìm thấy mã lỗi hệ thống tại đây: https://msdn.microsoft.com/en-us/l Library / windows / desktop / ms681382 (v = vs85) .aspx

Bạn sẽ tìm thấy các mã điển hình như 2 cho "không tìm thấy tệp" hoặc 5 cho "truy cập bị từ chối".

Và khi bạn vấp phải một mã không xác định, bạn có thể sử dụng lệnh này để tìm hiểu ý nghĩa của nó:

net helpmsg decimal_code

ví dụ

trợ giúp ròng 1

trả lại

Chức năng không chính xác


0

Sử dụng mã này

Environment.Exit(0);

sử dụng 0 làm int nếu bạn không muốn trả lại bất cứ thứ gì.


Điều này không trả lời câu hỏi của OP và trả về 0 sẽ trả lại một cái gì đó ...
PL
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.