星期六, 十二月 29, 2007

Holiday Weekend Timewaster: Guest House [Timewasters]



 
 

Sent to you by Hudong via Google Reader:

 
 

via Kotaku by Maggie Greene on 12/29/07

guesthouse.jpg While browsing my feeds during the inevitable mid-holiday news slump, I was pointed to some fascinating little Japanese point-and-click (or 'point-and-kick ass,' as Leigh Alexander described them over at Sexy Videogameland) puzzlers, lumped under the heading of 'room escape games.' Guest House is the latest in the series, and I spent quite a while clicking my way through all the frustrating (but not too sadistic) puzzles. It's a good way to spend a few hours on a lazy weekend. Terminal House [via Sexy Videogameland]



 
 

Things you can do from here:

 
 

星期四, 十二月 27, 2007

星期三, 十二月 26, 2007

The Word & Web Vector Tool

The Word & Web Vector Tool is a flexible Java library for statistical language modeling and integration of Web and Webservice based data sources. It supports the creation of word vector representations of text documents in the vector space model that is the point of departure for many text processing applications (e.g. text classification or information retrieval). Furthermore, it offers convenient interactive methods to extract data from structured sources, such was HTML or XML files. Finally, it allows to integrate external data by using Webservice APIs in a mashup-like way (e.g. for geo-mapping).

星期一, 十二月 24, 2007

Updated the layout today, so I wont post those long MSDN articles from google reader any more, instead, I will share them and link them through the widget on the page. This will make the page look more dedicated to ir related articles.

星期五, 十二月 21, 2007

Actiontec M1000 Modem Support Page - Qwest CommunicationsTransparent Bridging (PDF)
Sony eSupport - LF-PK1 - Software Updates & Drivers

11/29/2007 SONY finally made this software free

星期四, 十二月 20, 2007

ICU 3.8: Main Page
For unicode collation

星期二, 十二月 18, 2007

SVM - Support Vector Machines
TIE - Trainable Information Extractor what kind of classifier is used in this case?
LingPipe: Classification Tutorial just N-gram based classification, is it good enough?
Classifier4J - Classifier4J
RubyForge: CRM114 Text Classifier: Project Info
Rainbow
Rainbow is a program that performs statistical text classification. It is based on the Bow library.

星期六, 十二月 15, 2007

C# 3.0 - 新功能 - implicit Type



 
 

Hudong 通过 Google 阅读器发送给您的内容:

 
 

于 07-12-15 通过 MSDN Blogs 作者:jchiou

C# 3.0 允許區域變數(local variable)使用 var 來宣告變數,它並不是以前 VB 6 的那個 var。

當使用 var 宣告時,CLR 會在編譯階段,由實際的值(等號右邊的值)來判斷它是屬於那個型態

使用以下範例來說明:

        static void Main(string[] args)
        {
            List<Customer> customers = CreateCustomers();

            Console.WriteLine("Customers:\n");
            //foreach (Customer c in customers)
            foreach (var c in customers)
                Console.WriteLine(c);

            Console.WriteLine();

            var vInt = 168;
            var vString = "這是字串";
            var x = new[] { 1, 2, 3 };

            Console.WriteLine("vInt : {0}", vInt);
            Console.WriteLine("vString : {0}", vString);
            foreach(var a in x)
                Console.WriteLine(a);
        }

執行結果:

Customers:

波羅實業        台北市  1
湯姆科技        台中市  2
墩墩數位        高雄市  3
摩利光電        新竹市  4
瑞之路邊攤      花蓮市  5

vInt : 168
vString : 這是字串
1
2
3
Press any key to continue . . .

 

完整範例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace NewLanguageFeatures
{
    public class Customer
    {
        public int CustomerId { get; private set; }

        public string Name { get; set; }
        public string City { get; set; }

        public Customer(int Id)
        {
            CustomerId = Id;
        }

        public override string ToString()
        {
            return Name + "\t" + City + "\t" + CustomerId;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            List<Customer> customers = CreateCustomers();

            Console.WriteLine("Customers:\n");
            //foreach (Customer c in customers)
            foreach (var c in customers)
                Console.WriteLine(c);

            Console.WriteLine();

            var vInt = 168;
            var vString = "這是字串";
            var x = new[] { 1, 2, 3 };

            Console.WriteLine("vInt : {0}", vInt);
            Console.WriteLine("vString : {0}", vString);
            foreach(var a in x)
                Console.WriteLine(a);
        }

        static List<Customer> CreateCustomers()
        {
            return new List<Customer>
                {
                    new Customer(1) { Name = "波羅實業",          City = "台北市" },
                    new Customer(2) { Name = "湯姆科技",          City = "台中市" },
                    new Customer(3) { Name = "墩墩數位",          City = "高雄市" },
                    new Customer(4) { Name = "摩利光電",          City = "新竹市" },
                    new Customer(5) { Name = "瑞之路邊攤",        City = "花蓮市" }
                };
        }        

    }
}

