ann*_*lie 38 c# deployment install windows-services
我正在尝试部署Windows服务但不太确定如何正确执行.我将它构建为控制台应用程序,我现在将其转换为Windows服务项目,并从服务中的OnStart方法调用我的类.
我现在需要在没有Visual Studio的服务器上安装它,如果我正确理解它意味着我不能使用InstallUtil.exe而必须创建一个安装程序类.它是否正确?
我确实看过上一个问题,安装没有InstallUtil.exe的.NET Windows服务,但我只是想确保我已经正确理解它.
如果我创建了问题的接受答案链接到的类,下一步是什么?将MyService.exe和MyService.exe.config上传到服务器,双击exe文件,Bob是我的叔叔?
该服务只能安装在一台服务器上.
Hoà*_*ong 49
我知道这是一个非常古老的问题,但最好用新信息更新它.
您可以使用sc命令安装服务:
InstallService.bat:
@echo OFF
echo Stopping old service version...
net stop "[YOUR SERVICE NAME]"
echo Uninstalling old service version...
sc delete "[YOUR SERVICE NAME]"
echo Installing service...
rem DO NOT remove the space after "binpath="!
sc create "[YOUR SERVICE NAME]" binpath= "[PATH_TO_YOUR_SERVICE_EXE]" start= auto
echo Starting server complete
pause
Run Code Online (Sandbox Code Playgroud)
使用SC,您还可以执行更多操作:卸载旧服务(如果您之前已经安装过),检查是否存在具有相同名称的服务...甚至将您的服务设置为自动启动.
许多参考资料之一:使用sc.exe创建服务; 如何传入上下文参数
我用这种方式完成了InstallUtil.就个人而言,我觉得使用SC更清洁,更健康.
Geo*_*kos 32
您仍然可以在没有visual studio的情况下使用installutil,它包含在.net框架中
在服务器上,以管理员身份打开命令提示符:
CD C:\Windows\Microsoft.NET\Framework\v4.0.version (insert your version)
installutil "C:\Program Files\YourWindowsService\YourWindowsService.exe" (insert your service name/location)
Run Code Online (Sandbox Code Playgroud)
要卸载:
installutil /u "C:\Program Files\YourWindowsService\YourWindowsService.exe" (insert your service name/location)
Run Code Online (Sandbox Code Playgroud)
Mat*_*vis 18
该InstallUtil.exe工具只是针对服务中的安装程序组件的一些反射调用的包装器.因此,它实际上没有做太多,但运用这些安装程序组件提供的功能.Marc Gravell的解决方案只是提供了一种从命令行执行此操作的方法,这样您就不必再依赖InstallUtil.exe目标计算机了.
这是我基于Marc Gravell解决方案的一步一步.
为什么不创建一个安装项目?这真的很容易.
瞧,你已经完成了.
有关更多信息,请参见此处:http: //www.codeproject.com/KB/dotnet/simplewindowsservice.aspx
还有一种方法可以提示用户输入凭据(或提供自己的凭据).
这是一个基础服务类(ServiceBase 子类),可以将其子类化以构建可以从命令行轻松安装的 Windows 服务,无需 installutil.exe。此解决方案源自如何在安装后立即启动 .NET Windows 服务?,添加一些代码以使用调用 StackFrame 获取服务类型
public abstract class InstallableServiceBase:ServiceBase
{
/// <summary>
/// returns Type of the calling service (subclass of InstallableServiceBase)
/// </summary>
/// <returns></returns>
protected static Type getMyType()
{
Type t = typeof(InstallableServiceBase);
MethodBase ret = MethodBase.GetCurrentMethod();
Type retType = null;
try
{
StackFrame[] frames = new StackTrace().GetFrames();
foreach (StackFrame x in frames)
{
ret = x.GetMethod();
Type t1 = ret.DeclaringType;
if (t1 != null && !t1.Equals(t) && !t1.IsSubclassOf(t))
{
break;
}
retType = t1;
}
}
catch
{
}
return retType;
}
/// <summary>
/// returns AssemblyInstaller for the calling service (subclass of InstallableServiceBase)
/// </summary>
/// <returns></returns>
protected static AssemblyInstaller GetInstaller()
{
Type t = getMyType();
AssemblyInstaller installer = new AssemblyInstaller(
t.Assembly, null);
installer.UseNewContext = true;
return installer;
}
private bool IsInstalled()
{
using (ServiceController controller =
new ServiceController(this.ServiceName))
{
try
{
ServiceControllerStatus status = controller.Status;
}
catch
{
return false;
}
return true;
}
}
private bool IsRunning()
{
using (ServiceController controller =
new ServiceController(this.ServiceName))
{
if (!this.IsInstalled()) return false;
return (controller.Status == ServiceControllerStatus.Running);
}
}
/// <summary>
/// protected method to be called by a public method within the real service
/// ie: in the real service
/// new internal void InstallService()
/// {
/// base.InstallService();
/// }
/// </summary>
protected void InstallService()
{
if (this.IsInstalled()) return;
try
{
using (AssemblyInstaller installer = GetInstaller())
{
IDictionary state = new Hashtable();
try
{
installer.Install(state);
installer.Commit(state);
}
catch
{
try
{
installer.Rollback(state);
}
catch { }
throw;
}
}
}
catch
{
throw;
}
}
/// <summary>
/// protected method to be called by a public method within the real service
/// ie: in the real service
/// new internal void UninstallService()
/// {
/// base.UninstallService();
/// }
/// </summary>
protected void UninstallService()
{
if (!this.IsInstalled()) return;
if (this.IsRunning()) {
this.StopService();
}
try
{
using (AssemblyInstaller installer = GetInstaller())
{
IDictionary state = new Hashtable();
try
{
installer.Uninstall(state);
}
catch
{
throw;
}
}
}
catch
{
throw;
}
}
private void StartService()
{
if (!this.IsInstalled()) return;
using (ServiceController controller =
new ServiceController(this.ServiceName))
{
try
{
if (controller.Status != ServiceControllerStatus.Running)
{
controller.Start();
controller.WaitForStatus(ServiceControllerStatus.Running,
TimeSpan.FromSeconds(10));
}
}
catch
{
throw;
}
}
}
private void StopService()
{
if (!this.IsInstalled()) return;
using (ServiceController controller =
new ServiceController(this.ServiceName))
{
try
{
if (controller.Status != ServiceControllerStatus.Stopped)
{
controller.Stop();
controller.WaitForStatus(ServiceControllerStatus.Stopped,
TimeSpan.FromSeconds(10));
}
}
catch
{
throw;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
您所要做的就是在您的实际服务中实现两个公共/内部方法:
new internal void InstallService()
{
base.InstallService();
}
new internal void UninstallService()
{
base.UninstallService();
}
Run Code Online (Sandbox Code Playgroud)
然后在您要安装服务时调用它们:
static void Main(string[] args)
{
if (Environment.UserInteractive)
{
MyService s1 = new MyService();
if (args.Length == 1)
{
switch (args[0])
{
case "-install":
s1.InstallService();
break;
case "-uninstall":
s1.UninstallService();
break;
default:
throw new NotImplementedException();
}
}
}
else {
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new MyService()
};
ServiceBase.Run(MyService);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
92191 次 |
| 最近记录: |