部署C#服务器应用程序

时间:2014-11-18 09:52:40

标签: c# deployment server

我最近在C#中创建了一个多线程服务器作为控制台应用程序。最初它运行在通过端口转发暴露于互联网的公司计算机上。但是,我相信随着客户端的增加,可能需要推出真正的服务器设置。我之前从未这样做过,所以我想知道:

如何将这样的C#控制台应用程序部署到服务器上?是否需要转换为服务?我可以获得一个VPS并运行它吗?

我非常感谢任何答案或建议,谢谢

2 个答案:

答案 0 :(得分:1)

在c#中编写Windows服务非常简单。我喜欢结合控制台应用程序和服务。我把它结合起来,因为出于调试原因,控制台应用程序更好,生产服务更好。作为服务基地,我总是使用:

的Program.cs:

#define __USE_AS_CONSOLE___

using MyService.Service;
using System;
using System.Collections.Generic;
using System.Configuration.Install;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Diagnostics;

namespace MyService
{
    public class Program
    {
        #region Private Member
        private static ASServiceBase myServiceBase;
        private static string serviceName;
        #endregion

        #region Console
        const bool ShowConsole = true;

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool AllocConsole();

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool FreeConsole();

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern bool SetDllDirectory(string lpPathName);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern bool AddDllDirectory(string lpPathName);
        #endregion

        static void Main(string[] args)
        {
            AppDomain.CurrentDomain.AssemblyResolve += ResolveError;

            string installCommand = "";
            serviceName = GetServiceName();

            foreach(string arg in args)
            {
                if (arg.ToLower().StartsWith("/install"))
                {
                    installCommand = "/install";
                }
                else if (arg.ToLower().StartsWith("/uninstall"))
                {
                    installCommand = "/uninstall";
                }
            }

            if (System.Environment.UserInteractive)
            {
                string parameter = "";

                foreach (string arg in args)
                {
                    parameter += arg;

                    if (!arg.EndsWith(" "))
                    {
                        parameter += "";
                    }
                }

                switch (installCommand)
                {
                    case "/install":
                        if (!IsAdministrator())
                        {
                            System.Console.WriteLine("Die Anwendung muss als Administrator installiert werden.");
                            System.Console.ReadLine();
                            return;
                        }

                        ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetExecutingAssembly().Location });
                        return;
                        break;
                    case "/uninstall":
                        if (!IsAdministrator())
                        {
                            System.Console.WriteLine("Die Anwendung muss als Administrator installiert werden.");
                            System.Console.ReadLine();
                            return;
                        }

                        ManagedInstallerClass.InstallHelper(new string[] { "/u", Assembly.GetExecutingAssembly().Location });
                        return;
                        break;
                }

                AllocConsole();
                myServiceBase = new ASServiceBase();
                myServiceBase.Start();
                System.Console.ReadLine();
            }
            else
            {
                // ===============================================
                // Start Console
                AllocConsole();
                System.Console.WriteLine("Version 1.0");

                myServiceBase = new ASServiceBase();

                //Start service
                System.ServiceProcess.ServiceBase.Run(myServiceBase);

            }
        }

        public static bool IsAdministrator()
        {
            var identity = WindowsIdentity.GetCurrent();
            var principal = new WindowsPrincipal(identity);
            return principal.IsInRole(WindowsBuiltInRole.Administrator);
        }

        #region [Resolve Error]
        /// <summary>
        /// Resolve Error
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static Assembly ResolveError(object sender, ResolveEventArgs args)
        {
            try
            {
                Assembly cMyAssembly = null;
                string strTempAssmbPath = string.Empty;

                Assembly objExecutingAssemblies = Assembly.GetExecutingAssembly();
                AssemblyName[] arrReferencedAssmbNames = objExecutingAssemblies.GetReferencedAssemblies();

                AssemblyName myAssemblyName = Array.Find<AssemblyName>(arrReferencedAssmbNames, a => a.Name == args.Name);

                if (myAssemblyName != null)
                {
                    cMyAssembly = Assembly.LoadFrom(myAssemblyName.CodeBase);
                }
                else
                {
                    string rootFolder = GetAssemblyPath(args, "");
                    if (!string.IsNullOrEmpty(rootFolder))
                    {
                        if (File.Exists(rootFolder))
                        {
                            // Loads the assembly from the specified path.                  
                            cMyAssembly = Assembly.LoadFrom(rootFolder);
                        }
                    }

                    string assemblyFolder = GetAssemblyPath(args, "Assemblies\\");
                    if (!string.IsNullOrEmpty(assemblyFolder))
                    {
                        if (File.Exists(assemblyFolder))
                        {
                            // Loads the assembly from the specified path.                  
                            cMyAssembly = Assembly.LoadFrom(assemblyFolder);
                        }
                    }
                }

                // Returns the loaded assembly.
                return cMyAssembly;
            }
            catch (Exception exc)
            {
                FileLog.WriteLog("Fehler in Init.ResolveError:\r\n" + exc.ToString());
                return null;
            }
        }

        private static string GetAssemblyPath(ResolveEventArgs args, string AdditionalDirectory)
        {
            string returnValue = null;

            string cRMSAssemblyFolder = GlobalSettings.StudioPath + "\\" + AdditionalDirectory;

            Assembly cMyAssembly = null;
            string strTempAssmbPath = string.Empty;

            Assembly objExecutingAssemblies = Assembly.GetExecutingAssembly();
            AssemblyName[] arrReferencedAssmbNames = objExecutingAssemblies.GetReferencedAssemblies();

            AssemblyName myAssemblyName = Array.Find<AssemblyName>(arrReferencedAssmbNames, a => a.Name == args.Name);

            if (myAssemblyName == null)
            {
                if (args.Name.Contains(","))
                {
                    strTempAssmbPath = Path.Combine(cRMSAssemblyFolder, args.Name.Substring(0, args.Name.IndexOf(",")) + ".dll");
                }
                else
                {
                    strTempAssmbPath = Path.Combine(cRMSAssemblyFolder, args.Name + ".dll");
                }

                returnValue = strTempAssmbPath;
            }

            return returnValue;
        }
        #endregion
    }
}

