C#编程控制Com+服务

原创 2006年06月23日 15:59:00
C#编程控制Com+服务
 
创建日期:2006-6-23
适用于:.NET Framework,C#
作者:Dogvane
 
       因为在设计本地升级程序的时候,需要升级一个Com+服务的DLL,因此需要复制DLL之前需要停止Com+的服务,在阅了MSDN帮助后,找到一个Com+ 1.0 Admin Type Library的Com对象,所有的Com+操作都可以通过这个Com对象进行。
 
实现方法:
 
1.导出Com对象
 
2.创建一个用户控制com应用程序的对象
 
COMAdmin.COMAdminCatalogClass com = new COMAdmin.COMAdminCatalogClass();
COMAdmin.COMAdminCatalogCollection list = (COMAdmin.COMAdminCatalogCollection)com.GetCollection("Applications");
 
这里通过GetCollectoin来取得com应用程序的列表。
这个时候list的列表长度为1,里面并没有任何东西。当初以为是关键字写错了,试了N种其它方法都没有让列表里有值,该死的MSDN对于这个方法偏偏没有任何示例代码可用。最后在查阅网络上N种控制Com+的代码后终于知道,得到的列表需要调用Populate方法才能获得应用程序^_^!
 
3.禁用Com+应用程序
     list.Populate();   //   取得应用程序
     System.Collections.IEnumerator i = list.GetEnumerator();
     while(i.MoveNext())
     {
         COMAdmin.ICatalogObject app = (COMAdmin.ICatalogObject)i.Current;
         if (app.get_Value("Name").ToString() == _Name)
         {
              /// 禁用 com+ 服务
              app.set_Value("IsEnabled", false);
              list.SaveChanges();    //   保存本次操作,Com+服务不会停止
         }
     }
 
       取得所有的Com+应用程序后就是一个遍历的过程,从里面取得自己希望停止的Com+程序(用get_Value(“Name”)方法)。然后将IsEnable产生设置为false,如果是要启用Com+
 
4.虽然禁用了Com+应用程序,但是DLL有些时候还是不能服务,系统提示DLL文件还是被占用,原因查明后是向前Com+应用程序一直在使用,服务虽然被禁用,但是DLL程序还在运行。最后通过ShutdownApplication方式结束应用程序(相当于把进程杀掉)
com.ShutdownApplication(_Name);
 
 
5.如果只是打算更新某个应用程序里的一个组件(Components),则不一定要禁用整个程序,只需要禁用该组件就可以了。禁用的方法和禁用Com+应用程序的方法一样,所不同的是,我们在取得组件列表的时候,需要调用GetCollectionByQuery2这个方法,毕竟所有的组件都是存在于Com+应用程序下面的。
 
object key = app.Key; //   指定的Com+ 应用程序
     COMAdmin.COMAdminCatalogCollection Components = (COMAdmin.COMAdminCatalogCollection)com.GetCollectionByQuery2("Components", ref key);
     Components.Populate(); //   和Com+列表一样,新创建的列表里是没有任何东西的
 
 
6.其它的操作方法都类似,通过GetCollectionByQuery的方法取得Com+服务里的各种对象,然后通过这些对象的get_Value和set_Value进行各种Com+属性的设置,修改完成后再通过SaveChages()更新设置即可
 
 
 注意:
因为xp以后的操作系统,com+使用的接口是GetCollectionByQuery2,而在win2k下面使用的接口是GetCollectionByQuery。虽然在代码里面可以将针对接口的操作改为GetCollectionByQuery,但是,XP下编译的程序无法在win2K下运行,原因编译时导出的DLL会GetCollectionByQuery2的接口也倒出来,在系统win2K系统下创建对象接口时,找不到该函数,所以会出错。
正确的做法是,工程在发布时,需要到win2K系统下编译。
win9x,win nt 系统没有测试过不清除是否存在这样的问题。
附录:Com+ Service控制类代码
     ///<summary>
     /// Com+ Service的控制类
     ///</summary>
     internal class ComPlusService : IServiceControl
     {
         private int _TimeOut = 10;
 
         public int TimeOut
         {
              get
              {
                   return _TimeOut;
              }
              set
              {
                   if (value > 0)
                       _TimeOut = value;
                   else
                       _TimeOut = 10;
              }
         }
 
         string _Name = string.Empty;
         COMAdmin.COMAdminCatalogClass com = new COMAdmin.COMAdminCatalogClass();
 
         public ComPlusService(string name)
         {
              Name = name;
         }
         #region IServiceControl Members
 
         public string Name
         {
              get
              {
                   return _Name;
              }
              set
              {
                   _Name = value;
              }
         }
 
         public void Stop()
         {
              try
              {
                   LcftLog.Logging.Info("Stop Com+ Service: " + _Name);
                   COMAdmin.COMAdminCatalogCollection list = (COMAdmin.COMAdminCatalogCollection)com.GetCollection("Applications");
                   list.Populate();
 
                   System.Collections.IEnumerator i = list.GetEnumerator();
 
                   /// 停止 com+ 服务程序(从内存中卸载)
                   com.ShutdownApplication(_Name);
                   while(i.MoveNext())
                   {
                       COMAdmin.ICatalogObject app = (COMAdmin.ICatalogObject)i.Current;
                       if (app.get_Value("Name").ToString() == _Name)
                       {
                            /// 禁用 com+ 服务
                            app.set_Value("IsEnabled", false);
                            list.SaveChanges();
 
                            /// 下面的操作主要是取得 com+ 服务里的组件信息(DLL文件路径)
                            /// 然后判断这些组件是否已经停止(DLL从Com+应用程序里卸载,不存在写保护)
                            object key = app.Key;
                            COMAdmin.COMAdminCatalogCollection Components = (COMAdmin.COMAdminCatalogCollection)com.GetCollectionByQuery2("Components", ref key);
                            Components.Populate();
 
                            System.Collections.IEnumerator i2 = Components.GetEnumerator();
                            while (i2.MoveNext())
                            {
                                 COMAdmin.ICatalogObject obj2 = (COMAdmin.ICatalogObject)i2.Current;
                                 string dll = obj2.get_Value("DLL").ToString();
                                 int wait = TimeOut;
                                 LcftLog.Logging.Debug(dll);
                                 while(!CanWriteFile(dll))
                                 {
                                     if (wait -- < 0)
                                          break;
                                     System.Threading.Thread.Sleep(500);
                                 }
                            }
                       }
                   }
              }
              catch (Exception ex)
              {
                   LcftLog.Logging.Error("{0} Stop fail".Replace("{0}", _Name));
                   throw ex;
              }
         }
 
         private bool CanWriteFile(string fileName)
         {
              System.IO.FileStream stream = null;
              bool error = false;
              try
              {
                   stream = System.IO.File.Open(fileName, System.IO.FileMode.Open, System.IO.FileAccess.ReadWrite);
              }
              catch
              {
                   error = true;
              }
 
              if (stream != null)
                   stream.Close();
 
              return !error;
         }
 
         public void Start()
         {
              try
              {
                   LcftLog.Logging.Info("Start Com+ Service: " + _Name);
                   COMAdmin.COMAdminCatalogCollection list = (COMAdmin.COMAdminCatalogCollection)com.GetCollection("Applications");
                   list.Populate();
 
                   System.Collections.IEnumerator i = list.GetEnumerator();
                   while(i.MoveNext())
                   {
                       COMAdmin.ICatalogObject app = (COMAdmin.ICatalogObject)i.Current;
                       if (app.get_Value("Name").ToString() == _Name)
                       {
                            app.set_Value("IsEnabled", true);
                            list.SaveChanges();
                       }
                   }
                   com.StartApplication(_Name);
              }
              catch (Exception ex)
              {
                   LcftLog.Logging.Error("{0} Start fail".Replace("{0}", _Name));
                   throw ex;              
              }
         }
 
         #endregion
 
     }
 
 
 
版权声明:本文为博主原创文章,未经博主允许不得转载。

C#编写Window服务

用Visual C#创建Windows服务程序 一.Windows服务介绍:   Windows服务以前被称作NT服务,是一些运行在Windows NT、Windows 2000和Windo...

C#调用google搜索服务的源码示例

  • 2008年09月17日 11:30
  • 132KB
  • 下载

是什么让C#成为最值得学习的编程语言

是什么让C#成为最值得学习的编程语言,阅读完本文,你就知道。

[程序猿初养成]Coursera-C程序设计进阶-第二周作业-编程题#2

编程题#2:四大湖 注意: 总时间限制: 1000ms 内存限制: 65536kB 描述 我国有4大淡水湖。 A说:洞庭湖最大,洪泽湖最小,鄱阳湖第三。 B说:洪泽湖最大...

[程序猿初养成]Coursera-C程序设计进阶-第二周作业-编程题#4

编程题#4:Tomorrow never knows? 来源: POJ (Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。) 注意: 总时间限制: ...

C#编程遇到的问题:System.NullReferenceException及其反思

最近在写一个Kinect的体感游戏,遇到了System.NullReferenceException这个问题。虽然只用了半个小时就解决了,但是自己有很多反思。              Skelet...

C#中的MDI编程实例讲解

多文档界面就是所谓的MDI,他是从Windows 2.0下的Microsoft Excel电子表格程序开始引入的,这是因为Excel电子表格用户有时需要同时操作多份表格,MDI正好为这种操作多表格提供...
  • cca313
  • cca313
  • 2012年06月06日 11:55
  • 597

[程序猿初养成]Coursera-C程序设计进阶-第二周作业-编程题#6

编程题#6:流感传染 注意: 总时间限制: 1000ms 内存限制: 65536kB 描述 有一批易感人群住在网格状的宿舍区内,宿舍区为n*n的矩阵,每个格点为一个房间,房间...

[程序猿初养成]Coursera-C程序设计进阶-第二周作业-编程题#5

编程题#5:细菌实验分组 注意: 总时间限制: 1000ms 内存限制: 65536kB 描述 有一种细菌分为A、B两个亚种,它们的外在特征几乎完全相同,仅仅在繁殖能力上有显...

C#人工智能(AI)编程:对神经网络面向一个基本的对象(OOP)框架

C#人工智能(AI)编程:对神经网络面向一个基本的对象(OOP)框架         (A Neural Network is an Artificial Intelligence (AI) me...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C#编程控制Com+服务
举报原因:
原因补充:

(最多只允许输入30个字)