2017-10-04 48 views
9

Tôi đang cố gắng xây dựng một Dịch vụ Windows trong .Net Core 2.0 nhưng tôi đã đập đầu vào tường cả ngày và không có tiến bộ nào cả. Tất cả mọi thứ dường như được sử dụng Core 1.0/1.1 ngay cả những tài liệu Microsoft:.Net Core 2.0 Windows Service

Host an ASP.NET Core app in a Windows Service

TopShelf không hỗ trợ 2.0 là tốt, cho những gì tôi đã nhìn thấy.

Tôi đã thấy một số giải pháp lạ đặt tất cả mã trong Thư viện lớp chuẩn .Net và sau đó sử dụng ứng dụng .Net Framework để lưu trữ Dịch vụ Windows, nhưng điều này không có vẻ thanh lịch trong mắt tôi và tôi ' m cố gắng để thoát khỏi các.NET Framework hoàn toàn.

Tôi có muốn làm gì ngay bây giờ không? Tôi có thiếu cái gì đó thực sự cơ bản?

+0

Bản sao có thể có của [Dịch vụ Windows với .NET Core] (https://stackoverflow.com/questions/41014513/windows-service-with-net-core) –

+0

'cố gắng loại bỏ toàn bộ Khung.Net' trong khi cố gắng xây dựng dịch vụ _Windows_ có thể là một trận chiến khó khăn .. – thisextendsthat

Trả lời

2

Bạn không thể, đơn giản là vì sự hỗ trợ cho Dịch vụ Windows dựa trên .NET đang nằm trong Khuôn khổ .NET.

mỗi tài liệu bạn tham khảo:

Điều kiện tiên quyết

  • Các ứng dụng phải chạy trên bộ thực thi .NET framework.

Một lý do thẳng về phía trước là các dịch vụ sử dụng Microsoft.AspNetCore.Hosting.WindowsServices gói, mà phụ thuộc vào .NET Framework chính nó.

+0

Bạn phải nói gì về https://github.com/dasMulli/dotnet-win32-service – DGaspar

+0

hoạt động tốt trên windows 64? –

+0

@ maxman tốt khi tôi thử nghiệm nó, nó đã không đi tốt với .net Core 2.0, vì vậy tôi đã phải đi với https://github.com/PeterKottas/DotNetCore.WindowsService – DGaspar

5

tôi sẽ tóm tắt một số tùy chọn:

  1. Di chuyển mã của bạn vào một thư viện .NET Standard, và lưu trữ nó trong một ứng dụng .NET Framework, vì vậy bạn có thể sử dụng ServiceBase. Điều này tất nhiên sẽ cần .NET Framework được cài đặt trên máy mục tiêu
  2. Sử dụng NSSM (Trình quản lý dịch vụ không hút) để quản lý ứng dụng .NET Core console (có giấy phép miền công cộng)
  3. Sử dụng Windows Các cuộc gọi API để móc vào các phương thức dịch vụ Windows. Đây là phương pháp chụp bởi DotNetCore.WindowsServicedotnet-win32-service (cả hai đều MIT cấp phép)

Tôi nghĩ @ bình luận JeroenMostert là một chút khắc nghiệt - Tôi có thể nhìn thấy sự hấp dẫn của không bị lệ thuộc vào một phiên bản .NET Framework đặc biệt là có sẵn trên các máy mục tiêu. Nhiều người khác rõ ràng cảm thấy như nhau, như 2 repos tôi liên kết với khá phổ biến.

+0

Tôi đã xóa nhận xét của mình. Tôi cũng đã viết một câu trả lời mới để chỉ ra rằng bây giờ có một giải pháp dựa trên MS cho các dịch vụ trong .NET Core 2.0 (mặc dù sử dụng một số giải pháp của bên thứ ba vẫn thuận tiện hơn). Tôi tin tưởng rằng làm dịu mọi sự khắc nghiệt. :-) –

0

Có thể đây hoàn toàn là cảnh sát, nhưng hãy nhớ rằng với sự hỗ trợ đế cắm lớn hơn, bạn có thể xây dựng một dịch vụ chạy trong vùng chứa. Tại thời điểm đó, nó vẫn sẽ là .net lõi (2.0) nhưng chạy trên cửa sổ của bạn hộp. Hơn nữa, bạn có thể triển khai chỉ là về bất cứ nơi nào trong tương lai.

Khi lõi của dotnet đáo hạn, tôi là giải pháp tốt hơn và tốt hơn, giả sử dịch vụ của bạn không yêu cầu tài nguyên cục bộ cho máy chủ lưu trữ.

1

