Windows服务无法在发布

时间:2018-02-12 18:34:52

标签: c# .net windows-services

这有点奇怪,过去一周我一直绞尽脑汁试图解决这个问题。

我有一个Windows服务,它将作为一个新的站点启动器(内部工具)。我在解决方案中有5个项目:

  • IISWrapper(.NET Standard 2.0)
  • SiteLauncher(这是服务项目)(.NET Framework 4.7)
  • SiteLauncher.Debug(用于调试Web界面的控制台应用程序)(.NET Framework 4.7)
  • SiteLauncher.Actions(.NET Framework 4.7)
  • SiteLauncher.WebUI(.NET Framework 4.7)

我使用NancyFx自托管作为网络界面。所有5个项目都是使用Visual Studio中设置的x86体系结构构建的。 IISWrapper引用了Micorosft.Web.Administration,它是.NET Core,所以它必须是.NET Standard才能使用它。

这一切都有效。只要服务是在调试中构建的。如果我将其切换到Release,当我尝试与IIS交互时会出现这样的错误:

  

无法加载文件或程序集“System.Diagnostics.TraceSource,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b03f5f7f11d50a3a'或其中一个依赖项。定位的程序集的清单定义与程序集引用不匹配。 (HRESULT异常:0x80131040)

at Microsoft.Web.Administration.ConfigurationManager.CreateAdminManager[TClass,TInterface](WebConfigurationMap webConfigMap, Boolean isAdminConfig, Boolean isRedirectionConfig)
at Microsoft.Web.Administration.ConfigurationManager.CreateWritableAdminManager(WebConfigurationMap webConfigMap, String configPathToEdit, Boolean isAdminConfig, Boolean isRedirectionConfig)
at Microsoft.Web.Administration.ConfigurationManager.CreateConfiguration(WebConfigurationMap configMap, String configPathToEdit, Boolean isAdminConfig, Boolean isRedirectionConfig)
at Microsoft.Web.Administration.ConfigurationManager.GetConfiguration(String rawConfigurationPath, String cacheKey, Boolean isAdminConfig, Boolean isRedirectionConfig)
at Microsoft.Web.Administration.ConfigurationManager.GetApplicationHostConfiguration()
at Microsoft.Web.Administration.ServerManager.ApplicationPoolsSectionCreator()
at Microsoft.Web.Administration.Lazy.Initialize[T](T& target, CreateInstanceDelegate`1 valueFactory)
at Microsoft.Web.Administration.ServerManager.get_ApplicationPoolsSection()
at Microsoft.Web.Administration.ServerManager.ApplicationPoolCollectionCreator()
at Microsoft.Web.Administration.Lazy.Initialize[T](T& target, CreateInstanceDelegate`1 valueFactory)
at Microsoft.Web.Administration.ServerManager.get_ApplicationPools()
at IISWrapper.IISManager.CreateAppPool(String appPoolName, String userName, String password, Int64 memoryLimit)
at SiteLauncher.Actions.NewSiteSetup.SetUpSite(SiteCreatedEventArgs ev) in C:\Websites\manwaringweb\SiteLauncher\SiteLauncher.Actions\NewSiteSetup.cs:line 303
at SiteLauncher.Actions.NewSiteSetup.SvnUpdate_DoWork(Object sender, DoWorkEventArgs e) in C:\Websites\manwaringweb\SiteLauncher\SiteLauncher.Actions\NewSiteSetup.cs:line 53

NewSiteSetup.cs第303行是using语句:

Console.WriteLine($"{DateTime.Now:g}: Creating website...");
using (IISManager manager = new IISManager())
{
    manager.CreateAppPool(ev.Site.DomainName, ev.DbName, userPass);
    Directory.CreateDirectory($@"C:\inetpub\{ev.Site.DomainName}");
    manager.CreateWebsite(ev.Site.DomainName, $@"C:\inetpub\{ev.Site.DomainName}");
}

IISManager.CreateAppPool方法:

public void CreateAppPool(string appPoolName, string userName, string password, long memoryLimit = 200000)
{
    ApplicationPool pool = _manager.ApplicationPools.Add(appPoolName);
    pool.Enable32BitAppOnWin64 = true;
    pool.Recycling.PeriodicRestart.PrivateMemory = memoryLimit;
    pool.Cpu.Action = ProcessorAction.NoAction;
    pool.Cpu.Limit = 30000;
    pool.Failure.RapidFailProtectionMaxCrashes = 10;
    pool.ProcessModel.IdentityType = ProcessModelIdentityType.SpecificUser;
    pool.ProcessModel.UserName = userName;
    pool.ProcessModel.Password = password;
    pool.ManagedPipelineMode = ManagedPipelineMode.Integrated;

    _manager.CommitChanges();
}

我已验证此库存在于输出文件夹中。奇怪的是,我也在发布的控制台应用程序项目中得到了这个。我不知道区别是什么。

我已验证服务和控制台应用中安装了相同的软件包。两者似乎都在调试模式下工作,但在发布模式下失败。

服务类:

public partial class SiteLauncher : ServiceBase
{
    NancyHost _host;

    public SiteLauncher()
    {
        InitializeComponent();
    }

    protected override void OnStart(string[] args)
    {
        _host = new NancyHost(new Uri("http://localhost:9664"));
        _host.Start();

        WebEvents events = new WebEvents();
        events.SiteCreated += Events_SiteCreated;
        Bootstrapper.webEvents = events;
    }

    private void Events_SiteCreated(object sender, SiteCreatedEventArgs e)
    {
        NewSiteSetup.Initialize(e);
    }

    protected override void OnStop()
    {
        _host.Stop();
    }
}

控制台应用程序Program.cs:

class Program
{
    static void Main(string[] args)
    {
        var nancyHost = new NancyHost(new Uri("http://localhost:9664"));
        nancyHost.Start();
        Console.WriteLine("Web server running on http://localtest.me:9664...");

        WebEvents events = new WebEvents();
        events.SiteCreated += Events_SiteCreated;
        Bootstrapper.webEvents = events;


        Console.ReadLine();
        nancyHost.Stop();
    }

    private static void Events_SiteCreated(object sender, SiteCreatedEventArgs e)
    {
        Console.WriteLine($"{DateTime.Now:g}: Site {e.Site.DomainName} (ID: {e.Site.Id}) Created, with Repo: {e.Repository}");

        NewSiteSetup.Initialize(e);
    }
}

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

NuGet版本的Microsoft.Web.Administration专为IIS管理REST API而设计。请使用本地IIS附带的版本。

更多信息可在my blog post中找到。