草庐IT

部署jar包windows服务工具

code2roc 2023-04-19 原文

背景

某个周末一个线上项目因为服务器自动重启导致了系统挂了,我们是通过jenkins部署的jar包所以需要手动重启项目,解决问题后准备调换部署方式让项目随系统自动启动,试用tomcat后发现启动慢,并且日常开发springboot都是使用内置tomcat启动,如果要保持和部署方式保持一致(避免本地代码执行和部署方式不一致导致的bug),需要配置外部tomcat比较麻烦,所以决定还是以java -jar命令方式启动并注册为window服务

项目地址:https://gitee.com/code2roc/deploy-jar-util

环境依赖

  • windows系统

  • 安装framework4.0

  • 安装jdk配置环境变量

    jdk可以使用免安装版本(1.8)点击bat文件快速一键配置,下载地址如下

    https://yunpan.360.cn/surl_y83kPfrK6n7 (提取码:c4f2)

功能介绍

工具包含【服务名称】【jar包路径】【部署端口】【执行结果】【操作按钮】五个部分

  • 服务名称

对应的就是安装后windows服务的名字

  • jar包路径

部署项目的jar文件物理路径

  • 部署端口

默认为空不指定使用配置文件中端口,指定后使用自定义端口

  • 执行结果

显示安装/卸载/启动/关闭服务适输出的操作日志

  • 操作按钮

在进行服务操作前必须将所有配置确定输入后点击保存配置按钮

安装/卸载/启动/停止四个按钮对应相关windows服务的操作

服务安装后默认停止状态,需要手动启动,服务启动方式为自动

点击启动服务后会自动弹出启动日志界面动态刷新日志内容,若关闭了日志窗口,则进入deploylog文件夹查看deploy.out.log文件,每次启动项目该文件内容自动重置清除

实现介绍

window服务安装

使用开源组件winsw(https://github.com/winsw/winsw/),获取编译好的exe运行文件和xml配置文件,调用cmd进行相关命令操作,例如安装操作如下所示,页面相关配置保存读取直接操作xml文件即可

  private void btn_InstallService_Click(object sender, EventArgs e)
        {
            string command = "deploy.exe install";
            StartCmd(AppDomain.CurrentDomain.BaseDirectory, command, FinishCommand);
        }
  public void StartCmd(String workingDirectory, String command, EventHandler FinsishEvent)
        {
            Process p = new Process();
            p.StartInfo.FileName = "cmd.exe";
            p.StartInfo.WorkingDirectory = workingDirectory;
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardInput = true;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.CreateNoWindow = true;
            p.EnableRaisingEvents = true;  // 启用Exited事件  
            p.Exited += FinsishEvent;   // 注册进程结束事件  
            p.Start();
            p.StandardInput.WriteLine(command);
            p.StandardInput.WriteLine("exit");
            p.StandardInput.AutoFlush = true;
            string strOuput = p.StandardOutput.ReadToEnd();
            txt_Result.Text = strOuput;
            //等待程序执行完退出进程
            p.WaitForExit();
            p.Close();
        }

服务状态监控

通过引入System.ServiceProcess程序集调用服务相关api

  public void InitOpStatus()
        {
            btn_InstallService.Enabled = false;
            btn_StartService.Enabled = false;
            btn_UnstallService.Enabled = false;
            btn_StopService.Enabled = false;
            var serviceControllers = ServiceController.GetServices();
            bool existservice = false;
            foreach (var service in serviceControllers)
            {
                if (service.ServiceName == txt_ServerName.Text)
                {
                    existservice = true;
                    break;
                }
            }
            if (existservice)
            {
                var server = serviceControllers.FirstOrDefault(service => service.ServiceName == txt_ServerName.Text);
                if (server.Status == ServiceControllerStatus.Running)
                {
                    //服务运行中允许停止
                    btn_StopService.Enabled = true;
                }
                else
                {
                    //服务未运行允许卸载和启动
                    btn_UnstallService.Enabled = true;
                    btn_StartService.Enabled = true;
                }
            }
            else
            {
                //无此服务允许安装
                btn_InstallService.Enabled = true;
            }

        }

启动日志显示

使用定时器,不断刷新deploylog\deploy.out.log日志文件

   System.Windows.Forms.Timer timer;
        public LogForm()
        {
            InitializeComponent();
        }

        private void LogForm_Load(object sender, EventArgs e)
        {
            timer = new System.Windows.Forms.Timer();
            //1秒间隔
            timer.Interval = 1000;
            //执行事件
            timer.Tick += (s, e1) =>
            {
                RefreshLogContent();
            };
            //开始执行
            timer.Start();
        }


        public void RefreshLogContent()
        {
            string logPath = AppDomain.CurrentDomain.BaseDirectory + "deploylog\\deploy.out.log";
            string logContent = ReadFileContent(logPath);
            SetTextCallback d = new SetTextCallback(SetText);
            this.txt_Log.Invoke(d, new object[] { logContent });
        }

        public string ReadFileContent(string FileFullName)
        {
            if (File.Exists(FileFullName))
            {
                System.IO.FileStream fs = new System.IO.FileStream(FileFullName, System.IO.FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                string FileContent = "";
                try
                {
                    int fsLen = Convert.ToInt32(fs.Length);
                    byte[] heByte = new byte[fsLen];
                    int r = fs.Read(heByte, 0, heByte.Length);
                    FileContent = System.Text.Encoding.Default.GetString(heByte);
                }
                catch (Exception e)
                {
                    throw;
                }
                finally
                {
                    fs.Close();
                    fs.Dispose();
                }
                return FileContent;
            }
            else
            {
                return "";
            }

        }

        delegate void SetTextCallback(string text);

        private void SetText(string text)
        {
            txt_Log.Text = "";
            txt_Log.AppendText(text);
        }

        private void LogForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            timer.Stop();
        }

有关部署jar包windows服务工具的更多相关文章

  1. ruby - 使用 ruby​​ 和 savon 的 SOAP 服务 - 2

    我正在尝试使用ruby​​和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我

  2. ruby - 在 Ruby 程序执行时阻止 Windows 7 PC 进入休眠状态 - 2

    我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0

  3. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  4. ruby-on-rails - 启动 Rails 服务器时 ImageMagick 的警告 - 2

    最近,当我启动我的Rails服务器时,我收到了一长串警告。虽然它不影响我的应用程序,但我想知道如何解决这些警告。我的估计是imagemagick以某种方式被调用了两次?当我在警告前后检查我的git日志时。我想知道如何解决这个问题。-bcrypt-ruby(3.1.2)-better_errors(1.0.1)+bcrypt(3.1.7)+bcrypt-ruby(3.1.5)-bcrypt(>=3.1.3)+better_errors(1.1.0)bcrypt和imagemagick有关系吗?/Users/rbchris/.rbenv/versions/2.0.0-p247/lib/ru

  5. ruby-on-rails - s3_direct_upload 在生产服务器中不工作 - 2

    在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo

  6. ruby-on-rails - 每次我尝试部署时,我都会得到 - (gcloud.preview.app.deploy) 错误响应 : [4] DEADLINE_EXCEEDED - 2

    我是Google云的新手,我正在尝试对其进行首次部署。我的第一个部署是RubyonRails项目。我基本上是在关注thisguideinthegoogleclouddocumentation.唯一的区别是我使用的是我自己的项目,而不是他们提供的“helloworld”项目。这是我的app.yaml文件runtime:customvm:trueentrypoint:bundleexecrackup-p8080-Eproductionconfig.ruresources:cpu:0.5memory_gb:1.3disk_size_gb:10当我转到我的项目目录并运行gcloudprevie

  7. ruby - 在 Windows 机器上使用 Ruby 进行开发是否会适得其反? - 2

    这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby​​-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub

  8. ruby - 用 Ruby 编写一个简单的网络服务器 - 2

    我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b

  9. ruby-on-rails - 在 Rails 中调试生产服务器 - 2

    您如何在Rails中的实时服务器上进行有效调试,无论是在测试版/生产服务器上?我试过直接在服务器上修改文件,然后重启应用,但是修改好像没有生效,或者需要很长时间(缓存?)我也试过在本地做“脚本/服务器生产”,但是那很慢另一种选择是编码和部署,但效率很低。有人对他们如何有效地做到这一点有任何见解吗? 最佳答案 我会回答你的问题,即使我不同意这种热修补服务器代码的方式:)首先,你真的确定你已经重启了服务器吗?您可以通过跟踪日志文件来检查它。您更改的代码显示的View可能会被缓存。缓存页面位于tmp/cache文件夹下。您可以尝试手动删除

  10. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

随机推荐