【第21期】观点:人工智能到底用 GPU?还是用 FPGA?

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#\ASP.NET面试问题

1.面向对象的思想主要包括什么?2.什么是ASP.net中的用户控件3.什么叫应用程序域?什么是受管制的代码?什么是强类型系统?什么是装箱和拆箱?什么是重载?CTS、CLS和CLR分别作何解释?4.列...

服务设计原理:服务模式和反模式--MSDN

服务设计原理:服务模式和反模式 John Evdemon 服 务设计系列的法则已经发展到最佳通信实践和取样相关编码的程度。作为一系列相关论文的开始,本文提供了设计和实现网络服务的基本原理,并且对面向服务的体 系结构(SOA)的相关概念做了一个简要的回顾,以及有关于几种模式和反模式的详细讨论,当构建网络服务时,开发者可以利用它们。它可应用于能进行网络服 务开发和配置的任何编程语言或平台。 <img src="http://img.microsoft.com/library

欢迎关注CSDN程序人生公众号

关注程序员生活,汇聚开发轶事。

linux 命令总结

1、 永久更改ip ifconfig eth0 新ip 然后编辑/etc/sysconfig/network-scripts/ifcfg-eth0,修改ip 2、从Linux上远程显示Windows桌面 安装rdesktop包 3、 手动添加默认网关 以root用户,执行: route add default gw 网关的IP 想更改网关 vi

15个适合初学者学习C#编程语言的在线资源丨附地址

C#是一种通用编程语言,广泛应用于开发企业应用程序。C#是由Microsoft开发的,是.NET框架的主要语言。C#主要用于创建控制台应用程序、图形用户界面(GUI)应用程序和Web应用程序等。这些应...

C/C++面试题大汇总

转自:<a href="http://pengfei.zhmy.com/archives/2006/41955.html"
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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