การติดตั้งบริการ windows เดียวกันหลายอินสแตนซ์บนเซิร์ฟเวอร์


96

ดังนั้นเราจึงได้ผลิตบริการ windows เพื่อป้อนข้อมูลไปยังแอปพลิเคชันไคลเอนต์ของเราและทุกอย่างจะดีมาก ไคลเอนต์ได้มาพร้อมกับการร้องขอการกำหนดค่าที่สนุกสนานซึ่งต้องใช้สองอินสแตนซ์ของบริการนี้ที่ทำงานบนเซิร์ฟเวอร์เดียวกันและกำหนดค่าให้ชี้ไปที่ฐานข้อมูลแยกกัน

จนถึงตอนนี้ฉันยังไม่สามารถทำให้สิ่งนี้เกิดขึ้นได้และหวังว่าสมาชิก stackoverflow เพื่อนของฉันอาจให้คำแนะนำบางอย่างว่าทำไม

การตั้งค่าปัจจุบัน:

ฉันได้ตั้งค่าโครงการที่มีบริการ windows แล้วเราจะเรียกมันว่า AppService นับจากนี้เป็นต้นไปและไฟล์ ProjectInstaller.cs ที่จัดการขั้นตอนการติดตั้งแบบกำหนดเองเพื่อตั้งชื่อบริการตามคีย์ใน App.config เช่นนั้น :

this.serviceInstaller1.ServiceName = Util.ServiceName;
this.serviceInstaller1.DisplayName = Util.ServiceName;
this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem;

ในกรณีนี้ Util เป็นเพียงคลาสสแตติกที่โหลดชื่อบริการจากไฟล์กำหนดค่า

จากนี้ไปฉันได้ลองสองวิธีที่แตกต่างกันในการติดตั้งทั้งสองบริการและทั้งคู่ล้มเหลวในลักษณะเดียวกัน

วิธีแรกเพียงแค่ติดตั้งสำเนาแรกของบริการคัดลอกไดเร็กทอรีที่ติดตั้งและเปลี่ยนชื่อจากนั้นเรียกใช้คำสั่งต่อไปนี้หลังจากแก้ไขการกำหนดค่าแอปเพื่อเปลี่ยนชื่อบริการที่ต้องการ:

InstallUtil.exe /i AppService.exe

เมื่อไม่ได้ผลฉันพยายามสร้างโครงการติดตั้งที่สองแก้ไขไฟล์กำหนดค่าและสร้างตัวติดตั้งตัวที่สอง เมื่อฉันรันโปรแกรมติดตั้งมันทำงานได้ดี แต่บริการไม่ปรากฏใน services.msc ดังนั้นฉันจึงรันคำสั่งก่อนหน้ากับฐานรหัสที่สองที่ติดตั้ง

ทั้งสองครั้งฉันได้รับผลลัพธ์ต่อไปนี้จาก InstallUtil (เฉพาะส่วนที่เกี่ยวข้อง):

เรียกใช้การติดตั้งที่ทำธุรกรรม

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

การติดตั้งบริการ App Service Two ... Service App Service Two ได้รับการติดตั้งเรียบร้อยแล้ว การสร้าง EventLog source App Service Two ในแอปพลิเคชันบันทึก ...

เกิดข้อผิดพลาดระหว่างขั้นตอนการติดตั้ง System.NullReferenceException: การอ้างอิงวัตถุไม่ได้ตั้งค่าเป็นอินสแตนซ์ของอ็อบเจ็กต์

ขั้นตอนการย้อนกลับของการติดตั้งกำลังเริ่มต้นขึ้น

การกู้คืนบันทึกเหตุการณ์เป็นสถานะก่อนหน้าสำหรับแหล่งที่มา App Service Two Service App Service Two กำลังถูกลบออกจากระบบ ... Service App Service Two ถูกลบออกจากระบบเรียบร้อยแล้ว

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

การติดตั้งที่ทำธุรกรรมเสร็จสมบูรณ์แล้ว การติดตั้งล้มเหลวและดำเนินการย้อนกลับแล้ว

ขออภัยสำหรับโพสต์ที่ยืดยาวต้องการให้แน่ใจว่ามีข้อมูลที่เกี่ยวข้องเพียงพอ ส่วนที่ฉันนิ่งงันจนถึงตอนนี้ก็คือมันระบุว่าการติดตั้งบริการเสร็จสมบูรณ์และหลังจากนั้นจะสร้างซอร์ส EventLog ที่ดูเหมือนว่า NullReferenceException จะถูกโยนทิ้ง ดังนั้นหากใครรู้ว่าฉันทำอะไรผิดหรือมีแนวทางที่ดีกว่านี้จะได้รับการชื่นชมมาก