這個功能筆者很喜歡,如果要學習 LINQ 的朋友,建議對於 C# 3.0 語言的新功能先了解一下。

筆者使用的環境:Windows 2008 RC0 English + Visual Studio 2008


 
 

可从此处完成的操作:

 
 

C# 3.0 - 新功能 - Lambda expressoin



 
 

Hudong 通过 Google 阅读器发送给您的内容:

 
 

于 07-12-15 通过 MSDN Blogs 作者:jchiou

"=>"這個符號除了代表『等於大於』外,在 C# 3.0 語法中也表示 Lambda expression,它可以讓我們的程式碼更少,也可以讓程式的可讀性更高。

詳細說明:

http://msdn2.microsoft.com/en-us/library/bb397687(VS.90).aspx

完整範例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace NewLanguageFeatures
{
    public class Customer
    {
        public int CustomerId { get; private set; }

        public string Name { get; set; }
        public string City { get; set; }

        public Customer(int Id)
        {
            CustomerId = Id;
        }

        public override string ToString()
        {
            return Name + "\t" + City + "\t" + CustomerId;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            List<Customer> customers = CreateCustomers();

            Console.WriteLine("Customers:\n");

            var customerDictionary = new Dictionary<Customer, string>();

            foreach (var c in customers)
                customerDictionary.Add(c, c.Name);

            var matches = customerDictionary.FilterBy(
                (customer, name) => name.StartsWith("墩墩"));
           

            foreach (var m in matches)
                Console.WriteLine(m); 
        }

        static List<Customer> CreateCustomers()
        {
            return new List<Customer>
                {
                    new Customer(1) { Name = "波羅實業",          City = "台北市" },
                    new Customer(2) { Name = "湯姆科技",          City = "台中市" },
                    new Customer(3) { Name = "墩墩數位",          City = "高雄市" },
                    new Customer(4) { Name = "摩利光電",          City = "新竹市" },
                    new Customer(5) { Name = "瑞之路邊攤",        City = "花蓮市" }
                };
        }
    }

    public delegate bool KeyValueFilter<K, V>(K key, V value);

    public static class Extensions
    {
        public static List<K> FilterBy<K, V>(
        this Dictionary<K, V> items,
        KeyValueFilter<K, V> filter)
        {
            var result = new List<K>();

            foreach (KeyValuePair<K, V> element in items)
            {
                if (filter(element.Key, element.Value))
                    result.Add(element.Key);
            }
            return result;
        }

        public static List<T> Append<T>(this List<T> a, List<T> b)
        {
            var newList = new List<T>(a);
            newList.AddRange(b);
            return newList;
        }

        public static bool Compare(this Customer customer1, Customer customer2)
        {
            if (customer1.CustomerId == customer2.CustomerId &&
                customer1.Name == customer2.Name &&
                customer1.City == customer2.City)
            {
                return true;
            }

            return false;
        }
    }
}

執行結果:

Customers:

墩墩數位        高雄市  3
Press any key to continue . . .

筆者使用的環境:Windows 2008 RC0 English + Visual Studio 2008


 
 

可从此处完成的操作:

 
 

C# 3.0 - 新功能大綱



 
 

Hudong 通过 Google 阅读器发送给您的内容:

 
 

于 07-12-15 通过 MSDN Blogs 作者:jchiou

C#3.0 Design Themes

  • Improve on C#2.0
  • Language Integrated Query (LINQ)
  • 100% Backwards Compatible

C# 3.0 – New Language Features

  • Local Variable Type Inference
  • Object Initializers
  • Collection Initializers
  • Anonymous Types
  • Auto-Implemented Properties
  • Extension Methods
  • Lambdas
  • Query Expressions
  • Expression Trees
  • Partial Methods

 
 

可从此处完成的操作:

 
 

星期二, 十二月 11, 2007

Amazon.com: Healthy Sleep Habits, Happy Child: "Healthy Sleep Habits, Happy Child / Your Fussy Baby by Marc Weissbluth (Paperback - Oct 26, 2004)"

星期六, 十二月 01, 2007

GATE Download Page

GATE is...

