【项目总结】安装服务时的总结

总结一

1、服务安装软件编写时漏了调用一个函数,UpdateListView(),导致启动服务,一直不刷新状态,调试时一直抓着sc.start()不放,一直以为是这个问题。
报错:

{System.InvalidOperationException: 无法打开计算机“.”上的 OnlineService 服务。 
---> System.ComponentModel.Win32Exception: 拒绝访问。
--- 内部异常堆栈跟踪的结尾 ---
在 System.ServiceProcess.ServiceController.GetServiceHandle(Int32 desiredAccess)
在 System.ServiceProcess.ServiceController.Start(String[] args)
在 ServerManager.ServiceAPI.RunService(String NameService) 位置 g:\大通\大通服务器\ServerManager\ServiceAPI.cs:行号 88}

解决:使用管理员调试就好了。使用管理员打开VS,调试代码,运行正常。

总结二

将服务应用程序改为服务时
步骤1:新建两个组件Windows服务、安装程序类
这里写图片描述
分别命名为OnlineService和OnlineServiceInstaller.cs
引用添加System.Configuration.Install和System.ServiceProcess

OnlineService继承ServiceBase,重写OnStart( )和重写OnStop( );

        protected override void OnStart(string[] args)
        {
            m_server = new AsyncServer();
            m_logger = new FileLogger();
            m_server.SetLogger(m_logger);
            m_logger.InitLogAPI(GlobalData.GetAppPath(), "OnlineServer.log");

            ServerConfig config = new ServerConfig();
            if (!config.ReadFile(GlobalData.GetAppPath() + "\\ServerConfig.xml"))
            {
                m_logger.Log("无法读取配置文件!");
                return;
            }
            if (config.DBServerInfo == null)
            {
                m_logger.Log("无法从配置文件中读取数据库配置!");
                return;
            }
            if (config.TCPServerInfo == null)
            {
                m_logger.Log("无法从配置文件中读取服务器配置!");
                return;
            }

            DBGlobal.SetDBServer(config.DBServerInfo.Server, config.DBServerInfo.DBName,
                                 config.DBServerInfo.User, config.DBServerInfo.Password);

            m_server.Start(config.TCPServerInfo.IP, config.TCPServerInfo.Port);
        }

        protected override void OnStop()
        {
            if (m_server.Runing)
            {
                m_server.Stop();
            }
        }

OnlineService.Designer.cs不作修改
OnlineServiceInstaller.cs组件上添加两个控件
第一个是serviceInstaller1、第二个是serviceProcessInstaller1
这里写图片描述
这里写图片描述
OnlineServiceInstaller.Designer.cs中改写

this.serviceInstaller1.Description = "MDIA Online Server";
this.serviceInstaller1.DisplayName = "OnlineService";
this.serviceInstaller1.ServiceName = "OnlineService";

OnlineServiceInstaller.cs

    [RunInstaller(true)]
    public partial class OnlineServiceInstaller : Installer
    {
        public OnlineServiceInstaller()
        {
            InitializeComponent();
        }
    }
    //public不要忘了,会出现卸载不成功或者安装不成功

onlineService.Design.cs中服务名称

namespace CmmServer
{
     partial class CmmService
    {
        /// <summary> 
        /// 设计器支持所需的方法 - 不要
        /// 使用代码编辑器修改此方法的内容。
        /// </summary>
        private void InitializeComponent()
        {
            this.ServiceName = "OnlineService";
        }
    }
}

**OnlineServiceInstaller **类要是是公共的
OnlineService类要是公共的

    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        static void Main()
        {
            ServiceBase[] ServicesToRun;

            // 同一进程中可以运行多个用户服务。若要将
            // 另一个服务添加到此进程中,请更改下行以
            // 创建另一个服务对象。例如,
            //
            //   ServicesToRun = new ServiceBase[] {new Service1(), new MySecondUserService()};
            //
            ServicesToRun = new ServiceBase[] { new OnlineService() };
            ServiceBase.Run(ServicesToRun);
        }
    }

