代码改变世界

组件服务:8000401a 因为配置标识不正确,系统无法开始服务器进程。请检查用户名和密码

2024-07-19 14:18  CN-Phoenix  阅读(66)  评论(0编辑  收藏  举报

 

报错日志:

StartCAD Exception: Retrieving the COM class factory for component with CLSID {DED89DB0-45B6-11CE-B307-0800363A1E02} failed due to the following error: 8000401a 因为配置标识不正确,系统无法开始服务器进程。请检查用户名和密码。 (0x8000401A).
【记录时间】:2024-07-10 01:00:17,053 线程ID:[5] 日志级别:INFO 描述:StartCAD Exception: Retrieving the COM class factory for component with CLSID {DED89DB0-45B6-11CE-B307-0800363A1E02} failed due to the following error: 8000401a 因为配置标识不正确,系统无法开始服务器进程。请检查用户名和密码。 (0x8000401A).
【记录时间】:2024-07-10 01:00:17,055 线程ID:[5] 日志级别:INFO 描述:StartCAD Exception: Retrieving the COM class factory for component with CLSID {DED89DB0-45B6-11CE-B307-0800363A1E02} failed due to the following error: 8000401a 因为配置标识不正确,系统无法开始服务器进程。请检查用户名和密码。 (0x8000401A).

 

场景分析:

window服务进程会启动一个外部组件进程,得到com实例,然后调用该实例进行业务操作。

出错分析:

偶然出现,正常运行一段时间后出现,内部启动组件(Word|CAD)的时候用的是反射方式,代码环境.net6

可能原因:

1 com程序版本不匹配

2 组件服务标识和安全性设置用户未给到足够权限

3 windows服务的登录权限不够

部分参考方案:

1 Web程序方案 

2 PC程序方案

3 修改启动方式(抛弃反射启动,替换成Process.Start,然后获取Com组件)

针对不稳定出现的时候注意两个配置点

组件服务一定是启动用户,windows服务登录,必须有管理员权限

微软的后台服务问题总是充满玄学的味道

 如果服务进程和启动XXX.exe的用户权限不一样的话,获取Com组件容易失败

 比如服务进程是System而XXX.exe是Administrator

 1  ProcessStartInfo startInfo = new ProcessStartInfo();
 2  startInfo.FileName = @"XXX.exe";
 3  startInfo.UseShellExecute = true;
 4  startInfo.Verb = "runas"; // 请求管理员权限  
 5  startInfo.WindowStyle = ProcessWindowStyle.Hidden;
 6  var proce = Process.Start(startInfo); 8  if (proce == null)
 9      throw new Exception("Process.Start Fail");
10  
11  object? pvobj = null;
12  int tryCnt = 10;
13  while (pvobj == null && tryCnt-- > 0)
14  {
15      //等待进程完全启动
16      Thread.Sleep(1000);
17      int hres = GetActiveObject(ref gd, 0, out pvobj);
18      //framework 下 var application = (SolidEdge.Framework.Interop.Application)Marshal.GetActiveObject("SolidEdge.Application");                    
19      //引入vanara.pinvoke.ole后,可用 var hres = Vanara.PInvoke.OleAut32.GetActiveObject(gd, IntPtr.Zero, out pvobj);
20      Info($"GetActiveObject {pvobj != null} ,code {hres}");
21  }
22  var app = pvobj as SolidEdge.Framework.Interop.Application;                
23  if (app==null||app.ProcessID != proce.Id)
24  {
25      Info("Process.Start XXX not used,kill");
26      proce.Kill();
27  }