* the Eclipse of Natural Language Engineering, the Lucene of Information Extraction, a leading toolkit for Text Mining
* used worldwide by thousands of scientists, companies, teachers and students
* comprised of an architecture, a free open source framework (or SDK) and graphical development environment
* used for all sorts of language processing tasks, including Information Extraction in many languages
* funded by the EPSRC, BBSRC, AHRC, the EU and commercial users
* 100% Java reference implementation of ISO TC37/SC4 and used with XCES in the ANC
* 10 years old in 2005, used in many research projects and compatible with IBM's UIMA
* based on MVC, mobile code, continuous integration, and test-driven development, with code hosted on SourceForge

星期四, 十一月 29, 2007

星期一, 十一月 26, 2007

泰国邮至广东快件装百只巨型毒蜘蛛

太可惜了

 
 

Sent to you by Hudong via Google Reader:

 
 

via 社会新闻-焦点新闻 by WWW.SINA.COM.CN on 11/26/07

  时报讯 (记者 黄熙灯 通讯员 吴恂 钟华) 广东省检验检疫局昨天透露,在一个来自泰国的快件中,该局邮检办截获100只活蜘蛛,经鉴定可能是带毒虎纹捕鸟蛛。因收货人无法提供审批手续,他们已对"不速之客"销毁处理。   该快件是从白云机场入境,省检验检疫局邮检办在查验这....

 
 

Things you can do from here:

 
 
List of 20% cashback Paypal merchants

星期五, 十一月 16, 2007

星期三, 十一月 14, 2007

Windows Scripting 範例 學習手冊 雜誌 免費下載



 
 

Sent to you by Hudong via Google Reader:

 
 

via MSDN Blogs by polo on 11/14/07

TechNet 中心彿心來的 多年 Windows Scripting 範例 學習手冊 雜誌 一手氣大贈送

不論你是 Developer 或是 IT Pro 一定都要下載來拜

Over 160 articles from the TechNet Script Center collected in a single .CHM file.

Collection of Sesame Script columns published in the TechNet Script Center.

The first three years of the Hey, Scripting Guy! column, gathered in one fully-searchable archive.


 
 

Things you can do from here:

 
 

星期二, 十一月 06, 2007

Google AJAX Search API - Google Code
no daily limit, but it has to be used on a website.

Announcing: Microsoft Search Server 2008



 
 

Hudong 通过 Google 阅读器发送给您的内容:

 
 

于 07-11-6 通过 MSDN Blogs 作者:nickmac

Hi All,

 

We're excited to announce that we're publicly unveiling Microsoft Search Server 2008 this morning at the Enterprise Search Summit in San Jose, CA.    We're also announcing a FREE version of this product – Microsoft Search Server 2008 Expresswhich customers can download immediately as a release candidate.  Search is quickly becoming the preferred way for people to find and act on information in their business.  These products will allow us to fill out Microsoft's enterprise search product lineup, which also includes Microsoft Office SharePoint Server 2007. 

 

Both Search Server 2008 and Search Server 2008 Express offer an enterprise-ready search solution that empowers people to find the information they need to get work done quickly and easily.  Key investments across both products include:

·         Streamlined installation and administration

·         Federation with any business system or online service using the OpenSearch standard

·         No pre-set document limits

·         Numerous performance and indexing enhancements

 

Search Server Express provides all the functionality of Search Server, but is limited to a single-server installation.  Search Server's multi-server capabilities offer the high availability, load balancing, and failover larger corporate IT policies typically require.  Both products will be released in the first half of 2008, and this functionality will also be made available in Microsoft Office SharePoint Server 2007.

 

The team blog has been updated announcing this news.  The new Enterprise Search website on Microsoft.com is the best place for customers to go to find out about these products.  

 

We'd also like you to encourage customers to download the release candidate of Search Server Express today. 


 
 

可从此处完成的操作:

 
 

Sample Code to Create/Update/Submit/Approve Timesheets



 
 

Sent to you by Hudong via Google Reader:

 
 

via MSDN Blogs by chrisfie on 11/5/07