服务安装程序:

using System;
using System.Configuration.Install;
using System.ComponentModel;
using System.ServiceProcess;
using System.IO;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.Configuration;
using System.Diagnostics;

/// <summary>
/// Installerklasse für den Service
/// </summary>
[RunInstaller(true)]
public class QServiceInstaller : Installer
{
    #region private Member
    private ServiceInstaller myThisService;
    private IContainer components;
    private ServiceProcessInstaller myThisServiceProcess;
    #endregion

    public QServiceInstaller()
    {
        myThisService = new ServiceInstaller();
        myThisServiceProcess = new ServiceProcessInstaller();

        string Path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

        myThisServiceProcess.Account = ServiceAccount.LocalSystem;
        myThisService.ServiceName = "Your application name";
        myThisService.StartType = ServiceStartMode.Automatic;

        Installers.Add(myThisService);
        Installers.Add(myThisServiceProcess);
    }

    private void InitializeComponent()
    {

    }
}

您的服务基础:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading;

namespace MyService.Service
{
    public class ASServiceBase : ServiceBase
    {
        #region Private Member
        private Thread myServiceThread;
        private bool myDoStop;
        #endregion

        #region Constructor
        /// <summary>
        /// Constructor
        /// </summary>
        public ASServiceBase()
        {
            myDoStop = false;
        }
        #endregion

        #region Public Methods
        #region OnStart
        protected override void OnStart(string[] args)
        {
            Start();
        }

        /// <summary>
        /// Start
        /// </summary>
        public void Start()
        {
            myServiceThread = new Thread(new ThreadStart(Do));
            myServiceThread.Start();

            MainThread = myServiceThread;
        }
        #endregion

        #region Do Anything
        /// <summary>
        /// Execute
        /// </summary>
        public void Do()
        {
            while (!myDoStop)
            {
                // Do some stuff
                Thread.Sleep(10);
            }

            LoggingManager.Singleton.Deactivate();

            // =====================================================================================
            // Stop anything

            // =====================================================================================
        }
        #endregion

        #region OnStop
        protected override void OnStop()
        {
            Stop();
        }

        /// <summary>
        /// Stop
        /// </summary>
        public void Stop()
        {
            myDoStop = true;
        }
        #endregion

        #endregion

        #region Private Methods

        #endregion

        #region Public Member
        /// <summary>
        /// Main Thread
        /// </summary>
        public static Thread MainThread
        {
            get;
            set;
        }
        #endregion
    }
}

希望我的代码有所帮助。询问您是否有任何问题

答案 1 :(得分:0)

为这种程序提供服务更好。控制台应用程序输出使用大量资源,必须手动启动。虽然可以在每台计算机上执行服务,而用户甚至无需登录。

为了部署它,最好的方法是创建一个安装过程,然后将其安装在服务器上。然后,您可以为服务器创建一个uptade流程,这样您就不需要为每次更新安装它。