Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在linux中以非根用户身份运行mono服务_Linux_Service_Mono_Root_Daemon - Fatal编程技术网

在linux中以非根用户身份运行mono服务

在linux中以非根用户身份运行mono服务,linux,service,mono,root,daemon,Linux,Service,Mono,Root,Daemon,我需要在一个嵌入式系统上运行一个.NETC#应用程序(在Windows系统上开发),作为一个服务/守护进程,只需最少的Ubuntu安装(没有X,除了ssh没有服务器,只有相关软件)。我创建了一个包含行的/etc/init.d脚本 mono-service my-.net-app.exe service 这很有效。还有一个选项可以使用以交互方式启动应用程序(用于调试目的) 最后一个参数是.NET应用程序的参数,告诉它是否作为服务运行。这大致是这样实现的: private static void

我需要在一个嵌入式系统上运行一个.NETC#应用程序(在Windows系统上开发),作为一个服务/守护进程,只需最少的Ubuntu安装(没有X,除了ssh没有服务器,只有相关软件)。我创建了一个包含行的
/etc/init.d
脚本

mono-service my-.net-app.exe service
这很有效。还有一个选项可以使用以交互方式启动应用程序(用于调试目的)

最后一个参数是.NET应用程序的参数,告诉它是否作为服务运行。这大致是这样实现的:

private static void Main(string[] args){
  if(args.Any() && args[0] != null && args[0] == "service"){
    ServiceBase.Run(new[] {(ServiceBase) new MyService()});
  }else{
    try{
      Console.Write("starting app");
      if(StartWork()){
        Console.Write("press any key to exit");
        Console.ReadKey();
      }else{
        Console.WriteLine("starting app failed");
      }
    } // end try
    finally{
      StopWork();
      Console.WriteLine("finished app");
    }
  } // end else
...
} // end Main

public class MyService : ServiceBase{
  static private Thread _worker;

  protected override void OnStart(string[] args){
    _worker = new Thread(() => Program.StartWork(asService: true)); // this asService tells StartWork to not produce console output
    _worker.Start();
  }