Following my presentation last week at the Project Conference on Timesheet and Statusing API, please find attached some sample code that demonstrate how to create, update, submit and approve Timesheets programmatically in EPM2007 leveraging the standard Timesheet PSI methods (in C#).

As usual, this code is for sample use and provided "as-is" without express or implied warranty.


 
 

Things you can do from here:

 
 

星期日, 十一月 04, 2007

Visual Studio designer, CodeDom and InitializeComponent()



 
 

Hudong 通过 Google 阅读器发送给您的内容:

 
 

于 07-11-4 通过 MSDN Blogs 作者:carloc

The code problem

A few days ago I had the chance to work on a case not concerning ASP.NET or IIS, but rather an interaction with Visual Studio designer with classes from System.CodeDom namespace. The customer was developing a custom control meant for other developers to use it in their projects, and upon adding the control to the form, the former had to automatically modify the some codebehind files for example to add some custom methods and register itself in the InitializeComponent method to add events etc... The problem was that we were able to add new methods to the form, but despite our attempts nothing was added to InitializeComponent smile_thinking

codedom_initialize_menu

Here's the chunk of code we were using:

private void AddCode(Form form) {    IDesignerHost host = null;    host = (IDesignerHost)form.Site.GetService(typeof(IDesignerHost));     //Add method "Form1_Load" on Form1    //---------------------------------------------------------------------------    CodeMemberMethod member = new CodeMemberMethod();    member.Name = "Form1_Load";    member.Parameters.Add(new CodeParameterDeclarationExpression("System.Object", "sender"));    member.Parameters.Add(new CodeParameterDeclarationExpression("System.EventArgs", "e"));    CodeSnippetExpression sn;    sn = new CodeSnippetExpression("MessageBox.Show(\"Hello world\")");    member.Statements.Add(sn);    member.Attributes = MemberAttributes.Private;    CodeTypeDeclaration typedecl = (CodeTypeDeclaration)form.Site.GetService(typeof(CodeTypeDeclaration));    typedecl.Members.Add(member);    //---------------------------------------------------------------------------      //This code will add the following line to the "InitializeMethod" method    // this.Load += new System.EventHandler(this.Form1_Load);    //---------------------------------------------------------------------------    member = new CodeMemberMethod();    foreach (CodeTypeMember typememb in typedecl.Members)    {        if (typememb.Name == "InitializeComponent")        { member = (CodeMemberMethod)typememb; }    }    CodeDelegateCreateExpression createDelegate1;    createDelegate1 = new CodeDelegateCreateExpression(new CodeTypeReference("System.EventHandler"), new CodeThisReferenceExpression(), "Form1_Load");    CodeAttachEventStatement attach = new CodeAttachEventStatement(new CodeThisReferenceExpression(), "Load", createDelegate1);    member.Statements.Add(attach);    typedecl.Members.Add(member);    //---------------------------------------------------------------------------      //Add and remove a label because otherwise the code to add the method seems to stay "inactive,    //while in this way it works    //---------------------------------------------------------------------------    Label lbl = (Label)host.CreateComponent(typeof(Label));    host.DestroyComponent(lbl);    //--------------------------------------------------------------------------- }

Interestingly beside InitializeComponent Visual Studio was showing the yellow line which means that the code has been changed and still needs to be saved, so something was actually happening... so I tried to add the event in another method and it worked fine; an also adding a MessageBox inside the foeach loop to display LinePragma.FileName and LinePragma.LineNumber showed we were working on the appropriate code file and code line (the InitializeComponent declaration)... So there is a problem with InitializeCompoent itself?

Well, yes.

I remember I read about it long time ago when I was getting my hand dirty with the emerging .NET technology (it was back in 2001 I think), but then I moved to web applications and this went somewhere in the back of my mind... the InitializeComponent is a very important method for Visual Studio, which protects it from custom manipulations which might compromise good working of the designer, and this is actually explained in a KB article: Code comments that you add in the InitializeComponent method are lost when you add a control in Visual Studio .NET or in Visual Studio 2005.

And that was actually the exact situation we where into: for some reason the code was not added as expected unless we were adding and removing a control to the From (a Label in our case) and this simple trick had the effect to somehow activate the code (I guess that way we were calling some specific method otherwise we were not touching), but his also had the side effect to put us in the situation described in the article. And even if our was were working fine, sooner or later we would have stumbled in this kind of Visual Studio protection anyway, because a developer would have certainly added other controls to the form anyway...

So we had two problems here:

  1. Find a way to add event lines to the Form initialization
  2. Find a way to "refresh" the code without adding/removing fake controls to the Form

To resolve point one we decided to create an InitializeComponent2 method still inside Form1.Designer.cs (to have it consistent with the default InitializeComponent added by Visual Studio) so we were now able to add our events and custom properties, and add a call to our InitializeComponent2 in Form1 construction, right below the standard InitializeComponent() call, and this way we had our event working as expected smile_regular.

Chain of Events

When using design-time controls, it's important to know what happens behind the scenes when you drop a control on your design surface—or for controls such as a Form, what happens when you create a Form that is inherited from another Form you created.

When an object is opened in the design environment, the class that the object is inherited from (not the newly created class) is constructed by Visual Studio. Remember, a control that is created fires its constructor, which also fires the InitializeComponent() method within the base class's constructor. Once the derived class is constructed, that magically named method within your newly created class, InitializeComponent(), is parsed line-by-line by Visual Studio. The only thing magic about this method is its name. Visual Studio just knows to look for this method.

In Visual Basic .NET, if Visual Studio can't understand the line of code, the line is removed (a nice way of saying eaten). The Visual Basic team felt it was more important to maintain the design-time environment. The C# team felt it was more important to maintain the code, so if Visual Studio can't parse InitializeComponent() you'll get the text of the exception presented to you. This includes inherited Forms, or controls placed on the design surface of another component class control.

Any property that is part of your base object is set by the base object and its constructor. When the InitializeComponent() method runs, the values are changed to the values you have set on the property sheet. In Visual Studio, the property sheet is just a graphical representation of the InitializeComponent() method. If your base class performs some sort of functionality in the constructor, be careful; it will be executed in the design environment as well.

You do have some control over this, however. Any class that derives from the Component class has a property called DesignMode that is set to true when the code is executing within the constructs of the Visual Studio designer. So you have the option to wrap code within an if statement. There's one more trick, however. The DeisgnMode property isn't set to true in the constructor. Remember, there's no real magic here. Visual Studio creates your object as it parses the InitializeComponent() method. Once the object is constructed, Visual Studio keeps track of the objects it creates, and simply says:

newlyCreatedObject.DesignMode = true

Next steps

The argument intrigued me, so I was curious to further explore the capabilities offered by the CodeDom namespace; doing some researches on the Internet you can quite easily find articles which describes how to create a class from crash, create the source file and compile it on the fly to have the resulting assembly and this is quite a standard usage of CodeDome, here are just a couple of references:

But I've not been able to find good articles about how to customize the current code graph, the one we're currently using (instead of creating a completely new class/component from scratch), so I made some tests myself with conflicting results (something's working the way I like, something don't...). Here's what I've come up with, it's still not perfect (continue reading to find out what's wrong) but even if far from being perfect at least it works:

private void AddCode(Form form) {     //Hook to the designer     IDesignerHost host = (IDesignerHost)form.Site.GetService(typeof(IDesignerHost));        //Add method "Form1_Load" on Form1     CodeMemberMethod member = new CodeMemberMethod();     member.Name = "Form1_Load";     member.Parameters.Add(new CodeParameterDeclarationExpression("System.Object", "sender"));     member.Parameters.Add(new CodeParameterDeclarationExpression("System.EventArgs", "e"));     CodeSnippetExpression sn = new CodeSnippetExpression("MessageBox.Show(\"Hello world\")");     member.Statements.Add(sn);     member.Attributes = MemberAttributes.Private;     CodeTypeDeclaration typedecl = (CodeTypeDeclaration)form.Site.GetService(typeof(CodeTypeDeclaration));     typedecl.Members.Add(member);     //---------------------------------------------------------------------------        //Create an InitializeComponent2() method     member = new CodeMemberMethod();     member.Name = "InitializeComponent2";     typedecl.Members.Add(member);     //---------------------------------------------------------------------------        //Find the constructor and add a call to my "InitializeComponent2()" method     //CodeConstructor ctor = new CodeConstructor();     CodeConstructor ctor = null;     foreach (CodeTypeMember typememb in typedecl.Members)     {         if (typememb.Name == ".ctor")         {             ctor = (CodeConstructor)typememb;             break;         }     }      CodeMethodInvokeExpression invokeExpression = new CodeMethodInvokeExpression();     invokeExpression.Method = new CodeMethodReferenceExpression(         new CodeThisReferenceExpression(), "InitializeComponent2");      ctor.Statements.Add(invokeExpression);     typedecl.Members.Add(ctor);     //---------------------------------------------------------------------------        //This code will add the following line to the "InitializeMethod2" method     // this.Load += new System.EventHandler(this.Form1_Load);     member = new CodeMemberMethod();     foreach (CodeTypeMember typememb in typedecl.Members)     {         if (typememb.Name == "InitializeComponent2")         {             member = (CodeMemberMethod)typememb;         }     }      CodeDelegateCreateExpression createDelegate1 = new CodeDelegateCreateExpression(         new CodeTypeReference("System.EventHandler"), new CodeThisReferenceExpression(), "Form1_Load");     CodeAttachEventStatement attachStatement1 = new CodeAttachEventStatement(new CodeThisReferenceExpression(), "Load", createDelegate1);      member.Statements.Add(attachStatement1);     typedecl.Members.Add(member);     //---------------------------------------------------------------------------        //Add and remove a label because otherwise the code to add the method seems to stay "inactive",     //while in this way it works     Label lbl = (Label)host.CreateComponent(typeof(Label));     host.DestroyComponent(lbl);     //--------------------------------------------------------------------------- }

The debug problem

Debugging design time controls is not part of my daily job (I've never saw one, in web development), so while working on this case I had to figure out out to debug one of those... At the beginning I just needed to check a couple of variable values so to make things simple I just added a couple of MessageBox.Show() where I needed (like I used to fill my old ASP pages with Response.Write() statements long time ago). As you can guess this is not a practical approach. And at the same time I could not imagine to be the only person facing this problem, so there must be some article outside on the Internet dealing with this issue... and here is it, just in case you need it: Walkthrough: Debugging Custom Windows Forms Controls at Design Time.

Essentially what needs to be done is set the control's project as the startup progect, change the debug start action for the control you need to debug, setting it to "Start external program" and pointing it to the Visual Studio executable (default path is C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\devenv.exe), then set a breackpoint where you want to stop in its code and press F5 to start debugging. A new instance of Visual Studio is created, and from it you can open once again the Solution which contains the control you want to debug; now simply do what you need to run the control (add it to a new form for example) and hit the breakpoint (within the first Visual Studio instance, of course). Here we are, now you can step through, inspect variables and do whatever you usually do while debugging. smile_nerd

Note that the breakpoint icon in the first instance of Visual Studio will display the "breakpoint not hit" icon and tooltip until you cause the code to run, through the second Visual Studio instance

What's still missing

To have a well designed component I wanted to be able to create the InitializeComponent2 method where I wanted (possibly in the Designer.cs file to have it together with the standard InitializeComponent created by Visual Studio), remove the "#line" entries in the class constructor to have the code clean and easy to read and avoid the ugly trick to ad/remove a label to the form for activate the code. Unfortunately those are three problems I've still not resolved smile_thinking.

Creating a new method in Form1.cs is not a big deal, nor is adding some lines of code to it; but problems arise when trying to interact with the class constructor. This is not a protected method as we saw for InitializeComponent(), but no matter what I tried, there are always a few "#line" statements added:

public Form1() {  #line 17 "C:\Temp\TestForMS\TestForMS\TestForm\Form1.cs"     this.InitializeComponent();  #line default #line hidden     this.InitializeComponent2();  }

Interestingly those nasty "#line" does not appear if we create a new code constructor, I guess that's because in that case we're working with a new object we created and have "full control" on it; to make an example, creating a constructor overload and adding a call to my InitializeComponent2() produces perfectly clean code. Based on this assumption (still to verify, anyway) I tried to replace the class constructor with a new object created for this purpose, but when adding it to the class code graph still produces those lines... smile_eyeroll. Those are C# Preprocessor Directives and luckily the compiler does not complain, so for the moment I had to give up and live with them... smile_sad; but that's just for now, hopefully I'll find a way to get rid of them.

Ideally I wanted to create my InitializeComponent2() method to the Form1.Designer.cs file, but the default behavior is to add it to the Form1 class (in Form1.cs); the nice thing is that we have a LinePragma property which "Gets or sets the line on which the type member statement occurs", it contains a FileName and LineNumber property to clearly identify where the statement is executed. So I thought to use it to instruct the CodeDom to add my method in the code file I wanted with the following code (and quite a few variations of it):

//Create an InitializeComponent2() method member = new CodeMemberMethod(); member.Name = "InitializeComponent2"; foreach (CodeTypeMember typememb in typedecl.Members) {     if (typememb.Name == "InitializeComponent")     {         member.LinePragma = new CodeLinePragma();         member.LinePragma.FileName = typememb.LinePragma.FileName;         break;     } } typedecl.Members.Add(member); //---------------------------------------------------------------------------

Despite my attempts, InitializeComponent2() is always created in Form1.cs... still something to look into smile_eyeroll.

Finally, the ugly workaround (or should I say "alternative solution"? smile_tongue) of adding and removing the fake label to the form to activate the changes made to the code; I guess this invokes a sort of refresh mechanism, so I tried to dig into those calls with Reflector because I wanted to find the property to set or the method to call to activate the refresh without adding the label, but again with no luck... third (and hopefully last) point to clarify.

Conclusion

CodeDom offers some interesting capabilities to control developers but also has some limitations, here's a list (likely not complete):

  • CodeCompile unit does not have space for using directives or namespace members, so they are placed now into first default namespace
  • using alias directive - no support found
  • nested namespaces - no support found (so parser is flattening namespace hierarchy)
  • variable declaration list (int i,j,k;) - no support - transformed to individual var declarations
  • pointer type - no support found
  • jagged array type (array of arrays) - CSharpCodeProvider reverses order of ranks
  • params keyword - not supported - param is omitted in parsing and param is then an ordinary array type param
  • private modifier on nested delegate is not shown by CSharpCodeProvider (all other nested types works fine)
  • unsafe modifier - no support found
  • readonly modifier - no support found
  • volatile modifier - no support found
  • explicit interface implementation - not implemented yet (I think this can be done)
  • add and remove accessors for Event - no support found
  • virtual and override modifiers do not work in CSharpCodeProvider for events
  • Operator members and Destructors - no support found
  • Expressions - no unary expressions(operations), only one dimension array, some operators not supported
  • Attribute targets - no support found
  • Attributes on accessor - no support found
  • If CompileUnit contains custom attributes in global scope, CSharpCodeProvider prints then before global using directives (because using has to be in the first namespace)

Back to the sample treated in this post, I'll try to resolve those 3 open problems I mentioned above, but if any of you have some details to add (or a solution to share smile_wink) please leave a comment, I'll be happy to correct the post! smile_nerd

 

Carlo

Quote of the day:
Addresses are given to us to conceal our whereabouts. - Saki

 
 

可从此处完成的操作:

 
 

星期四, 十一月 01, 2007

华为鼓励近万员工主动辞职引热议



 
 

Sent to you by Hudong via Google Reader:

 
 

via 新闻中心-国内焦点新闻 by WWW.SINA.COM.CN on 11/1/07

  近万名华为员工被要求在明年元旦前主动辞职。近日,深圳华为技术有限公司对这些工作满8年的员工提出以上要求,他们辞职后可再与华为公司签订1~3年的劳动合同。由于华为是著名的标杆企业,因此,这一事件经媒体报道后,在社会上马上引起轰动。   对此,更多业内人士担心的....

 
 

Things you can do from here:

 
 
纳妾记·玄幻小说,书库·免费小说文学网站·文学天地

星期二, 十月 30, 2007

今年144万应届毕业生未如期就业



 
 

Sent to you by Hudong via Google Reader:

 
 

via 新闻中心-国内焦点新闻 by WWW.SINA.COM.CN on 10/30/07

  晨报讯 (记者 罗德宏) 记者昨天从教育部获悉,2008年全国高校毕业生将超过550万人,比今年增加50多万。   据介绍,今年全国高校毕业生是495万人,比2006年增加了82万人,毕业生总量和增量都是最多的一年。到今年9月1日,全国普通高等学校的毕业生实现就业的人数是351万人....

 
 

Things you can do from here:

 
 

星期一, 十月 29, 2007

Lenovo Thinkpad add on for IE7 slowing things down



 
 

Hudong 通过 Google 阅读器发送给您的内容:

 
 

于 07-10-29 通过 MSDN Blogs 作者:pooyad

I just got a new Lenovo Thinkpad T61p at work and am getting it set up.  Overall, it's very nice, I like the Thinkpad design, the pointing stick, and am getting used to the widescreen. 

I noticed that IE7 was unusally slow, especially when opening a new tab.  I always set the home page to blank to make sure everything opens fast; but for some reason everytime I would open a new tab it would take between 3-10 seconds before it would actually allow me to use the new tab.  I'd never seen this before with IE7 on my old laptop or home laptop.  Checked new tabs in my firefox installation and it was fine.

After a little searching I found the answer, though in a different language :)  It turns out it's an add-on from Lenovo (CPwmIEBrowserHelper Object) that's causing the problem.

It turns out many others have seen the same issue.  Now things are back to normal, happily browsing ... now to get my old passwords into this browser.


 
 

可从此处完成的操作:

 
 

Are you making these 3 common ASP.NET AJAX mistakes?



 
 

Hudong 通过 Google 阅读器发送给您的内容:

 
 

于 07-10-29 通过 MSDN Blogs 作者:JoeStagner

Check out Dave Wards advice on Update Panels and Postabacks at Encosia HERE.

http://encosia.com/2007/10/24/are-you-making-these-3-common-aspnet-ajax-mistakes/


 
 

可从此处完成的操作:

 
 

星期四, 十月 25, 2007

星期三, 十月 24, 2007

星期一, 十月 22, 2007

WSS 3.0中文應用範本免費下載中!



 
 

Sent to you by Hudong via Google Reader:

 
 

via MSDN Blogs by jchiou on 10/21/07

此外, WSS 提供了20種簡單的中文應用範本,包含人力資源, 專案管理, 銷售管理等常見應用, 免費供客戶使用. 可下載 "快速安裝套件"

下載位置:

http://download.microsoft.com/download/a/3/8/a3873330-221c-4d26-b563-25253deb68ff/WSSInstallationTlp.zip


 
 

Things you can do from here:

 
 

星期五, 十月 19, 2007

P3.NETPractical Programming Pearls For .NET Developers
osu!应援团 PC版

星期三, 十月 17, 2007

杨澜的杂志下载

名称:《StarMook》第十五期

发布时间:2007.10.17

当期艺人:张靓颖
C# Winforms and the Hidden Association Tag at OmegaMan’s Musings
9031: Free Downloads screen saver, icons etc

星期一, 十月 15, 2007

HOWTO: EWS: Use GetAttachment to download attachments off Mail/Appointment



 
 

Hudong 通过 Google 阅读器发送给您的内容:

 
 

于 07-10-15 通过 MSDN Blogs 作者:Vikas Verma

I have fallen for exchange web services. There are endless possibilities with exchange web services, and product group is still working to make it even better.

Today I have created a neat sample to download attachments off Exchange Server

Sample: DownloadAttachments

Input Params: itemID , folder

 

public void DownloadAttachments(string itemID,string folder)

{

 

ExchangeServiceBinding esb = new ExchangeServiceBinding();

esb.AllowAutoRedirect = true;

 

esb.Credentials = new System.Net.NetworkCredential("USERNAME", "PASSWORD", "DOMAIN");

esb.Url = "http://your-cas-server/ews/exchange.asmx";

 

//first we need to get the attachment IDs for the item so we will need to make a GetItem call first

//specify the conetent that we want to retrieve

 

PathToUnindexedFieldType[] ptufta = new PathToUnindexedFieldType[2];

ptufta[0] = new PathToUnindexedFieldType();

ptufta[0].FieldURI = UnindexedFieldURIType.itemAttachments;

ptufta[1] = new PathToUnindexedFieldType();

ptufta[1].FieldURI = UnindexedFieldURIType.itemHasAttachments;

ItemResponseShapeType irst = new ItemResponseShapeType();

irst.BaseShape = DefaultShapeNamesType.IdOnly;

irst.AdditionalProperties = ptufta;

ItemIdType[] biita = new ItemIdType[1];

biita[0] = new ItemIdType();

biita[0].Id = itemID;

//get the items

GetItemType git = new GetItemType();

git.ItemShape = irst;

git.ItemIds = biita;

 

GetItemResponseType girt = esb.GetItem(git);

 

if (girt.ResponseMessages.Items[0].ResponseClass != ResponseClassType.Success)

return;

 

//now that we have the attachment IDs let's request the atthacments and save them to disk

ItemType MsgItem = ((ItemInfoResponseMessageType)girt.ResponseMessages.Items[0]).Items.Items[0];

 

AttachmentResponseShapeType arst = null;

AttachmentIdType[] aita = null;

if (true == MsgItem.HasAttachments)

{

//create the attachment shape; we want the mime contnet just in case this is an message item so that we can save to disk

arst = new AttachmentResponseShapeType();

arst.IncludeMimeContent = true;

arst.IncludeMimeContentSpecified = true;

//create an array of attachment ids that we want to request

aita = new AttachmentIdType[MsgItem.Attachments.Length];

 

for (int i = 0; i < MsgItem.Attachments.Length; i++)

{

aita[i] = new AttachmentIdType();

aita[i].Id = MsgItem.Attachments[i].AttachmentId.Id;

}

}

 

 

//create a GetAttachment object for the GetAttachment operation

GetAttachmentType gat = new GetAttachmentType();

gat.AttachmentIds = aita;

gat.AttachmentShape = arst;

GetAttachmentResponseType gart = esb.GetAttachment(gat);

 

//save each attachment to disk

foreach (AttachmentInfoResponseMessageType Attachment in gart.ResponseMessages.Items)

{

switch (Attachment.Attachments[0].GetType().Name)

{

//attachments can be of type FileAttachmentType or ItemAttachmentType

//so we need to figure out which type we have before we manipulate it

case "FileAttachmentType":

//save to disk

FileAttachmentType TheFileAttachment = (FileAttachmentType)Attachment.Attachments[0];

 

using (Stream FileToDisk = new FileStream(folder + @"\" + Attachment.Attachments[0].Name, FileMode.Create))

{

FileToDisk.Write(TheFileAttachment.Content, 0,

TheFileAttachment.Content.Length);

FileToDisk.Flush();

FileToDisk.Close();

}

break;

 

case "ItemAttachmentType":

//save to disk

ItemType TheItemAttachment = ((ItemAttachmentType)Attachment.Attachments[0]).Item;

 

 

using (Stream FileToDisk = new FileStream(folder + @".\" + Attachment.Attachments[0].Name + ".eml", FileMode.Create))

{

byte[] ContentBytes = System.Convert.FromBase64String(TheItemAttachment.MimeContent.Value);

FileToDisk.Write(ContentBytes, 0,

ContentBytes.Length);

FileToDisk.Flush();

FileToDisk.Close();

}

break;

 

default:

break;

}

}

 

}

 

 

 

 


 
 

可从此处完成的操作: