ติดตั้ง Windows Service ที่สร้างใน Visual Studio


136

เมื่อฉันสร้างบริการ Windows ใหม่ใน Visual Studio 2010 ฉันจะได้รับข้อความแจ้งว่าใช้ InstallUtil และ net start เพื่อเรียกใช้บริการ

ฉันได้ลองขั้นตอนต่อไปนี้แล้ว:

  1. สร้างโครงการใหม่ไฟล์ -> ใหม่ -> โครงการ -> บริการ Windows
  2. ชื่อโครงการ: TestService
  3. สร้างโครงการตามที่เป็นอยู่ (ตัวสร้าง Service1, OnStart, OnStop)
  4. พร้อมรับคำสั่งเปิดเรียกใช้"C: \ Windows \ Microsoft.NET \ Framework \ v4.0.30319 \ InstallUtil.exe" TestService.exe
  5. เรียกTestService เริ่มต้นสุทธิ

ผลลัพธ์ของขั้นตอนที่ 4

เรียกใช้การติดตั้งทรานแซคชัน

เริ่มต้นขั้นตอนการติดตั้งของการติดตั้ง

ดูเนื้อหาของแฟ้มบันทึกสำหรับความคืบหน้าของแอสเซมบลี C: \ Users \ myusername \ Documents \ Visual Studio 2010 \ Projects \ TestService \ TestService \ obj \ x86 \ Debug \ TestService.exe

ไฟล์จะอยู่ที่ C: \ Users \ myusername \ Documents \ Visual Studio 2010 \ Projects \ Tes tService \ TestService \ obj \ x86 \ Debug \ TestService.InstallLog

การติดตั้งชุดประกอบ 'C: \ Users \ myusername \ Documents \ Visual Studio 2010 \ Projects \ TestS ervice \ TestService \ obj \ x86 \ Debug \ TestService.exe'

พารามิเตอร์ที่ได้รับผลกระทบคือ:

logtoconsole =

logfile = C: \ Users \ myusername \ Documents \ Visual Studio 2010 \ Projects \ TestService \ T estService \ obj \ x86 \ Debug \ TestService.InstallLog

assemblypath = C: \ Users \ myusername \ Documents \ Visual Studio 2010 \ Projects \ TestServ น้ำแข็ง \ TestService \ obj \ x86 \ Debug \ TestService.exe

ไม่พบโปรแกรมติดตั้งสาธารณะที่มีคุณสมบัติ RunInstallerAttribute.Yes ในชุด C: \ Users \ myusername \ Documents \ Visual Studio 2010 \ Projects \ TestService \ TestService \ TestService rvice \ obj \ x86 \ Debug \ TestService.exe

ขั้นตอนการติดตั้งเสร็จสมบูรณ์และเฟส Commit เริ่มต้นขึ้น

ดูเนื้อหาของแฟ้มบันทึกสำหรับความคืบหน้าของแอสเซมบลี C: \ Users \ myusername \ Documents \ Visual Studio 2010 \ Projects \ TestService \ TestService \ obj \ x86 \ Debug \ TestService.exe

ไฟล์จะอยู่ที่ C: \ Users \ myusername \ Documents \ Visual Studio 2010 \ Projects \ Tes tService \ TestService \ obj \ x86 \ Debug \ TestService.InstallLog

กระทำการชุมนุม 'C: \ Users \ myusername \ Documents \ Visual Studio 2010 \ Projects \ TestS ervice \ TestService \ obj \ x86 \ Debug \ TestService.exe'

พารามิเตอร์ที่ได้รับผลกระทบคือ:

logtoconsole =

logfile = C: \ Users \ myusername \ Documents \ Visual Studio 2010 \ Projects \ TestService \ T estService \ obj \ x86 \ Debug \ TestService.InstallLog

assemblypath = C: \ Users \ myusername \ Documents \ Visual Studio 2010 \ Projects \ TestServ น้ำแข็ง \ TestService \ obj \ x86 \ Debug \ TestService.exe

ไม่พบโปรแกรมติดตั้งสาธารณะที่มีคุณสมบัติ RunInstallerAttribute.Yes ในชุด C: \ Users \ myusername \ Documents \ Visual Studio 2010 \ Projects \ TestService \ TestService \ TestService rvice \ obj \ x86 \ Debug \ TestService.exe

ลบไฟล์ InstallState เนื่องจากไม่มีตัวติดตั้ง

ขั้นตอนการยอมรับเสร็จสมบูรณ์

การติดตั้งทรานแซคชันเสร็จสมบูรณ์แล้ว

ผลลัพธ์ของขั้นตอนที่ 5

ชื่อบริการไม่ถูกต้อง

ความช่วยเหลือเพิ่มเติมพร้อมใช้งานโดยการพิมพ์ NET HELPMSG 2185

คำตอบ:


243

คุณต้องเปิดไฟล์ Service.cs ในตัวออกแบบคลิกขวาแล้วเลือกเมนูตัวเลือก "เพิ่มตัวติดตั้ง"

มันจะไม่ติดตั้งทันทีคุณต้องสร้างคลาสตัวติดตั้งก่อน

