星期四, 十一月 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:

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