C# Visual studio 2010-发布模式下的应用程序即服务

C# Visual studio 2010-发布模式下的应用程序即服务,c#,.net,windows,visual-studio-2010,service,C#,.net,Windows,Visual Studio 2010,Service,我在visual studio 2010中创建了一个桌面控制台应用程序。如何将其转换为windows服务?。基本上在调试模式下,我希望它作为普通应用程序使用,但在发布模式下,我需要一个服务构建输出基本上,您的解决方案中需要3个项目: 应用程序本身 WinService for production 用于测试目的的控制台应用程序 因此,您的应用程序必须具有某种Start()方法,例如,无限循环可以完成所有工作,也可以使用Stop()方法停止处理 Winservice项目必须包含从ServiceBa

我在visual studio 2010中创建了一个桌面控制台应用程序。如何将其转换为windows服务?。基本上在调试模式下,我希望它作为普通应用程序使用,但在发布模式下,我需要一个服务构建输出

基本上,您的解决方案中需要3个项目:

  • 应用程序本身
  • WinService for production
  • 用于测试目的的控制台应用程序
  • 因此,您的应用程序必须具有某种
    Start()
    方法,例如,无限循环可以完成所有工作,也可以使用
    Stop()
    方法停止处理

    Winservice项目必须包含从
    ServiceBase
    派生的类,它有
    OnStart
    方法调用应用程序的
    Start
    OnStop
    方法调用应用程序的
    Stop
    方法

    接下来,在控制台应用程序中,您可以执行几乎相同的操作—在控制台的入口点调用
    Start
    方法

    到目前为止,对于调试,您运行控制台应用程序,对于发布版,您发布winservice项目

    Winservice类可能如下所示:

    upd

    Winservice codez:

    public class MyWinService : ServiceBase
    {
        IMyApplicationService _myApplicationService;
    
        //constructor - resolve dependencies here
        public MyWinService()
        {       
            _myApplicationService = new MyApplicationService();
        }
    
        protected override void OnStart(string[] args)
        {
            base.OnStart(args);
            try
            {
                _myApplicationService.Start();
            }
            catch (Exception exception)
            {      
                //log exception          
            }
        }
    
        protected override void OnStop()
        {
            base.OnStop();
            try
            {
                _myApplicationService.Stop();
            }
            catch (Exception exception)
            {
                //log exception             
            }
        }
    }
    
    申请服务:

    public class MyApplicationService : IMyApplicationService
    {
        public MyApplicationService()
        {
            //some initializations
        }
    
        public Start()
        {
            //do work here
        }
    
        public Stop()
        {
            //...
        }
    }
    

    您可以这样做:

    namespace Program
    {
        static class Program
        {
            public static bool Stopped = false;
            [STAThread]
            static void Main(string[] args)
            {
                Interactive.Initialize();
                Interactive.OnStopped += new Interactive.StopedDelegate(OnStopped);
                Interactive.Title = Path.GetFileNameWithoutExtension(
                    Assembly.GetExecutingAssembly().Location);
    
                if (args.Length == 0) Interactive.Run(RunProc);
                else if (args[0] == "-svc") ServiceBase.Run(new Service());
            }
            public static void RunProc() { yourConsoleMain(); }
            public static void OnStopped() { Stopped = true; exitFromMain(); }
        }
    
        public class Service : ServiceBase
        {
            public static string Name = Path.GetFileNameWithoutExtension(
                Assembly.GetExecutingAssembly().Location);
            public static string CmdLineSwitch = "-svc";
            public static ServiceStartMode StartMode = ServiceStartMode.Automatic;
            public static bool DesktopInteract = true;
            public bool Stopped = false;
            public Service() { ServiceName = Name; }
            public void Start() { OnStart(null); }
            protected override void OnStart(string[] args)
            {
                System.Diagnostics.EventLog.WriteEntry(
                    ServiceName, ServiceName + " service started.");
                Thread thread = new Thread(MainThread);
                thread.Start();
            }
            protected override void OnStop()
            {
                System.Diagnostics.EventLog.WriteEntry(
                    ServiceName, ServiceName + " service stopped.");
                Stopped = true;
                Application.Exit();
            }
            private void MainThread()
            {
                Interactive.Run(Program.RunProc);
                if (!Stopped) Stop();
            }
        }
    }
    
    让我解释一下。。。基本上,在
    Main
    中,如果程序是以参数
    '-svc'
    启动的,则定义程序作为服务启动

    RunProc()

    然后,覆盖ServiceBase,并执行一些基本的启动/停止服务

    在Windows 7及更高版本中,如果您想查看某些输出,必须明确定义您的服务可以与桌面交互。但还有一个问题,控制台窗口无法显示。所以我创建了这个控制台模拟器,它可以写入和读取输入

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Threading;
    using System.Runtime.InteropServices;
    
    namespace ProgramIO.Control
    {
        public delegate void WriteDelegate(string value, int x, int y);
        public delegate void ReadDelegate(out string value, bool readLine);
        public delegate void EnableInputDelegate(bool enable);
    
        public partial class InteractiveForm : Form
        {
            private delegate void ClearInputBufferDelegate();
    
            public enum EIOOperation { None = 0, Write, Read }
    
            private EventWaitHandle eventInvoke =
                new EventWaitHandle(false, EventResetMode.AutoReset);
            private EventWaitHandle eventInput =
                new EventWaitHandle(false, EventResetMode.AutoReset);
            private bool readLine = false;
            private string inputBuffer = "";
            private int inputPosition = 0;
            private int inputBufferPosition = 0;
            private EIOOperation IOOperation;
            private int bufferSize = 0x10000;
            private bool CaretShown = false;
    
            private delegate object DoInvokeDelegate(Delegate method, params object[] args);
            private delegate void SetTitleDelegate(string value);
            private delegate void SetForegroundcolorDelegate(Color value);
    
            public string Title {
                get { return Text; }
                set {
                    if (InvokeRequired) InvokeEx(
                        (SetTitleDelegate)delegate(string title) { Text = title; },
                        1000, new object[] { value });
                    else Text = value; }}
            public Color ForegroundColor {
                get { return ForeColor; }
                set {
                    if (InvokeRequired) InvokeEx(
                        (SetForegroundcolorDelegate)delegate(Color color) { ForeColor = color; },
                        1000, new object[] { value });
                    else ForeColor = value; }}
    
            public InteractiveForm()
            {
                InitializeComponent();
                DoubleBuffered = true;
            }
    
            #region Asynchronous Methods
            private bool InvokeEx(Delegate method, int timeout, params object[] args)
            {
                BeginInvoke((DoInvokeDelegate)DoInvoke, new object[] { method, args });
                if (eventInvoke.WaitOne(timeout)) return true;
                else return false;
            }
            private void EnableInput(bool enable)
            {
                if (InvokeRequired)
                    InvokeEx((EnableInputDelegate)DoEnableInput, 1000, new object[] { enable });
                else DoEnableInput(enable);
            }
            private void ClearInputBuffer()
            {
                if (InvokeRequired)
                    InvokeEx((ClearInputBufferDelegate)DoClearInputBuffer, 1000, new object[0]);
                else DoClearInputBuffer();
            }
            public void Write(string value, int x = -1, int y = -1)
            {
                lock (this) {
                    IOOperation = EIOOperation.Write;
                    if (InvokeRequired)
                        InvokeEx((WriteDelegate)DoWrite, 1000, new object[] { value, x, y });
                    else DoWrite(value, x, y);
                    IOOperation = EIOOperation.None; }
            }
            public string Read(bool readLine)
            {
                lock (this) {
                    EnableInput(true);
                    IOOperation = EIOOperation.Read; this.readLine = readLine; string value = "";
                    ClearInputBuffer(); eventInput.WaitOne();
                    object[] args = new object[] { value, readLine };
                    if (InvokeRequired) {
                        InvokeEx((ReadDelegate)DoRead, 1000, args); value = (string) args[0]; }
                    else DoRead(out value, readLine);
                    //inputPosition = textBox.Text.Length; inputBuffer = "";
                    ClearInputBuffer();
                    IOOperation = EIOOperation.None;
                    EnableInput(false);
                    return value;
                }
            }
            #endregion //Asynchronous Methods
    
            #region Synchronous Methods
            protected override void OnShown(EventArgs e) { base.OnShown(e); textBox.Focus(); }
            public object DoInvoke(Delegate method, params object[] args)
            {
                object obj = method.DynamicInvoke(args);
                eventInvoke.Set();
                return obj;
            }
            private void CorrectSelection()
            {
                if (textBox.SelectionStart < inputPosition) {
                    if (textBox.SelectionLength > (inputPosition - textBox.SelectionStart))
                        textBox.SelectionLength -= inputPosition - textBox.SelectionStart;
                    else textBox.SelectionLength = 0;
                    textBox.SelectionStart = inputPosition; }
            }
            protected void DoClearInputBuffer()
            {
                inputPosition = textBox.Text.Length; inputBuffer = "";
            }
            protected void DoEnableInput(bool enable)
            {
                if (enable) { textBox.ReadOnly = false; textBox.SetCaret(true); }
                else { textBox.ReadOnly = true; textBox.SetCaret(false); }
            }
            protected void DoWrite(string value, int x, int y)
            {
                string[] lines = textBox.Text.Split(new string[] { "\r\n" }, StringSplitOptions.None);
                string[] addLines = new string[0];
    
                if (y == -1) y = lines.Length - 1;
                if (lines.Length - 1 < y) addLines = new string[y - lines.Length - 1];
    
                if (y < lines.Length) {
                    if (x == -1) x = lines[y].Length;
                    if (lines[y].Length < x)
                        lines[y] += new String(' ', x - lines[y].Length) + value;
                    else
                        lines[y] = lines[y].Substring(0, x) + value +
                            ((x + value.Length) < lines[y].Length ?
                                lines[y].Substring(x + value.Length) : ""); }
                else {
                    y -= lines.Length;
                    if (x == -1) x = addLines[y].Length;
                    addLines[y] += new String(' ', x - addLines[y].Length) + value; }
    
                textBox.Text = (string.Join("\r\n", lines) +
                    (addLines.Length > 0 ? "\r\n" : "") + string.Join("\r\n", addLines));
                textBox.Select(textBox.Text.Length, 0); textBox.ScrollToCaret();
                inputBuffer = "";
            }
            protected void DoRead(out string value, bool readLine)
            {
                value = "";
                if (readLine) {
                    int count = inputBuffer.IndexOf("\r\n");
                    if (count > 0) { value = inputBuffer.Substring(0, count); }}
                else if (inputBuffer.Length > 0) {
                    value = inputBuffer.Substring(0, 1); }
                inputBuffer = "";
            }
            private void textBox_TextChanged(object sender, EventArgs e)
            {
                if (IOOperation == EIOOperation.Read) {
                    inputBuffer = textBox.Text.Substring(inputPosition);
                    if (!readLine || inputBuffer.Contains("\r\n")) eventInput.Set(); }
    
                if (textBox.Text.Length > bufferSize) { textBox.Text =
                    textBox.Text.Substring(textBox.Text.Length - bufferSize, bufferSize);
                    textBox.Select(textBox.Text.Length, 0); textBox.ScrollToCaret(); }
            }
            private void textBox_KeyDown(object sender, KeyEventArgs e)
            {
                if (IOOperation != EIOOperation.Read || 
                    (e.KeyCode == Keys.Back && inputBuffer.Length == 0))
                    e.SuppressKeyPress = true;
            }
            private void textBox_MouseUp(object sender, MouseEventArgs e)
            {
                CorrectSelection();
            }
            private void textBox_KeyUp(object sender, KeyEventArgs e)
            {
                if (!(IOOperation == EIOOperation.Read) ||
                    ((e.KeyCode == Keys.Left || e.KeyCode == Keys.Up) &&
                    textBox.SelectionStart < inputPosition))
                    CorrectSelection();
            }
            private void InteractiveForm_FormClosing(object sender, FormClosingEventArgs e)
            {
                eventInput.Set();
                lock (this) { }
            }
            #endregion //Synchronous Methods
        }
    
        public class InteractiveWindow : TextBox
        {
            [DllImport("user32.dll")]
            static extern bool HideCaret(IntPtr hWnd);
            [DllImport("user32.dll")]
            static extern bool ShowCaret(IntPtr hWnd);
    
            private delegate void SetCaretDelegate(bool visible);
    
            private const int WM_SETFOCUS = 0x0007;
            private bool CaretVisible = true;
    
            public void SetCaret(bool visible)
            {
                if (InvokeRequired) Invoke((SetCaretDelegate)DoSetCaret, new object[] { visible });
                else DoSetCaret(visible);
            }
            private void DoSetCaret(bool visible)
            {
                if (CaretVisible != visible)
                {
                    CaretVisible = visible;
                    if (CaretVisible) ShowCaret(Handle);
                    else HideCaret(Handle);
                }
            }
            protected override void WndProc(ref Message m)
            {
                base.WndProc(ref m);
                if (m.Msg == WM_SETFOCUS)
                {
                    if (CaretVisible) { ShowCaret(Handle); }
                    else HideCaret(Handle);
                }
            }
        }
    }
    
    namespace ProgramIO
    {
        using ProgramIO.Control;
        public static class Interactive
        {
            public delegate void StopedDelegate();
            public delegate void RunDelegate();
    
            public static bool Initialized = false;
            private static InteractiveForm frmIO = null;
            private static Thread IOThread = null;
            private static EventWaitHandle EventStarted =
                new EventWaitHandle(false, EventResetMode.AutoReset);
    
            public static string Title {
                get { return frmIO.Title; }
                set { frmIO.Title = value; } }
            public static Color ForegroundColor {
                get {return frmIO.ForeColor; }
                set { frmIO.ForeColor = value; } }
            public static event StopedDelegate OnStopped = null;
    
            private static void form_Show(object sender, EventArgs e)
            {
                frmIO = sender as InteractiveForm;
                EventStarted.Set();
            }
            private static void form_FormClosed(object sender, FormClosedEventArgs e)
            {
                lock (frmIO) {
                    frmIO = null;
                    Application.Exit(); }
            }
            public static void Initialize()
            {
                IOThread = new Thread(IOThreadProc);
                IOThread.Name = "Interactive Thread"; IOThread.Start();
                EventStarted.WaitOne();
                Initialized = true;
            }
            public static void Run(RunDelegate runProc = null)
            {
                if (!Initialized) Initialize();
                if (runProc != null) runProc();
                Application.Run();
                if (OnStopped != null) OnStopped();
            }
            public static void IOThreadProc()
            {
                InteractiveForm form = new InteractiveForm();
                form.Shown += new EventHandler(form_Show);
                form.FormClosed += new FormClosedEventHandler(form_FormClosed);
                Application.Run(form);
            }
            public static void Write(string value, int x = -1, int y = -1)
            {
                if (frmIO != null) lock (frmIO) { frmIO.Write(value, x, y); }
            }
            public static void WriteLine(string value)
            {
                if (frmIO != null) lock (frmIO) {
                    Interactive.Write(value); Interactive.Write("\r\n"); }
            }
            public static int Read()
            {
                if (frmIO != null) lock (frmIO) {
                    string input = frmIO.Read(false);
                    if (input.Length > 0) return input[0]; }
                return 0;
            }
            public static string ReadLine()
            {
                if (frmIO != null) lock (frmIO) { return frmIO.Read(true); }
                else return "";
            }
        }
    }
    
    使用系统;
    使用System.Collections.Generic;
    使用系统组件模型;
    使用系统数据;
    使用系统图;
    使用系统文本;
    使用System.Windows.Forms;
    使用系统线程;
    使用System.Runtime.InteropServices;
    名称空间ProgramIO.Control
    {
    公共委托void WriteDelegate(字符串值,int x,int y);
    公共委托void ReadDelegate(输出字符串值,bool readLine);
    公共委托void EnableInputDelegate(bool enable);
    公共部分类交互窗体:窗体
    {
    私有委托无效ClearInputBufferDelegate();
    公共枚举eIO操作{None=0,写入,读取}
    私有EventWaitHandle eventInvoke=
    新的EventWaitHandle(false,EventResetMode.AutoReset);
    私有EventWaitHandle eventInput=
    新的EventWaitHandle(false,EventResetMode.AutoReset);
    private bool readLine=false;
    私有字符串inputBuffer=“”;
    私有int inputPosition=0;
    私有int inputBufferPosition=0;
    私人电子运营;
    私有int bufferSize=0x10000;
    private bool CaretShown=假;
    私有委托对象DoInvokeDelegate(委托方法,参数对象[]args);
    私有委托void setTitleDeleteGate(字符串值);
    私有委托void SetForegroundcolorDelegate(颜色值);
    公共字符串标题{
    获取{返回文本;}
    设置{
    if(invokererequired)InvokeEx(
    (SetTitleDelegate)委托(字符串标题){Text=title;},
    1000,新对象[]{value});
    else Text=value;}}
    公共色背景色{
    获取{return ForeColor;}
    设置{
    if(invokererequired)InvokeEx(
    (SetForegroundcolorDelegate)委托(颜色){ForeColor=Color;},
    1000,新对象[]{value});
    else ForeColor=value;}}
    公共交互表单()
    {
    初始化组件();
    双缓冲=真;
    }
    #区域异步方法
    私有bool InvokeEx(委托方法,int超时,参数对象[]args)
    {
    BeginInvoke((DoInvokeDelegate)DoInvoke,新对象[]{method,args});
    if(eventInvoke.WaitOne(timeout))返回true;
    否则返回false;
    }
    私有void启用输入(bool启用)
    {
    如果(需要调用)
    InvokeEx((EnableInputDelegate)DoEnableInput,1000,新对象[]{enable});
    else-DoEnableInput(启用);
    }
    私有void ClearInputBuffer()
    {
    如果(需要调用)
    InvokeEx((ClearInputBufferDelegate)DoClearInputBuffer,1000,新对象[0]);
    else doclearnInputBuffer();
    }
    公共空写(字符串值,int x=-1,int y=-1)
    {
    锁(这个){
    IOOperation=eioooperation.Write;
    如果(需要调用)
    InvokeEx((WriteDelegate)DoWrite,1000,新对象[]{value,x,y});
    else-DoWrite(值x,y);
    IOOperation=EIOOperation.None;}
    }
    公共字符串读取(bool readLine)
    {
    锁(这个){
    启用输入(真);
    IOOperation=EIOOperation.Read;this.readLine=readLine;字符串值=”;
    ClearInputBuffer();eventInput.WaitOne();
    对象[]args=新对象[]{value,readLine};
    如果(需要调用){
    InvokeEx((ReadDelegate)DoRead,1000,args);值=(字符串)args[0];}
    else DoRead(输出值,读线);
    //inputPosition=textBox.Text.Length;inputBuffer=“”;
    ClearInputBuffer();
    IOOperation=EIOOperation.None;
    启用输入(假);
    返回值;
    }
    }
    #endregion//Asynchro