Kevin Li

突破.net极限
posts - 32, comments - 61, trackbacks - 24, articles - 0

2007年6月12日

当BizTalk使用多服务器部署方案时,如果要更新BizTalk Application引用到的程序集,就必须将程序集同时更新到多台服务器的GAC中。如果每次更新以后,都需要手工在多台服务器更新,实在太麻烦。为了偷懒,就想到用WMI在远程服务器上创建进程来更新GAC中的程序集:)

用WMI在远程服务器上创建进程的命令如下:
WMIC /node:server01 /user:mydomain\myusername /password:pass@word1 process call create "C:\gacutil /u myBizAssembly"
WMIC /node:server01 /user:mydomain\myusername /password:pass@word1 process call create "C:\gacutil /i C:\Deploy\myBizAssembly.dll"

接下来要做的就是将程序集,从Build机器copy到deploy服务器上,然后调用gacutil卸载程序集、重新安装程序集和重启BizTalk Host Instances了。把所有的命令都写到一个批处理文件就可以:

@Echo Copy files
Copy C:\Build\myBizAssembly.dll \\Server01\Deploy\myBizAssembly.dll 
Copy C:\Build\myBizAssembly.dll \\Server02\Deploy\myBizAssembly.dll
Copy C:\Build\myBizAssembly.dll \\Server03\Deploy\myBizAssembly.dll

@Echo Install assemblies to GAC
WMIC 
/node:server01 /user:mydomain\myusername /password:pass@word1 process call create "C:\gacutil /u myBizAssembly"
WMIC 
/node:server01 /user:mydomain\myusername /password:pass@word1 process call create "C:\gacutil /i C:\Deploy\myBizAssembly.dll"
WMIC 
/node:server02 /user:mydomain\myusername /password:pass@word1 process call create "C:\gacutil /u myBizAssembly"
WMIC 
/node:server02 /user:mydomain\myusername /password:pass@word1 process call create "C:\gacutil /i C:\Deploy\myBizAssembly.dll"
WMIC 
/node:server03 /user:mydomain\myusername /password:pass@word1 process call create "C:\gacutil /u myBizAssembly"
WMIC 
/node:server03 /user:mydomain\myusername /password:pass@word1 process call create "C:\gacutil /i C:\Deploy\myBizAssembly.dll"

@Echo Restart Host Instances
WMIC 
/node:server01 /user:mydomain\myusername /password:pass@word1 process call create "net stop BTSSvc$BizTalkReceiveHost"
WMIC 
/node:server01 /user:mydomain\myusername /password:pass@word1 process call create "net start BTSSvc$BizTalkReceiveHost"
WMIC 
/node:server02 /user:mydomain\myusername /password:pass@word1 process call create "net stop BTSSvc$BizTalkProcessHost"
WMIC 
/node:server02 /user:mydomain\myusername /password:pass@word1 process call create "net start BTSSvc$BizTalkProcessHost"
WMIC 
/node:server01 /user:mydomain\myusername /password:pass@word1 process call create "net stop BTSSvc$BizTalkSendHost"
WMIC 
/node:server01 /user:mydomain\myusername /password:pass@word1 process call create "net start BTSSvc$BizTalkSendHost"


不过这种方式,只适合不影响到BizTalk的Bindings的时候,比如新的程序集相对原来的程序集,多了一个ReceivePort,这种方式没办法更新BizTalk的Bindings。

这种方式,也适用于daily build後将程序集部署到测试服务器上,只需要加一段自定义任务就可以。

<Target Name="AfterCompile">
        
<Exec Command="&quot;c:\mywmideploy.bat&quot;"/>
</Target>



 

posted @ 2007-06-12 14:57 Kevin Li 阅读(211) | 评论 (0)编辑

2007年5月26日

在测试WCF 的WS-AT协议的时候发现,虽然wsHttpBinding只支持WS-AtomicTransaction,但是当我没有配置MSDTC支持WS-AT协议,或者没有启用WS-AT协议,事务还是能够正常的Commit和Rollback。刚开始不知道是什么原因,后来查了一下微软的相关文档,发现使用wsHttpBinding支持事务时,出于效率的考虑,WCF会首先使用Oletx事务,而不是完全的ws-at协议。只有在oletx协议不可用的情况,比如135端口没开、或者和java web service互操作的情况下,wcf才会完全使用ws-at协议。这固然是好,但是有时候我们并不希望这样(比如测试的时候),这时候我们可以修改注册表,禁止事务自动升级为oletx事务。具体是在注册表:HKLM\SOFTWARE\Microsoft\WSAT\3.0下增加一个名为“OleTxUpgradeEnabled”的DWord值,并且设置值为0(1为启用自动升级)

