调试Windows服务 - 阻止无法启动服务

时间:2017-03-07 13:01:19

标签: c#

尝试deubg一个Windows服务(删除了安装,代码,安装,代码等的需要..),以为我找到了解决方案

class Program
{
    static void Main(string[]args) 
    {
        ClientService service = new ClientService();

        if (args.Length > 0) 
        {
            Task.Factory.StartNew(service.Main, TaskCreationOptions.LongRunning);

            Console.WriteLine("running...");
            Console.ReadLine();

        }
        else 
        {
#if (!DEBUG)
            ServiceBase[]ServicesToRun;
            ServicesToRun = new ServiceBase[]
            {
                new MyService()
            };
            ServiceBase.Run(ServicesToRun);
# else
            ServiceBase.Run(service);
        }
# endif
    }
}

但是我仍然收到错误:

  

无法从命令行或调试器启动服务。首先必须安装Windows服务(使用installutil.exe),然后使用ServerExplorer,Windows服务管理工具或NET START命令启动。

enter image description here

任何想法我需要更改以避免提示?

4 个答案:

答案 0 :(得分:4)

您已复制Running Windows Service Application without installing it中的代码,但它已被设计破坏,并且您对其进行了错误更改。

它背后的想法是,你有一个func updateFeed(){ let uid = FIRAuth.auth()?.currentUser?.uid let ref = FIRDatabase.database().reference(fromURL: "https://firebaseio.com/") ref.child("users").child(uid!).child("Posts").observe(.value, with: { (snapshot) in for item in snapshot.children{ let snapshotValue = snapshot.value as? NSDictionary var snapString = String(describing: item) var snapInt = Int(snapString) self.postCollection.append(snapString) let firstName = (snapshot.value as! NSDictionary)["First Person"] as? String print("SnapShot: \(snapString)") //gives proper data self.postNumber = self.postCollection.count print("PostNumber: \(self.postNumber)") //equals 1 print("PostSource: \(self.postCollection)") } }) print("Number of Posts (After Adding): \(self.postCollection.count)") //equals 0 collectionView?.reloadData() } - 继承类,它包含一个执行实际服务逻辑的公共方法:

ServiceBase

然后在您的应用程序中,您可以这样开始:

public class MyService : ServiceBase
{
    public void DoTheServiceLogic()
    {
        // Does its thing
    }

    public override void OnStart(...)
    {
        DoTheServiceLogic();
    }
}

这提供了一个可以作为Windows服务安装的可执行应用程序。

但是您不想安装服务然后附加Visual Studio来调试它;这是一个非常低效的工作流程。

所以你发现尝试做的代码,就像在线发现的许多方法一样,是用一个命令行标志启动应用程序,比如class Program { static void Main(string[] args) { ServiceBase[] ServicesToRun = new ServiceBase[] { new MyService() }; ServiceBase.Run(ServicesToRun); } } ,然后调用服务逻辑上的公共方法 - 实际上没有将其作为Windows服务运行

可以这样实现:

/debug

现在,您可以指示Visual Studio在调试应用程序时传递class Program { static void Main(string[] args) { if (args.Length == 1 && args[0] == "/debug") { // Run as a Console Application new MyService().DoTheServiceLogic(); } else { // Run as a Windows Service ServiceBase[] ServicesToRun = new ServiceBase[] { new MyService() }; ServiceBase.Run(ServicesToRun); } } } 标志,如MSDN: How to: Set Start Options for Application Debugging中所述。

这稍微好一点,但仍然是一个糟糕的方法。您应该完全提取服务逻辑,并编写单元测试以便能够测试您的逻辑,而无需在应用程序中运行它,更不用说Windows服务了。

答案 1 :(得分:0)

以下是您可以做的事情:

创建一个与旅游服务同名的部分类:

 public partial class AlertEngineService
    {
        public void Run(string[] args)
        {

            OnStart(args);
            Console.WriteLine("Press any key to stop program alert engine service");
            Console.Read();
            OnStop();
        }
    }
}

并在debug:

上调用此命令
var servicesToRun = new ClientService ();
servicesToRun.Run(args);

您还可以将服务配置更改为以控制台身份运行(在属性部分中)。

希望有所帮助

答案 2 :(得分:0)

首先更改代码:

static void Main(string[] args)
{
#if DEBUG // If you are currently in debug mode
    ClientService service = new ClientService (); // create your service's instance
    service.Start(args); // start this service
    Console.ReadLine(); // wait for user input ( enter key )
#else // else you're in release mode
    ServiceBase[] ServicesToRun; // start service normally
    ServicesToRun = new ServiceBase[] 
    { 
        new MyService() 
    };
    ServiceBase.Run(ServicesToRun);
#endif
}

在您的服务中添加此方法:

public void Start(string[] args)
{
    OnStart(args);
}

现在您需要更改的是属性更改应用类型从Windows ApplicationConsole Application

答案 3 :(得分:0)

在Program.cs中

class Program
{
    static void Main(string[] args)
    {
        #if DEBUG
        new ClientService().Start();
        Thread.Sleep(Timeout.Infinite); //Ensure your service keeps running             
        #else
        ServiceBase[] ServicesToRun;
        ServicesToRun = new ServiceBase[] 
        { 
            new MyService() 
        };
        ServiceBase.Run(ServicesToRun);
        #endif
    }
}

在ClientService.cs

public void Start()
{
    OnStart(null);
}