Giờ đây bạn có thể viết Dịch vụ Windows trong .NET Core 2.0 mà không có thư viện của bên thứ ba, nhờ vào việc phát hành Windows Compatibility Pack (tại thời điểm viết thư, vẫn còn trong quá trình phát hành trước).Khi trang tự cảnh báo:

Nhưng trước khi bạn bắt đầu chuyển, bạn nên hiểu những gì bạn muốn thực hiện với việc di chuyển. Chỉ cần chuyển sang .NET Core vì nó là triển khai .NET mới không phải là một lý do đủ tốt (trừ khi bạn là True Fan).

Cụ thể, viết Dịch vụ Windows trong .NET Core hiện có thể thực hiện được, nhưng bạn sẽ không nhận được tính tương thích đa nền tảng, vì hội đồng dành cho nền tảng không phải Windows sẽ chỉ ném PlatformNotSupportedException nếu bạn cố gắng sử dụng mã dịch vụ. Làm việc xung quanh điều này là có thể (ví dụ như sử dụng RuntimeInformation.IsOSPlatform), nhưng đó là một câu hỏi khác hoàn toàn.

Ngoài ra, thư viện của bên thứ ba vẫn có thể cung cấp giao diện đẹp hơn liên quan đến cài đặt dịch vụ: bằng văn bản, phiên bản hiện tại của gói tương thích (2.0.0-preview1-26216-02) không hỗ trợ không gian tên System.Configuration.Install. ServiceProcessInstaller lớp học và installutil sẽ không hoạt động. Thêm về điều đó sau. Với tất cả những gì đã nói, hãy giả sử bạn đã tạo một dịch vụ Windows hoàn toàn mới (Service1) từ mẫu dự án (không bắt buộc vì nó không chứa gì thú vị, ngoài một lớp kế thừa từ ServiceBase). Tất cả bạn cần làm gì để làm cho nó xây dựng trên .NET Lõi 2.0 là để chỉnh sửa và thay thế các .csproj với định dạng mới:

<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0"> 
    <PropertyGroup> 
    <OutputType>Exe</OutputType> 
    <TargetFramework>netcoreapp20</TargetFramework> 
    <RuntimeIdentifier>win-x64</RuntimeIdentifier> 
    </PropertyGroup> 
    <ItemGroup> 
    <PackageReference Include="Microsoft.Windows.Compatibility" Version="2.0.0-*" /> 
    </ItemGroup> 
</Project> 

Và sau đó xóa properties\AssemblyInfo.cs kể từ khi nó không còn cần thiết và sẽ mâu thuẫn với thông tin phiên bản trong dự án.

Nếu bạn đã có dịch vụ và dịch vụ có phụ thuộc, việc chuyển đổi có thể phức tạp hơn. Xem here.

Bây giờ, bạn có thể chạy dotnet publish và nhận tệp thực thi. Như đã đề cập, bạn không thể sử dụng lớp ServiceProcessInstaller để cài đặt dịch vụ, vì vậy bạn sẽ phải tự

  • đăng ký nguồn sự kiện mà dịch vụ sử dụng;
  • tạo dịch vụ thực tế.

Điều này có thể được thực hiện với một số PowerShell. Từ một nâng lên nhanh chóng ở vị trí có chứa thực thi được công bố của bạn:

$messageResourceFile = "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\EventLogMessages.dll" 
New-EventLog -LogName Application -Source Service1 -MessageResourceFile $messageResourceFile 
sc.exe create Service1 binPath= (Resolve-Path .\WindowsService1.exe) 

Đây không phải là lý tưởng bằng nhiều cách: này cứng mã đường dẫn của tập tin tài nguyên thông điệp (chúng tôi thực sự cần được xác định nó ở đâu từ đường dẫn thực thi và đường dẫn thời gian chạy trong sổ đăng ký) và mã hóa cứng tên dịch vụ và tên thực thi. Bạn có thể muốn cung cấp cho dự án khả năng cài đặt của riêng mình bằng cách thực hiện một số phân tích cú pháp dòng lệnh trong Program.cs hoặc sử dụng một trong các thư viện được đề cập trong Cocowalla's answer.

+0

Tôi hiện đang có dịch vụ của mình đang chạy với https://github.com/dasMulli/dotnet-win32-service nhưng khi tôi có thể tôi sẽ thử và giải quyết bằng giải pháp này, vì nó trông giống như cách tốt nhất để kiểm tra trong tương lai, và ofc có vẻ như nó sẽ là cách làm bản địa. Nếu mọi việc suôn sẻ, tôi sẽ chấp nhận câu trả lời của bạn. – DGaspar

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