การอ้างอิงบางอย่างเกี่ยวกับตัวติดตั้งบริการ:

วิธีการ: เพิ่มตัวติดตั้งลงในแอปพลิเคชันบริการของคุณ

ค่อนข้างเก่า ... แต่นี่คือสิ่งที่ฉันกำลังพูดถึง:

Windows Services ใน C #: การเพิ่มตัวติดตั้ง (ตอนที่ 3)

โดยการทำเช่นนี้ProjectInstaller.csจะถูกสร้างขึ้นโดยอัตโนมัติ จากนั้นคุณสามารถดับเบิลคลิกที่นี่ป้อนผู้ออกแบบและกำหนดค่าส่วนประกอบ:

  • serviceInstaller1มีคุณสมบัติในการให้บริการของตัวเอง: Description, DisplayName, ServiceNameและStartTypeที่สำคัญที่สุด

  • serviceProcessInstaller1มีคุณสมบัติที่สำคัญนี้Accountนั่นคือบัญชีที่บริการจะทำงาน

ตัวอย่างเช่น:

this.serviceProcessInstaller1.Account = ServiceAccount.LocalSystem;

3
การเพิ่มตัวติดตั้งและการตั้งค่าบัญชีเป็น LocalSystem ก็ทำได้ ขอบคุณ!
Luc

1
ฉันได้รับข้อผิดพลาดเดียวกันใน VS2013 ฉันตรวจสอบลิงก์ที่คุณให้ไว้ตรวจสอบว่าฉันมี ProjectInstaller รวมถึงบริการคอมโพเนนต์ [กระบวนการ] ตัวติดตั้ง 1 ได้รับการกำหนดค่าอย่างถูกต้อง ฉันรัน installutil.exe ในฐานะผู้ดูแลระบบ มันยังรายงานว่า "ไม่พบโปรแกรมติดตั้งสาธารณะที่มีคุณลักษณะ RunInstallerAttribute.Yes" ความคิดใด ๆ
Barry Dysert

4
ฮ่า ๆ. ฉันชอบลิงก์ "ค่อนข้างเก่า" ไปยังไซต์ที่เรียกว่า Arcane Code ยิ่งเพจนั้นมีอายุมากขึ้นชื่อที่แท้จริงจะกลายเป็น :-)
HotN

"นักออกแบบ" คืออะไร? โดยทั่วไปแอปพลิเคชันที่ไม่มี UI จะไม่เกี่ยวข้องกับสิ่งใด ๆ ที่เรียกว่าผู้ออกแบบ
Maxx

บริการยังมีนักออกแบบเช่นเดียวกับฟอร์ม
Grungondola

11

มองไปที่:

ไม่พบโปรแกรมติดตั้งสาธารณะที่มีคุณสมบัติ RunInstallerAttribute.Yes ในชุด C: \ Users \ myusername \ Documents \ Visual Studio 2010 \ Projects \ TestService \ TestService \ TestService rvice \ obj \ x86 \ Debug \ TestService.exe

ดูเหมือนว่าคุณอาจไม่มีคลาสตัวติดตั้งในรหัสของคุณ นี่คือคลาสที่สืบทอดมาจากInstallerที่จะบอกinstallutilวิธีการติดตั้งปฏิบัติการของคุณเป็นบริการ

ปล. ฉันมีเทมเพลต Windows Service ติดตั้ง / debuggable เล็ก ๆ น้อย ๆ ของตัวเองที่นี่ซึ่งคุณสามารถคัดลอกโค้ดจากหรือใช้: Debuggable, ติดตั้ง Windows ด้วยตนเอง


เมื่อฉันคลิกขวาที่โครงการ TestService ใน Visual Studio -> Properties -> Services หน้านี้ถูกปิดใช้งาน ... คุณหมายถึงที่ตั้งอื่นหรือไม่ ภายใต้แอปพลิเคชันชื่อแอสเซมบลีคือ TestService
jkh

@ John: ละเว้นส่วนแรกเกี่ยวกับคอนโซลบริการดูที่ส่วนที่สองเริ่มต้นด้วยจริง ดูเหมือนว่าบริการไม่เคยติดตั้งเพราะไม่พบโปรแกรมติดตั้ง
James Michael Hare

8

นี่คือวิธีอื่นในการสร้างตัวติดตั้งและกำจัดข้อความแสดงข้อผิดพลาด นอกจากนี้ยังดูเหมือนว่า VS2015 express ไม่มีรายการเมนู "Add Installer"

คุณเพียงแค่ต้องสร้างคลาสและเพิ่มรหัสด้านล่างและเพิ่มการอ้างอิง System.Configuration.Install.dll

using System.Configuration.Install;
using System.ServiceProcess;
using System.ComponentModel;


namespace SAS
{
    [RunInstaller(true)]
    public class MyProjectInstaller : Installer
    {
        private ServiceInstaller serviceInstaller1;
        private ServiceProcessInstaller processInstaller;

