Flier's Sky

天空,蓝色的天空,眼睛看不到的东西,眼睛看得到的东西
posts - 115, comments - 316, trackbacks - 42, articles - 0

2008年1月23日

更新:程序员的思维模式都差不多,Kerem KusmezerJohn Robbin 发布了一个类似的工具.NET Mass Downloader。既然有的用我就不重新发明轮子了,下面那个项目停止维护,有需求的朋友直接用那个工具好了,具体使用说明可以参考


Download All the .NET Reference Source Code at Once with Net Mass Downloader

更新:在 sourceforge 上申请了一个项目,有兴趣的朋友可以上去下载代码,或者提交bug和改进建议。不过我估计也就年后才有时间继续处理,暂且挖个坑反正这里吧,呵呵

    从去年MS就开始喊着要开放.NET源代码,如今终于在一个含糊不清的授权协议下,通过Source Server的方式放了出来。虽然是如愿开源,但目前只提供几个核心模块,而且还限制必须在VS2008里面在线访问。
    其实既然决定开放,何必搞那么多限制出来,让偶等用着不爽还得自己动手丰衣足食,写个程序直接模拟VS2008获取源码的行为,一次性全部拖回来备用。
    空口无凭,上载一个
System.Xml 的源码包,和一个理论上能跑的程序原型,有兴趣的朋友可以试试。回头有时间了把相关代码整理一下再放出来,下面先大概说一下思路。

    首先,VS2008虽然要
打个补丁才能用源码调试,但这并不是下载源码的必要条件。MS发布源码所依赖的Source Server的机制,很早就通过 WinDbg 的发布包引入了。有兴趣的朋友可以使用 WinDbg 工具自己架设 Source Server,具体步骤请参考 %Debugging Tools for Windows%\sdk\srcsrv\ 目录下文档和脚本。
    而这个 Source Server 说白就是从 .pdb 调试符号文件里面,获取被绑定的已索引文件列表,然后根据系统_NT_SOURCE_PATH环境变量指定的服务器,拼接出一个 URL 然后通过http下载。具体这块的配置,可以参考
    Configuring Visual Studio to Debug .NET Framework Source Code
    讨厌的是MS在dbghelp.dll里面做了一些手脚,直接通过url去下载调试符号和源码是不被允许的。刚好scz前面研究过symbol server的行为,基本确定ms服务端是根据user agent来进行判断的。也就是说在发起请求时,把当前http的user agent改成ms认可的方式,就能够模拟dbghelp.dll通过srcsrv.dll完成的工作,具体代码类似

public const string DefaultUserAgent = "Microsoft-Symbol-Server/9.9.9.9 (C; V; ;)";

    
public void Restart(Uri uri)
    
{
      _request 
= (HttpWebRequest)WebRequest.Create(uri);
      _request.UserAgent 
= DefaultUserAgent;    

      IAsyncResult result 
= (IAsyncResult)_request.BeginGetResponse(
        
new AsyncCallback(ResponseCallback), this);
      ThreadPool.RegisterWaitForSingleObject(result.AsyncWaitHandle,
        
new WaitOrTimerCallback(TimeoutCallback), this, _timeout, true);      
    }
    另外一个罗嗦的事情,是每个链接建立后,MS服务器会先返回一个罗嗦的license声明,srcsrv.dll会弹出一个对话框让你Accept才能继续下载。
    例如你通过命令行去下载一个文件
wget  --user-agent=Microsoft-Symbol-Server/9.9.9.9
    Http:
//ReferenceSource.microsoft.com/source/.net/8.0/DEVDIV/
    depot
/DevDiv/releases/whidbey/REDBITS/ndp/fx/src/Misc/
   
InvariantComparer.cs/1/InvariantComparer.cs
    会直接返回一对垃圾信息,类似
SYMSRVCOMMAND:
YESNODIALOG:
IDYES:Accept:Accept=0cf80f849aa7449e9d064ade971bd887
IDNO:Decline:Decline=0cf80f849aa7449e9d064ade971bd887
TITLE:End User License Agreement
BUTTONDESCRIPTION:Please read carefully and understand the license agreement above. 
If you want to accept the license agreement, please click the “Accept” button.
TEXT:This license applies to the .NET Framework components that Microsoft makes available to you
in source code form.  To print these terms, select the contents of this area and copy then paste
into an application that can print text.

MICROSOFT .NET FRAMEWORK REFERENCE LICENSE
.NET FRAMEWORK REFERENCE SOURCE CODE


This license governs use of the accompanying software. If you use the software, you accept this license.
If you do not accept the license, do not use the software.
1. Definitions
The terms "reproduce," "reproduction" and "distribution" have the same meaning here as under U.S. copyright law.
 


    解决方法很简单,直接用正则表达式找到里面一个随机生成的id,然后程序自动Accept即可,代码类似
    private static Regex _accept = new Regex(@"IDYES:Accept:Accept=(\w*)");

          
if (task._auth)
          
{
          }

          
else
          