คำตอบ:


82

คุณลองใช้ sc / service controller util แล้วหรือยัง? ประเภท

sc create

ที่บรรทัดคำสั่งและจะให้รายการวิธีใช้แก่คุณ ฉันคิดว่าฉันเคยทำสิ่งนี้ในอดีตเพื่อโค่นล้มและใช้บทความนี้เป็นข้อมูลอ้างอิง:

http://svn.apache.org/repos/asf/subversion/trunk/notes/windows-service.txt


5
ฉันพบว่าหน้านี้มีประโยชน์: http://journalofasoftwaredev.wordpress.com/2008/07/16/multiple-instances-of-same-windows-service/. คุณสามารถแทรกโค้ดลงในโปรแกรมติดตั้งเพื่อรับชื่อบริการที่คุณต้องการเมื่อคุณเรียกใช้ installutil
Vivian River

9
เปลี่ยนลิงก์ไปยังบล็อก wordpress เป็นjournalofasoftwaredev.wordpress.com/2008/07
STLDev

21
  sc create [servicename] binpath= [path to your exe]

วิธีนี้ใช้ได้ผลสำหรับฉัน


5
เพียงเพื่อชี้ให้เห็น; [path to your exe]ต้องเต็มเส้นทางและอย่าลืมเว้นวรรคหลังbinpath=
mkb

2
สิ่งนี้ทำให้สามารถติดตั้งบริการได้หลายครั้ง อย่างไรก็ตามข้อมูลทั้งหมดที่ให้บริการโดยโปรแกรมติดตั้ง คำอธิบาย Fe ประเภทการเข้าสู่ระบบและอื่น ๆ ถูกละเว้น
Noel Widmer

20

คุณสามารถเรียกใช้บริการเดียวกันได้หลายเวอร์ชันโดยทำดังต่อไปนี้:

1) คัดลอกบริการปฏิบัติการและกำหนดค่าไปยังโฟลเดอร์ของตนเอง

2) คัดลอก Install.Exe ไปยังโฟลเดอร์ที่เรียกใช้บริการได้ (จากโฟลเดอร์. net framework)

3) สร้างไฟล์กำหนดค่าชื่อ Install.exe.config ในโฟลเดอร์ service executable พร้อมเนื้อหาต่อไปนี้ (ชื่อบริการเฉพาะ):

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="ServiceName" value="The Service Name"/>
    <add key="DisplayName" value="The Service Display Name"/>
  </appSettings>
</configuration>

4) สร้างไฟล์แบตช์เพื่อติดตั้งบริการโดยมีเนื้อหาดังต่อไปนี้:

REM Install
InstallUtil.exe YourService.exe
pause

5) ในขณะที่คุณอยู่ที่นั่นให้สร้างไฟล์แบตช์ถอนการติดตั้ง

REM Uninstall
InstallUtil.exe -u YourService.exe
pause

แก้ไข:

โปรดทราบว่าหากฉันพลาดอะไรไปนี่คือ ServiceInstaller Class (ปรับได้ตามต้องการ):

using System.Configuration;

namespace Made4Print
{
    partial class ServiceInstaller
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;
        private System.ServiceProcess.ServiceInstaller FileProcessingServiceInstaller;
        private System.ServiceProcess.ServiceProcessInstaller FileProcessingServiceProcessInstaller;

        /// <summary> 
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Component Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.FileProcessingServiceInstaller = new System.ServiceProcess.ServiceInstaller();
            this.FileProcessingServiceProcessInstaller = new System.ServiceProcess.ServiceProcessInstaller();
            // 
            // FileProcessingServiceInstaller
            // 
            this.FileProcessingServiceInstaller.ServiceName = ServiceName;
            this.FileProcessingServiceInstaller.DisplayName = DisplayName;
            // 
            // FileProcessingServiceProcessInstaller
            // 
            this.FileProcessingServiceProcessInstaller.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
            this.FileProcessingServiceProcessInstaller.Password = null;
            this.FileProcessingServiceProcessInstaller.Username = null;
            // 
            // ServiceInstaller
            // 
            this.Installers.AddRange(new System.Configuration.Install.Installer[] { this.FileProcessingServiceInstaller, this.FileProcessingServiceProcessInstaller });
        }

        #endregion

        private string ServiceName
        {
            get
            {
                return (ConfigurationManager.AppSettings["ServiceName"] == null ? "Made4PrintFileProcessingService" : ConfigurationManager.AppSettings["ServiceName"].ToString());
            }
        }

        private string DisplayName
        {
            get
            {
                return (ConfigurationManager.AppSettings["DisplayName"] == null ? "Made4Print File Processing Service" : ConfigurationManager.AppSettings["DisplayName"].ToString());
            }
        }
    }
}

ฉันคิดว่าสิ่งที่คุณอธิบายเป็นสิ่งที่ฉันได้ทำไม่มากก็น้อยโดยอนุญาตให้ตั้งค่า ServiceName และ DisplayName จากแอปบริการของฉันฉันได้ลองสิ่งที่คุณอธิบาย แต่น่าเสียดายที่ทำให้เกิดปัญหาเดียวกันในคำถามของฉัน
Switters

ฉันมีเทมเพลตที่ฉันใช้ซึ่งฉันใช้มานานแล้วบางทีฉันอาจพลาดอะไรไปคลาส ServiceInstaller ของคุณมีลักษณะอย่างไรจะโพสต์สำเนาที่ใช้งานได้ของหนึ่งที่ฉันใช้แจ้งให้ฉันทราบว่าฉันช่วยได้ไหม
Mark Redman

ตัวติดตั้งบริการของเรานั้นแทบจะเหมือนกัน ฉันใช้คลาสแบบคงที่เพื่อโหลดเซอร์วิสและแสดงชื่อจากไฟล์ config แต่นอกเหนือจากนั้นจะคล้ายกันมาก ฉันเดาว่าทำไมมันถึงไม่ได้ผลสำหรับฉันก็คืออาจมีบางอย่างที่แปลกประหลาดเกี่ยวกับรหัสบริการของเรา โชคไม่ดีที่มีมือจำนวนมากเข้ามา จากสิ่งที่ฉันเข้าใจคำตอบของคุณควรใช้งานได้ในส่วนใหญ่ขอบคุณสำหรับความช่วยเหลือ
Switters

2
ขอบคุณมาก ฉันคิดว่าไฟล์ config การติดตั้งจะต้องมีชื่อว่า InstallUtil.exe.confg ไม่ใช่ Install.exe.config สำหรับ InstallUtil.exe
NullReference

แนวทางที่ดีที่ใช้ได้ผลจริง นั่นคือถ้าคุณรู้ว่าจะคัดลอก InstallUtil.exe ตัวใดไปยังโฟลเดอร์การติดตั้งของคุณ (โดยส่วนตัวแล้วฉันมีเวอร์ชันเฟรมเวิร์กจำนวนมากติดตั้งซึ่งทำให้สำเนา 64 บิตแย่ลง) สิ่งนี้จะทำให้ยากที่จะอธิบายกับทีม Helpdesk หากพวกเขาทำการติดตั้ง แต่สำหรับการติดตั้งที่นำไปสู่การพัฒนานั้นเป็นเรื่องที่สวยงามมาก
timmi4sa

11

คำถามเก่าฉันรู้ แต่ฉันโชคดีที่ใช้ตัวเลือก / servicename บน InstallUtil.exe ฉันไม่เห็นมันแสดงอยู่ในวิธีใช้ในตัว

InstallUtil.exe /servicename="My Service" MyService.exe

ฉันไม่แน่ใจว่าฉันอ่านเรื่องนี้ครั้งแรกที่ไหน แต่ฉันไม่ได้เห็นมันตั้งแต่นั้นมา YMMV.


3
ส่งกลับข้อผิดพลาดนี้:An exception occurred during the Install phase. System.ComponentModel.Win32Exception: The specified service already exists
mkb

@mkb คุณมีบริการอื่นที่เรียกว่า "My Service" หรือไม่?
Jonathon Watney

ใช่ตามคำถามฉันมีบริการเดียวที่สามารถเรียกใช้งานได้เหมือนกัน แต่ฉันต้องการติดตั้งสองอินสแตนซ์โดยแต่ละรายการมีการกำหนดค่าที่แตกต่างกัน ฉันคัดลอกและวาง exe บริการ แต่อันนี้ใช้ไม่ได้
mkb

1
/ servicename = "My Service InstanceOne" และ / servicename = "My Service InstanceTwo" ชื่อต้องไม่ซ้ำกัน
granadaCoder

11

อีกวิธีที่รวดเร็วในการระบุค่าที่กำหนดเองสำหรับServiceNameและDisplayNameใช้installutilพารามิเตอร์บรรทัดคำสั่ง

  1. ในProjectInstallerชั้นเรียนของคุณแทนที่วิธีการเสมือนInstall(IDictionary stateSaver)และUninstall(IDictionary savedState)

    public override void Install(System.Collections.IDictionary stateSaver)
    {
        GetCustomServiceName();
        base.Install(stateSaver);
    }
    
    public override void Uninstall(System.Collections.IDictionary savedState)
    {
        GetCustomServiceName();
        base.Uninstall(savedState);
    }
    
    //Retrieve custom service name from installutil command line parameters
    private void GetCustomServiceName()
    {
        string customServiceName = Context.Parameters["servicename"];
        if (!string.IsNullOrEmpty(customServiceName))
        {
            serviceInstaller1.ServiceName = customServiceName;
            serviceInstaller1.DisplayName = customServiceName;
        }
    }
    
  2. สร้างโครงการของคุณ
  3. ติดตั้งบริการโดยinstallutilเพิ่มชื่อที่กำหนดเองของคุณโดยใช้/servicenameพารามิเตอร์:

    installutil.exe /servicename="CustomServiceName" "c:\pathToService\SrvcExecutable.exe"
    

โปรดทราบว่าหากคุณไม่ได้ระบุ /servicenameในบรรทัดคำสั่งบริการจะถูกติดตั้งด้วยค่า ServiceName และ DisplayName ที่ระบุในคุณสมบัติ ProjectInstaller / config


2
แจ่ม !! ขอบคุณ - นี่คือสิ่งที่จำเป็นและตรงประเด็น
Iofacture

7

ฉันไม่มีโชคกับวิธีการข้างต้นเมื่อใช้ซอฟต์แวร์การปรับใช้อัตโนมัติของเราเพื่อติดตั้ง / ถอนการติดตั้งบริการ windows แบบเคียงข้างกันบ่อยๆ แต่ในที่สุดฉันก็พบสิ่งต่อไปนี้ซึ่งช่วยให้ฉันส่งพารามิเตอร์เพื่อระบุคำต่อท้าย ไปยังชื่อบริการบนบรรทัดคำสั่ง นอกจากนี้ยังช่วยให้นักออกแบบสามารถทำงานได้อย่างถูกต้องและสามารถปรับเปลี่ยนเพื่อแทนที่ชื่อทั้งหมดได้อย่างง่ายดายหากจำเป็น

public partial class ProjectInstaller : System.Configuration.Install.Installer
{
  protected override void OnBeforeInstall(IDictionary savedState)
  {
    base.OnBeforeInstall(savedState);
    SetNames();
  }

  protected override void OnBeforeUninstall(IDictionary savedState)
  {
    base.OnBeforeUninstall(savedState);
    SetNames();
  }

  private void SetNames()
  {
    this.serviceInstaller1.DisplayName = AddSuffix(this.serviceInstaller1.DisplayName);
    this.serviceInstaller1.ServiceName = AddSuffix(this.serviceInstaller1.ServiceName);
  }

  private string AddSuffix(string originalName)
  {
    if (!String.IsNullOrWhiteSpace(this.Context.Parameters["ServiceSuffix"]))
      return originalName + " - " + this.Context.Parameters["ServiceSuffix"];
    else
      return originalName;
  }
}

ด้วยเหตุนี้ฉันจึงสามารถทำสิ่งต่อไปนี้ได้: หากฉันเรียกบริการว่า "บริการที่ยอดเยี่ยม" ฉันสามารถติดตั้งเวอร์ชัน UAT ของบริการได้ดังนี้:

InstallUtil.exe /ServiceSuffix="UAT" MyService.exe

สิ่งนี้จะสร้างบริการที่มีชื่อว่า "Awesome Service - UAT" เราได้ใช้สิ่งนี้เพื่อเรียกใช้เวอร์ชัน DEVINT, TESTING และ ACCEPTANCE ของบริการเดียวกันที่ทำงานเคียงข้างกันในเครื่องเดียว แต่ละเวอร์ชันมีชุดไฟล์ / การกำหนดค่าของตัวเอง - ฉันไม่ได้ลองสิ่งนี้เพื่อติดตั้งบริการหลายอย่างที่ชี้ไปที่ไฟล์ชุดเดียวกัน

หมายเหตุ: คุณต้องใช้/ServiceSuffixพารามิเตอร์เดียวกันในการถอนการติดตั้งบริการดังนั้นคุณต้องดำเนินการต่อไปนี้เพื่อถอนการติดตั้ง:

InstallUtil.exe /u /ServiceSuffix="UAT" MyService.exe


นั่นเป็นเรื่องที่ดี แต่สำหรับผู้ติดตั้งเท่านั้น เมื่อคุณมีชื่ออินสแตนซ์ใหม่แล้วบริการของ Windows จะทราบชื่อใหม่นี้ได้อย่างไร คุณต้องส่งต่อในการสร้างบริการ Windows หรือไม่?
progLearner

ขอบคุณ! โปรแกรมติดตั้งจะตั้งชื่อบน Windows Service ในขณะที่ติดตั้งโดยใช้ค่าที่กำหนดในวิธี SetNames () ด้านบน
tristankoffee

แน่นอน แต่คุณจะตั้งชื่อนี้จากโลกภายนอกได้อย่างไร?
progLearner

ในคำตอบของฉันคือคำสั่งที่ใช้ในบรรทัดคำสั่งเพื่อติดตั้ง (และถอนการติดตั้ง) บริการในโลกภายนอก คุณค่าที่คุณส่งผ่าน/ServiceSuffix="UAT"จะถูกใช้โดยโปรแกรมติดตั้งเพื่อตั้งค่าคำต่อท้ายบนบริการ UATในตัวอย่างของฉันค่าผ่านมี ในสถานการณ์ของฉันฉันแค่ต้องการเพิ่มคำต่อท้ายในชื่อที่มีอยู่ของบริการ แต่ไม่มีเหตุผลที่คุณไม่สามารถปรับเปลี่ยนชื่อนี้เพื่อแทนที่ชื่อทั้งหมดด้วยค่าที่ส่งผ่านมา
tristankoffee

ขอบคุณ แต่นั่นคืออินพุตบรรทัดคำสั่ง (= อินพุตด้วยตนเอง) ไม่ใช่โค้ด ตามคำถามเดิม: เมื่อคุณมีชื่ออินสแตนซ์ใหม่แล้วบริการ Windows จะทราบชื่อใหม่นี้ได้อย่างไร? คุณต้องส่งต่อในการสร้างบริการ Windows หรือไม่?
progLearner

4

สิ่งที่ฉันได้ทำเพื่อให้งานนี้คือการจัดเก็บชื่อบริการและชื่อที่แสดงใน app.config สำหรับบริการของฉัน จากนั้นในคลาสตัวติดตั้งของฉันฉันโหลด app.config เป็น XmlDocument และใช้ xpath เพื่อดึงค่าออกมาและนำไปใช้กับ ServiceInstaller.ServiceName และ ServiceInstaller.DisplayName ก่อนที่จะเรียกใช้ InitializeComponent () ถือว่าคุณยังไม่ได้ตั้งค่าคุณสมบัติเหล่านี้ใน InitializeComponent () ซึ่งในกรณีนี้การตั้งค่าจากไฟล์กำหนดค่าของคุณจะถูกละเว้น รหัสต่อไปนี้คือสิ่งที่ฉันเรียกจากตัวสร้างคลาสตัวติดตั้งก่อนที่จะ InitializeComponent ():

       private void SetServiceName()
       {
          string configurationFilePath = Path.ChangeExtension(Assembly.GetExecutingAssembly().Location, "exe.config");
          XmlDocument doc = new XmlDocument();
          doc.Load(configurationFilePath);

          XmlNode serviceName = doc.SelectSingleNode("/xpath/to/your/@serviceName");
          XmlNode displayName = doc.SelectSingleNode("/xpath/to/your/@displayName");

          if (serviceName != null && !string.IsNullOrEmpty(serviceName.Value))
          {
              this.serviceInstaller.ServiceName = serviceName.Value;
          }

          if (displayName != null && !string.IsNullOrEmpty(displayName.Value))
          {
              this.serviceInstaller.DisplayName = displayName.Value;
          }
      }

ฉันไม่เชื่อว่าการอ่านไฟล์การกำหนดค่าโดยตรงจาก ConfigurationManager AppSettings หรือสิ่งที่คล้ายกันจะทำงานได้เหมือนกับเมื่อโปรแกรมติดตั้งทำงานมันทำงานในบริบทของ InstallUtil.exe ไม่ใช่. exe ของบริการของคุณ คุณอาจสามารถทำบางอย่างกับ ConfigurationManager.OpenExeConfiguration ได้อย่างไรก็ตามในกรณีของฉันสิ่งนี้ไม่ได้ผลเนื่องจากฉันพยายามเข้าไปในส่วนการกำหนดค่าแบบกำหนดเองที่ไม่ได้โหลด


