【C#】Windows服务(Service)安装及启停

这篇具有很好参考价值的文章主要介绍了【C#】Windows服务(Service)安装及启停。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、创作背景

二、问题解决

2.1 安装Windows service服务

2.2 主方法Main()主方法改写

2.3 安装service服务/卸载service服务

2.4 服务启停

2.5 服务调用运行

2.6 关于权限的提升

三、资源分享

3.1 引入组件

3.2 新手使用


一、前言

我能抽象出整个世界,但是我不能抽象你。 想让你成为私有常量,这样外部函数就无法访问你。 又想让你成为全局常量,这样在我的整个生命周期都可以调用你。 可惜世上没有这样的常量,我也无法定义你,因为你在我心中是那么的具体。

哈喽大家好,本专栏为【项目实战】专栏,有别于【底层库】专栏,我们可以发现增加 了『问题描述』、『项目展示』章节,十分符合项目开发流程,让读者更加清楚项目解决的问题、以及产品能够达到的效果。本专栏收纳项目开发过程的解决方案,是我项目开发相对成熟、可靠方法的提炼,我将这些问题的解决思路梳理,撰写本文分享给大家,大家遇到类似问题,可按本文方案处理。

本专栏会持续更新,不断完善,专栏文章关联性较弱(文章之间依赖性较弱,没有阅读顺序)。大家有任何问题,可以私信我。如果您对本专栏感兴趣,欢迎关注吧,我将带你用最简洁的代码,实现复杂的功能。
 

二、创作背景

今天,我们完成了一个应用程序的开发,我们要将其设置成开机自启程序,继上篇文章介绍有两种方式。

一种,开机启动目录下创建应有程序的快捷方式;

另一种,写Windows服务;我们现在采用“服务方式自启程序”。

因为用户不具备管理员权限,为了安全考虑,我们方便监控管理。最终确认方案二。

先说说我们面临的问题,或者说是待解决的问题:

①安装服务,通过咱新开发的C#应用软件安装,不希望借助第三方工具(installutil.exe),因为面向人群非科班出身,操作越简单越好。

②开启、停止服务,不希望出现【黑色命令框】弹窗,看着就烦,用户体验不好。

③不希望出现Windows权限不够的提示框,因为用户是普通用户,不具备“管理员操作权限”,本程序有一些敏感操作,有需要最高权限,不要出现“权限不够,哪怕是否确认授权”消息提示框。

怎么样?需求是不是很变态,需要同时满足以上三点,网上很多技术教程已经不适用。变态需求即是挑战,下面我将介绍本文解决方案,彻底解决以上问题,希望可以帮助面临同样困状的你们。

三、解决方案

3.1 安装Windows service服务

点击【是否开机自启】,安装Windows service服务,并实现服务启停。

【C#】Windows服务(Service)安装及启停

3.2 主方法Main()主方法改写

Program.cs文件Main()有两种运行方式

①客户端方式启动,最常用的方式,相当于鼠标双击可执行程序

②服务service方式启动,采用Windows service安装,默认含有参数。

因此我们可以通过参数args区分两种方式,如下图代码所示,其中客户端启动参用“单例模式”,我这里使用了全局信号量卡控,一次只能运行一个程序客户端。

 static void Main(string[] args)
        {
            //ProcessExec processExec = new ProcessExec();
            //string aa = "";
            //processExec.MediaServiceStart("", out aa);

            if (args.Length > 0)
            {
                var serviceName = Const.ct_strServiceName;
                var host = HostFactory.New(x =>
                {
                    x.EnableShutdown();
                    x.Service<ServiceCtrl>();
                    x.RunAsLocalSystem();
                    x.SetDescription(Const.ct_strProjName);
                    x.SetDisplayName(serviceName);
                    x.SetServiceName(serviceName);
                });
                LogHelper.Info("***********主程序运行(服务方式)**********");
                host.Run();
            }
            else
            {
                bool createNew;
                //使用用互斥量(System.Threading.Mutex)只运行一个实列
                using (System.Threading.Mutex mutex = new System.Threading.Mutex(true, Application.ProductName, out createNew))
                {
                    if (createNew)
                    {
                        Application.EnableVisualStyles();
                        Application.SetCompatibleTextRenderingDefault(false);
                        LogHelper.Info("***********主程序运行(客户端方式)**********");
                        Application.Run(new FormMain());
                    }
                    else
                    {
                        System.Threading.Thread.Sleep(1000);
                        System.Environment.Exit(1);
                    }
                }
            }
            
    }