posted @ 2007-05-26 23:58 Kevin Li 阅读(1514) | 评论 (1)编辑

     摘要: 分析WCF WS-AT消息内容  阅读全文

posted @ 2007-05-26 23:39 Kevin Li 阅读(2206) | 评论 (1)编辑

     摘要: 配置MSDTC支持WS-AT协议,并使用WCF写使用WS-AT协议的分布式事务应用程序  阅读全文

posted @ 2007-05-26 23:08 Kevin Li 阅读(3109) | 评论 (3)编辑

2007年2月9日

前两天看到了Jeffrey Zhao的鸡肋烹制出的美味——真正可调试的ASP.NET AJAX  ,真是不错,把Ajax的代码整理成一个项目文件,现在可以调试了。

但是因为微软没有提供设计时的源代码,开发的时候还是没法设计时支持,感觉还是不爽,没法只好自己用Reflector + FileDisassembler反编译源代码了。反编译后对其中的2个匿名方法处理了一下,得到了下面的源代码(其中包括了Jeffery Zhao整理的System.Web.Extensions的源代码)。

另外,因为有些虚拟主机的trust Level没有设置为Full,所以直接把微软的两个dll上传上去会报无法加载指定的程序集,所以对老赵的代码稍微修改了一下,加了个[assembly: AllowPartiallyTrustedCallers()],这样就可以在不支持Full Trust Level的虚拟主机上用了。

ASP.NET Ajax源代码

编译以后就可以不再需要微软的那两个dll了。

感谢老赵的System.Web.Extensions的源代码。
 
[注]非常抱歉,刚才的代码匿名方法上有点问题,现在已经修正,请重新下载最新版本:)

posted @ 2007-02-09 10:21 Kevin Li 阅读(1977) | 评论 (9)编辑

2006年11月10日

     摘要: 在.net 1.1或者.net 2.0中要实现分布式事务,如果不涉及远程调用,如调用remoting或者web service的方法,应该说是一件非常简单的事情,只需要用COM+(1.1/ServiceDomain)或者TransactionScope(2.0),通过msdtc协调即可。

但是当事务方法中还需要调用remoting或者web service(不使用ws-at)时,由于remoting不支持事务传播机制,因此即便客户端调用remoting后发生错误回滚,remoting server上已经执行的操作(如数据库操作)也已经无法回滚。
  阅读全文

posted @ 2006-11-10 00:56 Kevin Li 阅读(2472) | 评论 (0)编辑

2005年12月10日

最近使用多线程同时调用一个Web Service,总是有很多调用报超时,代码类似于下面的代码(为了简化,我把调用Web Service改为使用HttpWebRequest访问一个网址,效果时一样的):

我循环调用100次,但是总是有几十次调用报超时,具体如下:

System.Net.WebException: 操作已超时。
   at System.Net.HttpWebRequest.GetResponse()
   at HttpRequestTest.HttpRequestTest.MakeWebRequest(Object obj) in g:\my documents\visual studio projects\httprequesttest\httprequesttest.cs:line 35

真的不知道为什么,难道Web Service就不能在多线程的环境下调用!

因为目前找不到原因,暂时放在首页,想向各位请教,明天就撤调,请手下留情,谢谢!


 1using System;
 2using System.Diagnostics;
 3using System.Net;
 4using System.Threading;
 5
 6namespace HttpRequestTest
 7{
 8    /// <summary>
 9    /// Class1 的摘要说明。
10    /// </summary>

11    class HttpRequestTest
12    {
13
14        //[STAThread]
15        static void Main(string[] args)
16        {
17            for(int i = 0; i < 100; i++ )
18            {
19                ThreadPool.QueueUserWorkItem(new WaitCallback(MakeWebRequest),"http://www.163.com");
20            }

21            Console.ReadLine();
22        }

23
24        private static void MakeWebRequest (object obj)
25        {
26            string url = obj as string;
27            HttpWebResponse res = null;
28            try
29            {
30                HttpWebRequest req = (HttpWebRequest)WebRequest.Create (url);
31                req.Timeout = 15000;
32
33                Console.WriteLine ("\nConnecting to " + url + " ");
34
35                res = (HttpWebResponse)req.GetResponse ();
36
37                Console.WriteLine("[" + AppDomain.GetCurrentThreadId() + "] ContentLength:" + res.ContentLength);
38                Console.WriteLine ("Connected.\n");
39
40
41            }

42            catch (Exception e)
43            {
44                Console.WriteLine ("Source : " + e.Source);
45                Console.WriteLine ("Message : " + e.Message);
46                Console.WriteLine(e.ToString());
47                Debug.WriteLine(e.ToString());
48                //Console.WriteLine("StackTrace :" + e.StackTrace);
49            }

50            finally
51            {
52                if (res != null)
53                {
54                    res.Close ();
55                }

56            }

57        }

58    }

59}