  protected override void OnStop(){
    Program.StopWork();
    _worker.Join(1000);
  }
}
此实现的目的是允许应用程序在linux机器上发送
SIGTERM
时优雅地消亡(即执行
StopWork()

出于安全原因,我需要能够以非root用户身份运行服务。我创建了一个新用户,使其成为应用程序写入其日志文件的目录的所有者,并将其添加到各个组中,以使其能够访问所需的设备文件。然后,root将启动应用程序作为

sudo -u newuser mono-service my-.net-app.exe service

使用
mono
的第二个选项运行良好,但使用
mono服务的第一个选项运行不正常(请参见下面的错误消息)。由于它与
mono
配合使用,我相信用户
newuser
拥有访问所有相关文件和设备的适当权限。我想知道
mono服务
是否被认为是一个仅限根用户的应用程序

我还可以使用
mono
选项并抑制控制台输出,如下所示:

private static void Main(string[] args){
  try{
    Console.Write("starting app");
    if(StartWork(consoleoutput)){ // true or false depending on whether the service argument was given
      Console.Write("press any key to exit");
      Console.ReadKey();
    }else{
      Console.WriteLine("starting app failed");
    }
  } // end try
  finally{
    StopWork();
    Console.WriteLine("finished app");
  }
...
} // end Main
但是,当我终止服务(即向
mono
进程发送SIGTERM)时,它会立即停止.net应用程序,而不允许它执行
finally

最后,我的问题是,是否有人知道为什么
mono服务
在没有以root用户身份启动时会失败。错误消息如下所示,正如我前面提到的,当我使用
mono
而不是
mono服务时,它不存在

ERROR Program [4] [15:03:06.795 01/12/14] Error in Main!
FluentNHibernate.Cfg.FluentConfigurationException: An invalid or incomplete configuration was used while creating a SessionFactory. Check PotentialReasons collection, and InnerException for more detail.

---> NHibernate.HibernateException: Could not create the driver from SAFEmine.DataStore.Database.MonoSqliteDriver, SAFEmine.DataStore, Version=1.3.0.6, Culture=neutral, PublicKeyToken=null. ---> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> NHibernate.HibernateException: The IDbCommand and IDbConnection implementation in the assembly Mono.Data.Sqlite could not be found. Ensure that the assembly Mono.Data.Sqlite is located in the application directory or in the Global Assembly Cache. If the assembly is in the GAC, use <qualifyAssembly/> element in the application configuration file to specify the full name of the assembly.
at NHibernate.Driver.ReflectionBasedDriver..ctor (System.String providerInvariantName, System.String driverAssemblyName, System.String connectionTypeName, System.String commandTypeName) [0x00000] in <filename unknown>:0 
at NHibernate.Driver.ReflectionBasedDriver..ctor (System.String driverAssemblyName, System.String connectionTypeName, System.String commandTypeName) [0x00000] in <filename unknown>:0 
at SAFEmine.DataStore.Database.MonoSqliteDriver..ctor () [0x00000] in <filename unknown>:0 
at (wrapper managed-to-native) System.Reflection.MonoCMethod:InternalInvoke (System.Reflection.MonoCMethod,object,object[],System.Exception&)
at System.Reflection.MonoCMethod.InternalInvoke (System.Object obj, System.Object[] parameters) [0x00000] in <filename unknown>:0 
错误程序[4][15:03:06.795 01/12/14]主程序出错!
FluentNHibernate.Cfg.FluentConfigurationException:创建SessionFactory时使用了无效或不完整的配置。有关详细信息,请检查潜在原因集合和InnerException。
--->NHibernate.HibernateeException:无法从SAFEmine.DataStore.Database.MonoSqliteDriver、SAFEmine.DataStore、版本=1.3.0.6、区域性=neutral、PublicKeyToken=null创建驱动程序。-->System.Reflection.TargetInvocationException:调用的目标已引发异常。-->NHibernate.HibernateeException:在程序集Mono.Data.Sqlite中找不到IDbCommand和IDbConnection实现。确保程序集Mono.Data.Sqlite位于应用程序目录或全局程序集缓存中。如果程序集位于GAC中,请使用应用程序配置文件中的元素指定程序集的全名。
在NHibernate.Driver.ReflectionBasedDriver..ctor(System.String providerInvariantName、System.String DriversEmblyname、System.String connectionTypeName、System.String commandTypeName)[0x00000]处,输入:0
位于:0中的NHibernate.Driver.ReflectionBasedDriver..ctor(System.String DriversAssemblyName、System.String connectionTypeName、System.String commandTypeName)[0x00000]处
位于:0中的SAFEmine.DataStore.Database.MonoSqliteDriver..ctor()[0x00000]
at(包装器管理为本机)System.Reflection.MonoCMethod:InternalInvoke(System.Reflection.MonoCMethod,object,object[],System.Exception&)
在System.Reflection.Method.InternalInvoke(System.Object obj,System.Object[]参数)[0x00000]中:0

或者,如果我满足于使用
mono
而不是
mono服务
,有没有办法从.net应用程序中捕获
SIGTERM
,然后优雅地死去?我试过这样做:,但代码在VisualStudio上无法编译,因为
使用的是Mono.Unix
行的code>和
无效。我也在Windows上安装了Mono,并尝试使用Mono编译器,但它抱怨了同样的问题。

Mono service.exe
创建了一个新的
AppDomain
,其中
ApplicationBase
是当前目录。这可能会影响程序集加载。由于您看到这样的错误,我将尝试启用
MONO\u LOG\u LEVEL=debug MONO\u LOG\u MASK=asm
和/或
strace-e file
,以查看它们是否提供了任何提示

还请注意,您可以将
-d
切换到
mono服务
,让它为您更改目录。

mono.Unix
位于。
private static void Main(string[] args){
  try{
    Console.Write("starting app");
    if(StartWork(consoleoutput)){ // true or false depending on whether the service argument was given
      Console.Write("press any key to exit");
      Console.ReadKey();
    }else{
      Console.WriteLine("starting app failed");
    }
  } // end try
  finally{
    StopWork();
    Console.WriteLine("finished app");
  }
...
} // end Main
ERROR Program [4] [15:03:06.795 01/12/14] Error in Main!
FluentNHibernate.Cfg.FluentConfigurationException: An invalid or incomplete configuration was used while creating a SessionFactory. Check PotentialReasons collection, and InnerException for more detail.

---> NHibernate.HibernateException: Could not create the driver from SAFEmine.DataStore.Database.MonoSqliteDriver, SAFEmine.DataStore, Version=1.3.0.6, Culture=neutral, PublicKeyToken=null. ---> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> NHibernate.HibernateException: The IDbCommand and IDbConnection implementation in the assembly Mono.Data.Sqlite could not be found. Ensure that the assembly Mono.Data.Sqlite is located in the application directory or in the Global Assembly Cache. If the assembly is in the GAC, use <qualifyAssembly/> element in the application configuration file to specify the full name of the assembly.
at NHibernate.Driver.ReflectionBasedDriver..ctor (System.String providerInvariantName, System.String driverAssemblyName, System.String connectionTypeName, System.String commandTypeName) [0x00000] in <filename unknown>:0 
at NHibernate.Driver.ReflectionBasedDriver..ctor (System.String driverAssemblyName, System.String connectionTypeName, System.String commandTypeName) [0x00000] in <filename unknown>:0 
at SAFEmine.DataStore.Database.MonoSqliteDriver..ctor () [0x00000] in <filename unknown>:0 
at (wrapper managed-to-native) System.Reflection.MonoCMethod:InternalInvoke (System.Reflection.MonoCMethod,object,object[],System.Exception&)
at System.Reflection.MonoCMethod.InternalInvoke (System.Object obj, System.Object[] parameters) [0x00000] in <filename unknown>:0