3.3 安装service服务/卸载service服务

①添加新项-->Windows服务--AutoPlayerService.cs

【C#】Windows服务(Service)安装及启停

 ②右键空白处,【添加安装程序】,它会自动创建ProjectInstaller.cs文件,打开该文件有两个组件serviceProcessInstaller1、serviceInstaller1

网上大部分文章,教你们在属性中填写 服务信息,这种方式存在缺陷,常常服务不能够自动注入,需要借助第三方工具写入注册表,我教你们另外一种方式,如下图所示:

【C#】Windows服务(Service)安装及启停【C#】Windows服务(Service)安装及启停

 ③我的方式,通过使用底层入口实现。

添加以下4行代码。

        [DllImport("kernel32.dll")]
        public static extern int WinExec(string CmdLine, int ShowCmd);

        [DllImport("shell32.dll")]
        public static extern int ShellExecute(IntPtr hWnd, string Operation, string FileName,
                                              string Parameters, string Directory, int ShowCmd);

 ④实现方法

安装服务

                string cmd = Application.ExecutablePath;
                cmd += " install";
                WinExec(cmd, 1);
                MessageBox.Show("服务安装完毕!");
                ShellExecute(this.Handle, "open", "Services.msc", "", "", 1);

卸载方法

                    ServiceStop(Const.ct_strServiceName);//停止服务
                    string cmd = Application.ExecutablePath;
                    cmd += " uninstall";
                    WinExec(cmd, 1);
                    MessageBox.Show("服务卸载完毕!");

3.4 服务启停

①创建服务类ServiceCtrl.cs ,实现接口ServiceControl。

  public class ServiceCtrl : ServiceControl
    {
        MainTimer m_MainTimer;

        public ServiceCtrl()
        {
            try
            {
                m_MainTimer = new MainTimer(21600);//6小时检查一次
                m_MainTimer.InitTimer();
            }
            catch (Exception err)
            {
                LogHelper.Error("初始化服务发生错误:" + err.ToString());
            }
        }

        /// <summary>
        /// 服务启动时执行
        /// </summary>
        /// <param name="c"></param>
        /// <returns></returns>
        public bool Start(Topshelf.HostControl c)
        {
            try
            {
                m_MainTimer.StartTimer();
                string l_strMsgError = "";
                if (SysParameter.shutdown_tag == "T")
                {
                    ProcessExec exec = new ProcessExec();
                    exec.StartShutDown(out l_strMsgError);
                }
                return true;
            }
            catch (Exception err)
            {
                LogHelper.Error("启动服务发生错误:" + err.ToString());
                return false;
            }
        }

        /// <summary>
        /// 服务关闭时执行
        /// </summary>
        /// <param name="c"></param>
        /// <returns></returns>
        public bool Stop(Topshelf.HostControl c)
        {
            try
            {
                m_MainTimer.StopTimer();
                return true;
            }
            catch (Exception err)
            {
                LogHelper.Error("停止服务发生错误:" + err.ToString());
                return false;
            }
        }
    }

②服务启动

        //启动服务
        public static void ServiceStart(string serviceName)
        {
            using (ServiceController control = new ServiceController(serviceName))
            {
                if (control.Status == ServiceControllerStatus.Stopped)
                {
                    control.Start();
                }
            }
        }

③服务停止

      //停止服务
        public static void ServiceStop(string serviceName)
        {
            using (ServiceController control = new ServiceController(serviceName))
            {
                if (control.Status == ServiceControllerStatus.Running)
                {
                    control.Stop();
                }
            }
        }