总结三

服务获取AppPath时的不能再使用Windows.Form.
System.Windows.Forms.Application.StartupPath

        static public string GetWindowsServiceInstallPath(string ServiceName)
        {
            string key = @"SYSTEM\CurrentControlSet\Services\" + ServiceName;
            string path = Registry.LocalMachine.OpenSubKey(key).GetValue("ImagePath").ToString();
            //替换掉双引号   
            path = path.Replace("\"", string.Empty);

            FileInfo fi = new FileInfo(path);
            return fi.Directory.ToString();
        }

        static public string GetAppPath()
        {
            string strPath = GetWindowsServiceInstallPath("OnlineService");
            return strPath;
        }

额外补充

生成程序如果是AnyCpu的话,在32位系统上就是32位的程序,在64位上就是64位程序,如果当SQLite是32位的时候,就会出现SQLite库的相关错误。
像这样的错误:

所生成项目的处理器架构“MSIL”与引用“System.Data.SQLite, Version=1.0.62.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=x86”的处理器架构“x86”不匹配

总结四

Access数据库连接报错,未在本机注册Micsoft.Access 驱动
解决办法:安装一个驱动Access驱动安装包(64位的)

ODBC驱动方式:
Driver={Microsoft Access Driver (*.mdb)};Dbq=c:somepathdbname.mdb;Uid=Admin;Pwd=pass;
微软的odbc驱动存在一些不稳定的bug,有可能导致此类错误。应该将其修改为oledb的access驱动方式。微软本身已经放弃了对odbc数据源连接方式的支持,并建议用户使用oledb方式

OLEDB驱动方式:
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:somepathdbname.mdb;User Id=admin;Password=pass;
32位系统
Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:somepathdbname.mdb
64位系统

Access的SQL语句和SQLServer不一样
accesss要用的是"#" +time.Text+ “#”,SQL是可以直接用单引号。
Access中* 为匹配多个字符串,但是在C#编写Access的模糊查询中必须用 %才能查询匹配%,但是,在Access中的SQL查询中只能使用 *匹配查询!

Access后缀名
.mdb Access 2007以前的版本
.accdb Access 2007以后的版本

SQL Server后缀名
备份文件是 .bak
分离出来的数数据,mdf是数据库文件,ldf是日志文件。

总结五

安装服务时,在日志里面报这个错误:
System.BadImageFormatException
解决方法:
一般有两种情况:程序目标平台不一致 & 引用dll文件的系统平台不一致。
1、程序目标平台不一致:
项目>属性>生成:x86 和x64平台
在这里插入图片描述
注:此种问题一般是编译错误

2、引用dll文件的系统平台不一致
程序中引用外部dll文件的目标平台的版本x86和x64不一致。
注:此种问题是运行时错误

总结6 服务自启动的方法

1、开始菜单启动
先找到“开始”菜单的“启动”关联的目录;
然后创建快捷方式到这个目录;
2、将启动的项目名称、文件位置添加到启动项即可

//添加到  当前登陆用户的   注册表启动项
RegistryKey RKey = Registry.CurrentUser.CreateSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run");
//添加到  所有用户的  注册表启动项
RegistryKey Rkey = Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run");
RKey.SetValue("AppName",@"C:\\AppName.exe");

AppName C:\AppName.exe

or

AppName “C:\AppName.exe”
如果你的路径中,带有空格,需要使用双引号引起来,这样能保证在启动的时候不会出现问题,如下:

// @ 符号中的双引号需要用两次来转义
RKey.SetValue("AppName", @"""C:\AppName.exe""");

3、Windows计划任务方式启动
Windows 的计划任务方式添加启动也是可以实现自启动的方式,但是个人感觉这种方式有点奇葩……
注意:任务计划需要添加引用,在 Com 中搜索 TaskScheduler,添加即可,并且要在“嵌入互操作类型”设置为false,使程序编译时,能从互操作程序集中获取 COM 类型的类型信息。

参考 https://blog.csdn.net/arrowzz/article/details/69808761

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值