        public MyProjectInstaller()
        {
            // Instantiate installer for process and service.
            processInstaller = new ServiceProcessInstaller();
            serviceInstaller1 = new ServiceInstaller();

            // The service runs under the system account.
            processInstaller.Account = ServiceAccount.LocalSystem;

            // The service is started manually.
            serviceInstaller1.StartType = ServiceStartMode.Manual;

            // ServiceName must equal those on ServiceBase derived classes.
            serviceInstaller1.ServiceName = "SAS Service";

            // Add installer to collection. Order is not important if more than one service.
            Installers.Add(serviceInstaller1);
            Installers.Add(processInstaller);
        }
    }
}

ใช้ VS2015 เช่นกันและวิธีแก้ไขปัญหานี้ทำให้ฉันผ่าน "ข้อผิดพลาดสาธารณะที่ไม่มีตัวติดตั้ง RunInstallerAttribute.Yes" ที่ฉันเคยได้รับมาก่อน ขอบคุณ!
PHBeagle

6

ปัญหาทั่วไปสองประการ:

  1. ไม่มีคลาส ProjectInstaller (ในขณะที่ @MiguelAngelo ได้ชี้)
  2. พร้อมรับคำสั่งต้อง“เรียกใช้ในฐานะผู้ดูแลระบบ

4

อีกปัญหาที่เป็นไปได้ (ซึ่งฉันวิ่งเข้าไป):

ตรวจสอบให้แน่ใจว่าระดับคือProjectInstaller publicบอกตามตรงฉันไม่แน่ใจว่าฉันทำอย่างนั้น แต่ฉันได้เพิ่มตัวจัดการเหตุการณ์ลงProjectInstaller.Designer.csใน:

this.serviceProcessInstaller1.BeforeInstall += new System.Configuration.Install.InstallEventHandler(this.serviceProcessInstaller1_BeforeInstall);

ฉันเดาว่าในระหว่างกระบวนการสร้างฟังก์ชันตัวจัดการอัตโนมัติProjectInstaller.csมันจะเปลี่ยนนิยามคลาสจาก

public class ProjectInstaller : System.Configuration.Install.Installer

ถึง

partial class ProjectInstaller : System.Configuration.Install.Installer

เปลี่ยนคำหลักที่มีpublic partialดังนั้นเพื่อที่จะแก้ไขมันจะต้องเป็น

public partial class ProjectInstaller : System.Configuration.Install.Installer

ฉันใช้ Visual Studio 2013 Community edition


ฉันรู้ว่านี่คือ 3 ปีต่อมา แต่สิ่งนี้แก้ปัญหาของฉันได้ ไม่แน่ใจว่าทำไมหรือเมื่อผู้ออกแบบเปลี่ยนคลาสสาธารณะบางส่วนก่อนหน้านี้เป็นคลาสบางส่วนภายใน ขอบคุณ!
trashrobber

2

การเปลี่ยนแปลงที่ซ่อนตัวใน VS 2010 และ. NET 4.0 และใหม่กว่า

ไม่พบโปรแกรมติดตั้งสาธารณะที่มีคุณสมบัติ RunInstallerAttribute.Yes

มีการเปลี่ยนนามแฝงหรือคอมไพเลอร์การล้างข้อมูลใน. NET ที่อาจเปิดเผยการปรับแต่งเล็กน้อยสำหรับกรณีเฉพาะของคุณ

หากคุณมีรหัสต่อไปนี้ ...

RunInstaller(true)   // old alias  

คุณอาจต้องอัปเดตเป็น

RunInstallerAttribute(true)  // new property spelling

มันเป็นเหมือนนามแฝงที่มีการเปลี่ยนแปลงภายใต้การครอบคลุมในเวลาคอมไพล์หรือตอนรันไทม์และคุณจะได้รับพฤติกรรมข้อผิดพลาดนี้ การเปลี่ยนแปลงอย่างชัดเจนข้างต้นเป็น RunInstallerAttribute (true) ได้แก้ไขในสถานการณ์การติดตั้งทั้งหมดของเราในเครื่องทั้งหมด

หลังจากคุณเพิ่มโครงการหรือตัวติดตั้งบริการแล้วให้ตรวจสอบ RunInstaller“ เก่า” (จริง) และเปลี่ยนเป็น RunInstallerAttribute ใหม่ (จริง)


ตามความรู้ของฉันคุณสามารถละเว้น postfix "Attribute" เช่น [RunInstaller (true)] และ [RunInstallerAttribute (true)] เหมือนกัน ลองใช้ด้วยแอตทริบิวต์ที่แตกต่างกันเช่น [DebuggerStepThrough ()] และ [DebuggerStepThroughAttribute ()] - ทั้งคู่จะใช้งานได้เมื่อนำไปใช้กับคลาส
Matt

1

ยังมีอีกสิ่งที่ฉันพบ: ตรวจสอบให้แน่ใจว่าคลาสของคุณได้รับการติดตั้ง ProjectInstaller ) อยู่ด้านบนสุดของลำดับชั้นเนมสเปซฉันพยายามใช้คลาสสาธารณะภายในคลาสสาธารณะอื่น แต่ผลลัพธ์นี้มีข้อผิดพลาดเก่า ๆ

ไม่พบโปรแกรมติดตั้งสาธารณะที่มีคุณสมบัติ RunInstallerAttribute.Yes

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.