④判断服务是否在运行状态(可选)

        //判断服务状态
        public static bool IsServiceRuning(string serviceName)
        {
            ServiceController[] services = ServiceController.GetServices();
            foreach (ServiceController sc in services)
            {
                if (sc.ServiceName.ToLower() == serviceName.ToLower())
                {
                    if (sc.Status == ServiceControllerStatus.Running)
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
            }
            return false;
        }

3.5 服务调用运行

以上基本完成了服务的开发,关于服务调用我给一个案例:我这里鼠标右键点击,自动启动服务,开始执行主方法。

 //启动服务(Windows服务运行)
        private void BTN_ServiceRun_Click(object sender, EventArgs e)
        {
            m_service.Start(null);
            try
            {
                BTN_ServiceRun.Enabled = false;

                //ToDo:采用服务式,无dos黑框
                //string cmd = Const.ct_strServiceName;
                //cmd = "net start " + cmd;
                //FormSet.WinExec(cmd, 1);

                FormSet.ServiceStart(Const.ct_strServiceName);
                if (DataOperation.UpdateStateType("正在运行"))
                {
                    GC_Main.DataSource = DataOperation.SelectData();
                    GC_Main.RefreshDataSource();
                }
            }
            finally
            {
                BTN_ServiceStop.Enabled = true;
            }
        }

        //停止服务(Windows服务停止)
        private void BTN_ServiceStop_Click(object sender, EventArgs e)
        {
            m_service.Stop(null);
            try
            {
                BTN_ServiceStop.Enabled = false;

                FormSet.ServiceStop(Const.ct_strServiceName);
                if (DataOperation.UpdateStateType("已停止"))
                {
                    GC_Main.DataSource = DataOperation.SelectData();
                    GC_Main.RefreshDataSource();
                }
            }
            finally
            {
                BTN_ServiceRun.Enabled = true;
            }
        }

3.6 关于权限的提升

有时,你或许没有管理员权限,毕竟公司电脑嘛,每次服务开启都会有弹窗提示“权限不足”,很是厌烦,而且我们还要再次人工干预,这时你需要再程序中增加用户权限配置清单。

创建app.manifest应用程序清单文件。

<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
  <assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
    <security>
      <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
        <!-- UAC 清单选项
             如果想要更改 Windows 用户帐户控制级别,请使用
             以下节点之一替换 requestedExecutionLevel 节点。n
        <requestedExecutionLevel  level="asInvoker" uiAccess="false" />
        <requestedExecutionLevel  level="requireAdministrator" uiAccess="false" />
        <requestedExecutionLevel  level="highestAvailable" uiAccess="false" />

            指定 requestedExecutionLevel 元素将禁用文件和注册表虚拟化。
            如果你的应用程序需要此虚拟化来实现向后兼容性,则删除此
            元素。
        -->
        <requestedExecutionLevel  level="requireAdministrator" uiAccess="false" />
      </requestedPrivileges>
    </security>
  </trustInfo>

  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
    <application>
      <!-- 设计此应用程序与其一起工作且已针对此应用程序进行测试的
           Windows 版本的列表。取消评论适当的元素,
           Windows 将自动选择最兼容的环境。 -->

      <!-- Windows Vista -->
      <!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />-->

      <!-- Windows 7 -->
      <!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />-->

      <!-- Windows 8 -->
      <!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />-->

      <!-- Windows 8.1 -->
      <!--<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />-->

      <!-- Windows 10 -->
      <!--<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />-->

    </application>
  </compatibility>

  <!-- 指示该应用程序可以感知 DPI 且 Windows 在 DPI 较高时将不会对其进行
       自动缩放。Windows Presentation Foundation (WPF)应用程序自动感知 DPI,无需
       选择加入。选择加入此设置的 Windows 窗体应用程序(目标设定为 .NET Framework 4.6 )还应
       在其 app.config 中将 "EnableWindowsFormsHighDpiAutoResizing" 设置设置为 "true"。-->
  <!--
  <application xmlns="urn:schemas-microsoft-com:asm.v3">
    <windowsSettings>
      <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
    </windowsSettings>
  </application>
  -->

  <!-- 启用 Windows 公共控件和对话框的主题(Windows XP 和更高版本) -->
  <!--
  <dependency>
    <dependentAssembly>
      <assemblyIdentity
          type="win32"
          name="Microsoft.Windows.Common-Controls"
          version="6.0.0.0"
          processorArchitecture="*"
          publicKeyToken="6595b64144ccf1df"
          language="*"
        />
    </dependentAssembly>
  </dependency>
  -->

</assembly>

<requestedExecutionLevel  level="requireAdministrator" uiAccess="false" />这句代码帮你以管理员身份运行,这样就不会弹窗了。

四、资源分享

4.1 引入组件

你需要引入最强大的组件库 Geyc.Utils.dll,我已经本文介绍的方法封装了,本组件包含大量实战项目的操作类、底层库、UI控件等,定期更新补充。

倘若你在项目引用过程中,发现组件中的错误,或是库不支持,或是组件适配环境性问题,请联系我修改封装底层库文件。

链接:https://pan.baidu.com/s/1sEO9aH2_re7Xwa-WDL_V7w?pwd=l6d0 
提取码:l6d0

【C#】Windows服务(Service)安装及启停

4.2 新手使用

我已将方法封装,你也只需要几行代码就可以实现本文阐述的功能。

//判断服务是否运行
IsServiceRuning(string serviceName)

//安装服务
InstallService(string serviceFilePath)

//卸载服务
UninstallService(string serviceFilePath)

//启动服务
ServiceStart(string serviceName)

//停止服务
ServiceStop(string serviceName)

4.3 底层库源码

组件库 Geyc.Utils.dll中,你使用到的方法如下:

        [DllImport("kernel32.dll")]
        public static extern int WinExec(string CmdLine, int ShowCmd);

        [DllImport("shell32.dll")]
        public static extern int ShellExecute(IntPtr hWnd, string Operation, string FileName,
                                              string Parameters, string Directory, int ShowCmd);


     #region 开机自启项
        string serviceFilePath = Application.ExecutablePath;
        private void checkBox_AutoRun_CheckedChanged(object sender, EventArgs e)
        {
            if (!m_bStart) return;

            if (checkBox_AutoRun.Checked) //设置开机自启动  
            {
                string cmd = Application.ExecutablePath;
                cmd += " install";
                WinExec(cmd, 1);
                ShellExecute(this.Handle, "open", "Services.msc", "", "", 1);
                FrmTips.ShowTipsSuccess(this, "开机自启已启动!");

                AppConfig.SetValue("auto_run", "T");
            }
            else //取消开机自启动  
            {
                if (this.IsServiceExisted(Const.ct_strServiceName))
                {
                    ServiceStop(Const.ct_strServiceName);//停止服务
                    string cmd = Application.ExecutablePath;
                    cmd += " uninstall";
                    WinExec(cmd, 1);
                    FrmTips.ShowTipsSuccess(this, "开机自启已终止!");
                }
                AppConfig.SetValue("auto_run", "F");
            }
        }


        //判断服务是否存在
        private bool IsServiceExisted(string serviceName)
        {
            ServiceController[] services = ServiceController.GetServices();
            foreach (ServiceController sc in services)
            {
                if (sc.ServiceName.ToLower() == serviceName.ToLower())
                {
                    return true;
                }
            }
            return false;
        }

        #region 安装服务/卸载服务
        //安装服务
        private void InstallService(string serviceFilePath)
        {
            using (AssemblyInstaller installer = new AssemblyInstaller())
            {
                installer.UseNewContext = true;
                installer.Path = serviceFilePath;
                IDictionary savedState = new Hashtable();//空参数
                installer.Install(savedState);
                installer.Commit(savedState);
            }
        }

        //卸载服务
        private void UninstallService(string serviceFilePath)
        {
            using (AssemblyInstaller installer = new AssemblyInstaller())
            {
                installer.UseNewContext = true;
                installer.Path = serviceFilePath;
                installer.Uninstall(null);
            }
        }
        #endregion

        //判断服务状态
        public static bool IsServiceRuning(string serviceName)
        {
            ServiceController[] services = ServiceController.GetServices();
            foreach (ServiceController sc in services)
            {
                if (sc.ServiceName.ToLower() == serviceName.ToLower())
                {
                    if (sc.Status == ServiceControllerStatus.Running)
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
            }
            return false;
        }

        //启动服务
        public static void ServiceStart(string serviceName)
        {
            using (ServiceController control = new ServiceController(serviceName))
            {
                if (control.Status == ServiceControllerStatus.Stopped)
                {
                    control.Start();
                }
            }
        }

        //停止服务
        public static void ServiceStop(string serviceName)
        {
            using (ServiceController control = new ServiceController(serviceName))
            {
                if (control.Status == ServiceControllerStatus.Running)
                {
                    control.Stop();
                }
            }
        }
        #endregion

 五、系列文章

C#项目--业务单据号生成器(定义规则、自动编号、流水号)
本文链接:https://blog.csdn.net/youcheng_ge/article/details/129129787

C#项目--开始日期结束日期范围计算(上周、本周、明年、前年等)
本文链接:https://blog.csdn.net/youcheng_ge/article/details/129040663

C#项目--数据实体类使用
本文链接:https://blog.csdn.net/youcheng_ge/article/details/128816638

C#项目--单据审批流方案
本文链接:https://blog.csdn.net/youcheng_ge/article/details/128972545

C#项目--二维码标签制作及打印(完整版)
本文链接:https://blog.csdn.net/youcheng_ge/article/details/126884228

C#项目--条码管理操作手册
本文链接:https://blog.csdn.net/youcheng_ge/article/details/126589496

C#项目--WebAPI发布和IIS部署,及异常处理
本文链接:https://blog.csdn.net/youcheng_ge/article/details/126539836

C#项目--提高编程效率,代码自动生成
本文链接:https://blog.csdn.net/youcheng_ge/article/details/126890673

C#项目--提高编程效率,Excel数据导入工具
本文链接:https://blog.csdn.net/youcheng_ge/article/details/126427323

C#项目--Windows服务(Service)安装及启停方案
本文链接:https://blog.csdn.net/youcheng_ge/article/details/124053794

C#项目--穿透Session隔离,服务调用外部程序(无窗体界面解决)
本文链接:https://blog.csdn.net/youcheng_ge/article/details/124053033

C#项目--任务计划实现,使用Quartz类
本文链接:https://blog.csdn.net/youcheng_ge/article/details/123667723

C#项目--《周计划管理关于产前准备模块》解决方案20200203
本文链接:https://blog.csdn.net/youcheng_ge/article/details/122919543

C#项目--项目中,源码解析的正则表达式
本文链接:https://blog.csdn.net/youcheng_ge/article/details/118337074

C#项目--如何获取文件版本和MD5值
本文链接:https://blog.csdn.net/youcheng_ge/article/details/112513871

C#项目--如何测试网络是否连通
本文链接:https://blog.csdn.net/youcheng_ge/article/details/110137288文章来源地址https://www.toymoban.com/news/detail-401049.html

到了这里,关于【C#】Windows服务(Service)安装及启停的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Linux系列:开发环境搭建:ubuntu图形界面安装samba服务器、SSH使用、mount -t cifs 挂载windows共享目录方法与问题解决

    samba一种在局域网上共享文件和打印机的一种通信协议,它为局域网内的不同计算机之间提供文件及打印机等资源的共享服务。 通常linux开发环境要和windows平台进行文件交互,使用samba进行文件夹共享,这样会给开发带来很大的便利性,samba安装很简单,下面介绍一下在ubunt

    2024年02月21日
    浏览(53)
  • Windows系统如何将frp或其他应用配置为service服务并开机自启?

    本文使用WinSW实现service服务配置 WinSW(Windows Service Wrapper)是一个开源的 Windows 服务包装器,它可以将任何可执行文件(如 Java 应用程序、Python 脚本、Ruby 脚本等)转换为 Windows 服务,并为其提供了一些额外的功能,如重新启动、日志记录、配置文件管理等。 1. 下载WinSW安装

    2024年02月09日
    浏览(31)
  • windows共享文件夹(目录)(SMB服务)

    SMB服务,文件共享服务,俗称文件夹(目录)、打印机等共享 windos系统中,文件夹共享需要设置指定用户与密码,通过输入用户和密码进行连接,在设置共享时系统中有Everyone所有人设置,允许所有人直接访问,但是访问基本不成功,所以需要指定用户与密码去进行访问,提

    2024年02月02日
    浏览(46)
  • 重新安装mysql时,Windows Service Name已经被占用了怎么办

    重新安装mysql时,Windows Service Name已经被占用了怎么办,如图: 解决办法: 一,以管理员身份运行命令提示符(直接在搜索栏输入:cmd); 运行之后: 二, 输入命令:sc delete MySQL80(输入重复的Windows Service Name,我MySQL的Windows Service Name是MySQL80,你输入你的Windows Service Name)

    2024年02月12日
    浏览(25)
  • 实现一个Windows环境一键启停Oracle的bat脚本

      Oracle数据库有许多优点,其中一些最重要的包括: 可靠性和稳定性: Oracle数据库经过长期的发展和测试,被广泛认为是非常可靠和稳定的数据库管理系统。它在大型企业和关键业务环境中被广泛应用,能够处理高负载和大规模的数据。 高性能: Oracle数据库具有优化的查询

    2024年02月21日
    浏览(33)
  • Linux服务器同步Windows目录同步-rsync

    最近需要,Linux的服务器同步Windows的一个目录。查了下,大概有三种方法:网盘同步;rsync同步;挂载目录。 网盘同步,可以选择搭建一个Nextcloud 。但是问题在于,我需要的是,客户端和服务端的同步,而不是客户端和客户端的同步。服务端没有界面,安装客户端的网盘软件

    2024年02月11日
    浏览(51)
  • filebeat服务启停

    filebeat的服务启停 filebeat的启动通过二进制文件来实现,如: 实现后台启动可以通过nohup命令实现,如: 但filebeat的进程依赖会话,当启动filebeat的ssh断开后,filebeat会自动停止, 所以要使用特殊命令保证filebeat的运行,如下: 停止服务,杀死filebeat的进程 扩展--shell文件 she

    2024年02月11日
    浏览(29)
  • Windows10安装VS Code报错:安装程序不能创建目录

    在Windows10下安装VS Code编辑器时,将安装位置手动设置为D盘内,运行安装程序时报错: 提示安装程序不能创建目录。 使用管理员权限运行安装程序。方法一:右键——以管理员身份运行; 方法二:右键——属性——兼容性——以管理员身份运行此程序。 再次运行安装程序,

    2024年02月11日
    浏览(33)
  • 如何将Docker(Windows桌面版)自定义安装目录

    从官网下载Docker桌面版安装包后,点击exe文件,自动就安装到了C盘,无法指定其他目录。同时,Docker占用空间不小,放到系统盘不合适。 Docker桌面版的默认安装目录是C:Program FilesDocker,将这个目录通过软链接指向其他目录,Docker的安装文件便会迁移到自定义目录,达到不占

    2024年02月08日
    浏览(30)
  • Oracle21C:Windows版本的安装、卸载、环境变量配置、避坑指南|ORA-12514|为什么安装目录没有bin目录

    安装Oracle21C(点击下载),因不得其法,各种报错,导致不能正常使用Oracle。  提示:版本是Oracle21C, 其他版本可能存在差异, 目前官网已更新到Oracle23C (进官网后,向下滚动,可下载其他版本)。  1)Oracle下载地址:官网下载页面 2)navecat下载地址:navecate 3)sqlplus下载地

    2024年01月25日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包