สวัสดีบ้านคริส! สะดุดกับคำตอบของคุณเพราะฉันกำลังสร้างเว็บ API ที่ใช้ OWIN ที่โฮสต์ด้วยตัวเองรอบ ๆ ตัวกำหนดตารางเวลา Quartz.NET และติดไว้ในบริการ Windows เนียนสวย! หวังว่าคุณจะสบายดี!
NovaJoe

สวัสดีบ้านคริส! สะดุดกับคำตอบของคุณเพราะฉันกำลังสร้างเว็บ API ที่ใช้ OWIN ที่โฮสต์ด้วยตัวเองรอบ ๆ ตัวกำหนดตารางเวลา Quartz.NET และติดไว้ในบริการ Windows เนียนสวย! หวังว่าคุณจะสบายดี!
NovaJoe

4

เพียงเพื่อปรับปรุงคำตอบที่สมบูรณ์แบบของ @ chris.house.00 สิ่งนี้คุณสามารถพิจารณาฟังก์ชั่นต่อไปนี้เพื่ออ่านจากการตั้งค่าแอพของคุณ:

 public void GetServiceAndDisplayName(out string serviceNameVar, out string displayNameVar)
        {
            string configurationFilePath = Path.ChangeExtension(Assembly.GetExecutingAssembly().Location, "exe.config");
            XmlDocument doc = new XmlDocument();
            doc.Load(configurationFilePath);

            XmlNode serviceName = doc.SelectSingleNode("//appSettings//add[@key='ServiceName']");
            XmlNode displayName = doc.SelectSingleNode("//appSettings//add[@key='DisplayName']");


            if (serviceName != null && (serviceName.Attributes != null && (serviceName.Attributes["value"] != null)))
            {
                serviceNameVar = serviceName.Attributes["value"].Value;
            }
            else
            {
                serviceNameVar = "Custom.Service.Name";
            }

            if (displayName != null && (displayName.Attributes != null && (displayName.Attributes["value"] != null)))
            {
                displayNameVar = displayName.Attributes["value"].Value;
            }
            else
            {
                displayNameVar = "Custom.Service.DisplayName";
            }
        }

2

ฉันมีสถานการณ์ที่คล้ายกันซึ่งฉันต้องมีบริการก่อนหน้านี้และบริการที่อัปเดตที่ทำงานเคียงข้างกันบนเซิร์ฟเวอร์เดียวกัน (มันเป็นมากกว่าการเปลี่ยนแปลงฐานข้อมูล แต่เป็นการเปลี่ยนแปลงโค้ดด้วย) ดังนั้นฉันจึงไม่สามารถเรียกใช้. exe ซ้ำสองครั้งได้ ฉันต้องการ. exe ใหม่ที่คอมไพล์ด้วย DLL ใหม่ แต่มาจากโปรเจ็กต์เดียวกัน เพียงแค่เปลี่ยนชื่อบริการและชื่อที่แสดงของบริการไม่ได้ผลสำหรับฉันฉันยังคงได้รับ "ข้อผิดพลาดของบริการที่มีอยู่แล้ว" ซึ่งฉันเชื่อว่าเป็นเพราะฉันกำลังใช้โครงการการทำให้ใช้งานได้ ในที่สุดสิ่งที่ได้ผลสำหรับฉันคือภายใน Deployment Project Properties ของฉันมีคุณสมบัติที่เรียกว่า "ProductCode" ซึ่งเป็น Guid

ป้อนคำอธิบายภาพที่นี่

หลังจากนั้นสร้างโครงการติดตั้งใหม่เป็น. exe หรือ. msi ใหม่ที่ติดตั้งสำเร็จ


1

แนวทางที่ง่ายที่สุดคือตามชื่อบริการบนชื่อ dll:

string sAssPath = System.Reflection.Assembly.GetExecutingAssembly().Location;
string sAssName = System.IO.Path.GetFileNameWithoutExtension(sAssPath);
if ((this.ServiceInstaller1.ServiceName != sAssName)) {
    this.ServiceInstaller1.ServiceName = sAssName;
    this.ServiceInstaller1.DisplayName = sAssName;
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.