60


posted @ 2005-12-10 21:25 Kevin Li 阅读(4141) | 评论 (14)编辑

2005年5月30日

http://www.microsoft.com/china/msdn/library/langtool/vcsharp/csharpgenerics.mspx

介绍的挺全面的

posted @ 2005-05-30 22:26 Kevin Li 阅读(2553) | 评论 (5)编辑

2005年5月28日

在.net 1.1中我们无法对基础类型,如int、DateTime、enum类型等赋予null的值,但这在实际应用中往往会带来很多麻烦,比如有下面这个函数:

class OrderDAC{
    public ArrayList GetOrders(OrderStatus status){
    }
}
public enum OrderStatus{
    Initial,
    Canceled,
    Delivered
}
如果我们希望该函数GetOrders中当输入的为status == null 的时候获取所有OrderStatus的订单,而如果status不等于 null 时获取指定状态下的订单,在.net 1.1中根本无法实现,因为我们无法将 status 设为 null,因为它是基础类型。

又考虑另外一种情况,如:

OrderInfo order = new OrderInfo();
order.DeliveryDate = reader.IsDbNull("DeliveryDate") == true? null : (DateTime) reader["DeliveryDate"];

上面的代码实际上无法编译通过,因为DateTime不允许付空,取而代之的是:
if( reader.IsDbNull("DeliveryDate") == false){
    order.DeliveryDate = (DateTime) reader["DeliveryDate"];
}

当我们要判断 order.DeliveryDate 是否有赋值,也不能采用 if( order.DeliveryDate == null ),这时往往需要给类似的字段赋一个默认值,比如 DateTime.MinValue,但这处理起来也是挺麻烦的。


幸运的是,在.net 2.0中,提供了 Nullable的范型,通过它,我们可以为基础类型如int等赋予null的值,具体如下:

class OrderDAC{
    public List<OrderInfo> GetOrders(Nullable<OrderStatus> status){
    }
}
上面用到了两个范型,一个是List<OrderInfo>,一个是Nullable<OrderStatus>,有了这个,我们就可以调用
OrderDAC ord = new OrderDAC();
List<OrderInfo> orders = ord.GetOrders(null);

这样我们就可以为 OrderStatus status 赋予null的值,是不是方便了很多呢?

同样,我们也可以定义
class OrderInfo{
    public Nullable<DateTime> DeliveryDate;
}

这样,我们就可以为OrderInfo.DeliveryDate 赋予 null,并且可以判断 OrderInfo.DeliveryDate == null ,又方便了很多。

其实象这样的例子还有很多:)

.net 2.0 确实为我们提供了很多便利,期待正式版!!






posted @ 2005-05-28 22:38 Kevin Li 阅读(1522) | 评论 (4)编辑

2005年4月20日

分布式事务在Windows 2003的配置比较麻烦,原来我就碰到过怎么设置也启动不了的情况,近日在别人指导下弄好了,顺便写个配置步骤,希望对大家有用
1、 添加/删除程序中,选择添加Windows组件,选择应用程序服务器,选择启用分布式事务网络访问
2、 在DTC所涉及的所有服务器中,启用NETBIOS,确保所有服务器能相互ping通对方,具体为修改所有服务器中的C:\Windows\System32\Drivers\etc\hosts文件(具体可参考hosts文件的内部帮助)。[注意]必须修改所有的服务器中的hosts文件
3、 禁用SQL Server 的DTC RPC安全,具体为在HKEY_LOCAL_MACHINE\Software\Microsoft\MSDTC下新建一个DWord键,名称为TurnOffRpcSecurity,设置其值为1
4、 重启MSDTC
5、 关闭网络防火墙(或者开放相应的端口)
6、 参考:
http://www.support.microsoft.com/?kbid=555017&SD=tech
http://support.microsoft.com/default.aspx?scid=kb;zh-tw;306843
http://support.microsoft.com/kb/250367/

posted @ 2005-04-20 14:11 Kevin Li 阅读(2118) | 评论 (0)编辑