{
            
string license = Encoding.Unicode.GetString(task._buf, 0, read);

            Match m 
= _accept.Match(license);

            
if (m.Success)
            
{

              task._auth 
= true;

              
string id = m.Groups[1].Value;

              _logger.DebugFormat(
"Accept license id {0} for {1}", id, task._request.Address);

              Uri uri 
= new Uri(string.Format("{0}?Accept={1}", task._uri.ToString(), id));

              task.Restart(uri);
            }

          }

其他的基本上没什么需要说明的,就是很基本的http请求调用啥的,呵呵

至于从.pdb里面获取文件名列表,需要调用dbghelp.dll里面的一组api
SymInitializeW/SymCleanup用来初始化和析构symbol engine
SymLoadModuleExW/SymUnloadModule64用来加载要便利源代码的模块
SymEnumSourceFilesW用来遍历一个有.pdb符号且包含已索引源码的列表
SymGetSourceFileW和SymGetSourceFileTokenW/SymGetSourceFileFromToken两套API,都可以用来获得特定源码的下载URL,然后把这个地址用上面两个方法处理一下即可。

注意:目前的实现只是个原型,需要手动下载和配置.pdb文件,并且直接发起大量的异步http请求,对网速慢的朋友,可能需要用 -i 参数增加超时时间(确实15分钟)


   
   
 

posted @ 2008-01-23 02:50 Flier Lu 阅读(6610) 评论(21) 编辑

2006年2月19日

摘要: 原文:http://www.blogcn.com/User8/flier_lu/blog/29042138.html1.3 局部重绘模式的服务器端响应在第一小节中,我们曾提到 ScriptManager 在重载的 Web.UI.Control.OnInit 事件中,会根据页面请求中 delta = true 是否存在,判断当前页面是否处于局部重绘模式中,并接管 LoadComplete 时间来处理...阅读全文

posted @ 2006-02-19 23:40 Flier Lu 阅读(5457) 评论(7) 编辑

2006年2月18日

摘要: 原文:http://www.blogcn.com/User8/flier_lu/blog/28981917.html1.2UpdatePanel与局部重绘模式(PartialRenderingMode)在上一节介绍Altas整体结构时曾经提到,可以在启用局部重绘模式的情况下,通过通过<altas:UpdatePanel.../>标签定义需要异步更新的范围。我们知道,传统的HTTP协议应...阅读全文

posted @ 2006-02-18 00:49 Flier Lu 阅读(4794) 评论(4) 编辑

2006年2月17日

摘要: 原文:http://www.blogcn.com/User8/flier_lu/blog/28949768.html[0]概述上周MS发布了面向ASP.NET的AJAX框架——Atlas最新CTP2006.1预览版,ScottGu在其blog上做了较为详细的介绍。NewAtlasBuildAvailableforDownloadwithASP.NET2.0更详细的更新说明,可以参考nikhilk的...阅读全文

posted @ 2006-02-17 00:16 Flier Lu 阅读(5892) 评论(11) 编辑

2005年12月30日

posted @ 2005-12-30 01:36 Flier Lu 阅读(3835) 评论(3) 编辑

2005年12月27日

posted @ 2005-12-27 00:28 Flier Lu 阅读(13169) 评论(11) 编辑

2005年11月20日

摘要: 前两个月大概翻过《应用框架的设计与实现——.NET平台》一书,也曾在MSN space上发过一个简短的书评。因为刚刚看到某人的一篇书评,感觉赞誉太过。于是把以前的书评翻出来转贴一下,如有观点过于偏激权且博大家一笑。http://spaces.msn.com/members/flierlu/Blog/cns!1pQ1oe7hJhEc4MgjNgGwRvvA!153.entry9月18日《应用框架的设...阅读全文

posted @ 2005-11-20 16:11 Flier Lu 阅读(2742) 评论(3) 编辑

2005年8月28日

posted @ 2005-08-28 22:15 Flier Lu 阅读(4192) 评论(10) 编辑

2005年8月24日

摘要: http://spaces.msn.com/members/flierlu/Blog/cns!1pQ1oe7hJhEc4MgjNgGwRvvA!138.entry 如果让我推荐学习 Java 语言的书单,除了面向初学者的 Thinking in Java 和面向进阶者的 Inside JVM 之外,现在又可以增加一本面向执着者的 Java Rules。 虽然相对枯燥的第 1 章曾让我一度放下此书改...阅读全文

posted @ 2005-08-24 22:55 Flier Lu 阅读(1360) 评论(1) 编辑

2005年8月21日

摘要: http://spaces.msn.com/members/flierlu/Blog/cns!1pQ1oe7hJhEc4MgjNgGwRvvA!131.entry 《Enterprise Services with the .NET Framework》一书实际上漏掉了一个非常重要的议题,那就是对企业级服务自身的可管理性支持。JSE 5 中一个非常重要的改进,就是直接集成了对 JMX 标准的支持,...阅读全文

posted @ 2005-08-21 11:29 Flier Lu 阅读(1330) 评论(3) 编辑