Mohammed Atef’s Technical blog

Running windows command shell using xp_cmdshell

Introduction

In this post i am going to share with you how to use xp_cmdshell stored procedure for running windows command shell.

xp_cmdshell is system stored procedure that used to run Windows command shell and passes in a string for execution. Any output is returned as rows of text.

Synatx

xp_cmdshell { ‘command_string’ } [ , no_output ]

where command_string Is the string that contains a command to be passed to the operating system. command_string is varchar(8000) or nvarchar(4000) and no_output Is an optional parameter, specifying that no output should be returned to the client.

Enable XP_cmdshell

If you tried to run this stored procedure and you have error says, access denied, you have to enable xp_cmdshell using below SQL script.

   1: EXEC
   2: sp_configure 'show advanced options', 1
   3: GO
   4: RECONFIGURE
   5: GO
   6: EXEC
   7: sp_configure 'xp_cmdshell', 1
   8: GO
   9: RECONFIGURE
  10: GO

Executing vb application without parameter

If you have a .net windows console application named helloworld.exe and it requires to run it from SQL you can use below list of SQL script

   1: declare @cmd varchar(500)
   2: select @param1=rolename,@param2=solutionname from roles where id in
   3: set @cmd='cmd /C "C:\helloworld.exe'
   4: exec xp_cmdshell  @cmd

Executing vb application with two parameters

otherwise, if you have an exe requires two parameters to run it, you can use below SQL Script.

   1: declare @cmd varchar(500)
   2: declare @param1 varchar(50)
   3: declare @param2 varchar(50)
   4: select @param1='param1',@param2='param2'
   5: set @cmd='cmd /C "C:\helloworld.exe '+@param1+' '+@param2+'"'
   6: exec xp_cmdshell  @cmd

Conclusion

above post we saw how to use xp_cmdshell with different modes of needs, hope it is helped.

May 30, 2013 Posted by | .Net 2010, C#,VB.Net, Developement | , , , , | Leave a comment

Workflow Foundation 4.0 Collections

Introduction

In this post we will see an important built in activities comes with Workflow foundation 4.0., these built-in activities enable you to manipulate a collection in your workflow. this post guide you to do the most required actions for manipulating collections like add,remove and delete items from collection and sorting, searching and clearing the collection.

We will build a console application that demonstrates these activities using a Book Store application.

Building Book Store application
To build the Book Store application you should follow the below steps

1- Create new console application and add System.Activities reference to the new project

2- Open the program.cs file and add the following list of code for declaring BookStoreListItem this class contains a few public properties that store information about an item to be stored.

   1: public class BookStoreListItem
   2:     {
   3:         public string Description { get; set; }
   4:         public int Quantity { get; set; }
   5:         public decimal UnitPrice { get; set; }
   6:         public string Author { get; set; }
   7:         public string BookName { get; set; }
   8:         public BookStoreListItem(string description, int quantity, decimal unitPrice,string author, string bookName)
   9:         {
  10:             Description = description;
  11:             Quantity = quantity;
  12:             UnitPrice = unitPrice;
  13:             BookName = bookName;
  14:             Author = author;
  15:         }
  16:         public BookStoreListItem(string bookName)
  17:         {
  18:             BookName= bookName;
  19:         }
  20:     }

3- Initiate the Workflow by adding the following namespace to the top of program.cs class

using System.Activities.Expressions; now add the following list of code after the closed practices for the main method in the program.cs class

   1: private static Activity CollectionWF()
   2:         {
   3:             // myList is a collection of ListItem objects
   4:             Variable<ICollection<BookStoreListItem>> myList = new Variable<ICollection<BookStoreListItem>>()
   5:             {
   6:                 Name = "MyList",
   7:                 Default = new LambdaValue<ICollection<BookStoreListItem>>
   8:                     (env => new List<BookStoreListItem>())
   9:             };
  10:             return new Sequence
  11:             {
  12:                 Variables = { myList },
  13:                 Activities =
  14:                 {
  15:                     new WriteLine
  16:                     {
  17:                         Text = "Workflow starting..."
  18:                     },
  19:                     new AddToCollection<BookStoreListItem>
  20:                     {
  21:                         Collection = myList,
  22:                         Item = new LambdaValue<BookStoreListItem>
  23:                         (env => new BookStoreListItem("New WorkFlow 4.0 book", 5, 50,"Mohammed", "WorkFlow 4.0"))
  24:                     },
  25:                     new AddToCollection<BookStoreListItem>
  26:                     {
  27:                         Collection = myList,
  28:                         Item = new LambdaValue<BookStoreListItem>
  29:                         (env => new BookStoreListItem("New Linq 4.0 book", 3, 30,"Sherif", "LINQ 4.0"))
  30:                     },
  31:                     new AddToCollection<BookStoreListItem>
  32:                     {
  33:                         Collection = myList,
  34:                         Item = new LambdaValue<BookStoreListItem>
  35:                         (env => new BookStoreListItem("New Windows Communication Foundation 4.0 book", 8, 80,"Atef", "WCF 4.0"))
  36:                     },
  37:                     new AddToCollection<BookStoreListItem>
  38:                     {
  39:                         Collection = myList,
  40:                         Item = new LambdaValue<BookStoreListItem>
  41:                         (env => new BookStoreListItem("Visual studio 2010 book", 15, 40,"Khalid", "VS 2010"))
  42:                     },
  43:                     new WriteLine
  44:                     {
  45:                         Text = "Workflow ended"
  46:                     }
  47:                 }
  48:             };
  49:         }

This workflow defines a variable that is a collection of BookStoreListItem classes named myList. The variable can be any typeof collection that supports the ICollection interface.the LambdaValue Represents a lambda expression used as an r-value, which supports binding of In arguments so it is bind the default value of myList with the returned new instance of BookStoreListItem class .

After that we are going to build the sequence activity for our workflow and the sequence activity will have the following activities

a- writeline activity that printing “Workflow starting…”

b- four AddToCollection activity that used for adding new item of BookStoreListItem to myList

c- another writeline activity to print “Workflow ended…”

4- Now we need to invoke the workflow, so please add the following lines of code in the main method at program.cs class

   1: WorkflowInvoker.Invoke(CollectionWF());
   2: Console.WriteLine("Press ENTER to exit");
   3: Console.ReadLine();

These few line of code used to invoke the workflow by calling collectionWF into the Invoke method.

If you have run the application now you will find the following lines printed

Workflow starting…

Workflow ended…

Press ENTER to exit

5- Printing Collection , we will provide a way to display the contents of the books list, to do that right-click the project and choose Add new Item and select Class, For the class name, enter PrintBooksList.cs. The implementation of this class is shown in Listing below

   1: using System;
   2: using System.Activities;
   3: using System.Collections.Generic;
   4: namespace WFFBookStoreApp
   5: {
   6:     public sealed class PrintBooksList: CodeActivity
   7:     {
   8:         public InArgument<ICollection<BookStoreListItem>> Collection { get; set; }
   9:
  10:         protected override void Execute(CodeActivityContext context)
  11:         {
  12:             ICollection<BookStoreListItem> list =
  13:             this.Collection.Get<ICollection<BookStoreListItem>>(context);
  14:             if (list.Count == 0)
  15:             {
  16:                 Console.WriteLine("The Book list is empty");
  17:             }
  18:             else
  19:             {
  20:                 foreach (BookStoreListItem l in list)
  21:                 {
  22:                     Console.WriteLine("Book Named {0} has the following information :", l.BookName);
  23:                     Console.WriteLine("(Description:{0} ,Quantity: {1},Price: {2} ,Author {3})",
  24:                     l.Description,l.Quantity.ToString(), l.UnitPrice, l.Author);
  25:                 }
  26:                 Console.WriteLine();
  27:             }
  28:         }
  29:     }
  30: }

This custom activity receives the collection as an input argument. It expects a collection of BookStoreListItem classes. the overridden execute method first check if the list empty or not, if yes it is printing the book list is empty message, else it is loop throw the list and print each book item information, this code is very simple you can understand but if you do not know how to create custom activity please visit the following link WFF 4.0 custom activity.

6- To use this custom activity, Open the program.cs file and add the following activity definition to the collectionWF () method before the final writeline activity

   1: new PrintBooksList
   2:                     {
   3:                         Collection=myList
   4:                     },

If you run the application now you will find the following message printed

clip_image002

7- Sorting the collection, we will provide a way to sort the books list by book price, to do that right-click the project and choose Add new Item and select Class, For the class name, enter SortBooksList.cs. The implementation of this class is shown in Listing below

   1: using System;
   2: using System.Activities;
   3: using System.Collections.Generic;
   4: namespace WFFBookStoreApp
   5: {
   6:     public sealed class SortBooksList : CodeActivity
   7:     {
   8:         public InOutArgument<ICollection<BookStoreListItem>> Collection { get; set; }
   9:         protected override void Execute(CodeActivityContext context)
  10:         {
  11:             ICollection<BookStoreListItem> tempList = this.Collection.Get<ICollection<BookStoreListItem>>(context);
  12:             if (tempList.Count > 0)
  13:             {
  14:                 List<BookStoreListItem> sortedList = new List<BookStoreListItem>(tempList);
  15:                 ItemComparer c = new ItemComparer();
  16:                 sortedList.Sort(c as IComparer<BookStoreListItem>);
  17:                 Collection.Set(context, sortedList as ICollection<BookStoreListItem>);
  18:             }
  19:         }
  20:     }
  21:     public class ItemComparer : IComparer<BookStoreListItem>
  22:     {
  23:         public int Compare(BookStoreListItem x, BookStoreListItem y)
  24:         {
  25:             // Handle null arguments
  26:             if (x == null && y == null)
  27:                 return 0;
  28:             if (x == null)
  29:                 return -1;
  30:             if (y == null)
  31:                 return 1;
  32:             // Perform comparison based on the priority
  33:             if (x.UnitPrice == y.UnitPrice)
  34:                 return 0;
  35:             if (x.UnitPrice > y.UnitPrice)
  36:                 return 1;
  37:             else
  38:                 return -1;
  39:         }
  40:     }
  41: }

This custom activity receives the collection as an input argument and return the same argument after sorting it. It expects a collection of BookStoreListItem classes .the overridden Execute() method of this activity takes a collection as both an input and output argument.The Sort() method of the List class is used to perform the sort, but you must supply a class that implements the IComparer interface because the standard implementation will not know how to sort BookStoreListItem objects. The IComparer interface provides a single method called Comparer (), which receives two objects (x and y) as input parameters. It returns 0 if the two objects are equal, 1 if x is greater than y, and -1 if x is less than y.

8- To use this custom activity, Open the Program.cs file and add the following activity definition to the collectionWF () method before the final writeline activity

   1: new SortBooksList
   2: {
   3:     Collection=myList
   4: },
   5: new WriteLine
   6: {
   7:     Text = "Books List sorted by Price"
   8: },
   9: new PrintBooksList
  10: {
  11:     Collection=myList
  12: },

If you run the application now you will find the following message printed

clip_image002[7]

if you have reviewed the printed lines in console, you will find the new books listed after line “books list sorted by price are order desc by price.

9- Searching in the collection, now we are going to use built in activity in Workflow Foundation 4.0 like ExistsInCollection, so we will check if the item found in the book list or not.

As the ExistsInCollection should iterate between books list items so it is require to use Equals() methods which mean we need to implement this method to our BookStoreListItem class, For our purposes, you should consider two items equal if they have the same name,To do that add the following list of code to BookStoreListItem class in program.cs file

   1: public override bool Equals(object obj)
   2: {
   3:     BookStoreListItem i = obj as BookStoreListItem;
   4:     if (i == null)
   5:         return false;
   6:     else
   7:     {
   8:         if (i.BookName == this.BookName)
   9:             return true;
  10:         else
  11:             return false;
  12:     }
  13: }
  14: public override int GetHashCode()
  15: {
  16:     return base.GetHashCode();
  17: }

The Equals() method cast the input object to a BookStoreListItem and returns True if the BookName property matches. When overriding the Equals() method, the compiler expects you to also override the GetHashCode() method. This implementation simply calls the base method

10- Now , we can use ExistsInCollection to do that add the following lines of code before the final writeline activity

   1: public override bool Equals(object obj)
   2:        {
   3:            BookStoreListItem i = obj as BookStoreListItem;
   4:            if (i == null)
   5:                return false;
   6:            else
   7:            {
   8:                if (i.BookName == this.BookName)
   9:                    return true;
  10:                else
  11:                    return false;
  12:            }
  13:        }
  14:        public override int GetHashCode()
  15:        {
  16:            return base.GetHashCode();
  17:        }
  18:

If you have run the application now you will see this line printed before workflow ended

“LINQ 4.0 Book has been added before”

11- Remove item from Collection, Workflow Foundation 4.0 has activity named RemoveFromCollection that is responsible for removing item from collection it very easy in implementation, we will use it to remove book named “LINQ 4.0“,to do that add the following line of code before the final writeline activity

   1: new WriteLine
   2: {
   3:     Text = "Removing LINQ 4.0 book from Books Store..."
   4: },
   5: new RemoveFromCollection<BookStoreListItem>()
   6: {
   7:     Collection = myList,
   8:     Item = new LambdaValue<BookStoreListItem>
   9:         (env => new BookStoreListItem("LINQ 4.0"))
  10: },
  11: new PrintBooksList()
  12: {
  13:     Collection = myList
  14: },

if you have run the application now you will see the following lines printed before workflow ended line

clip_image002[9]

12- Clearing the collection, Workflow Foundation 4.0 has built in activity to clear collection named ClearCollection to use this activity add the following lines of code before the final writeline activity

   1: new ClearCollection<BookStoreListItem>()
   2: {
   3:     Collection = myList
   4: },
   5: new PrintBooksList()
   6: {
   7:     Collection = myList
   8: },

If you have run the application now you will find line printed before workflow ended that says

“The book list is Empty”

Conclusion:

I was trying to learn you how WFF 4.0 are manipulation with collection,you can download The complete implementation of that post from here and you can return back to workflow posts list here

Back to other Workflow Foundation 4.0  posts

I Hope that helped

September 26, 2010 Posted by | .Net 2010 | , , , , , , | 1 Comment

Workflow Foundation 4.0 Tracking

Introduction

This post will guide you to use extensions for tracking Workflow events while it is executing the defined activities.This is useful for monitoring a workflow’s execution and for triggering external processing.

Tracking
In WF 4.0, tracking is accomplished through tracking participants, which are extensions that are derived
from the TrackingParticipant abstract class.
First of all to implement tracking extensions you need to inherit TrackingParticipant class and overrides the Track() method, which is where most of the work is done. When a trackable event occurs, the workflow instance will enumerate all the extensions and will call the Track() method in any that are derived from the TrackingParticipant base class.
A TrackingRecord is passed into the Track() method. This is an abstract class; the actual instance passed
in will be one of the following classes, which are derived from the TrackingRecord class:
WorkflowInstanceRecord contains data about the workflow instance.
You can use this class to print the Workflow instance ID and Workflow instance state as shown in the below list of codes:

   1: WorkflowInstanceRecord instance = record as WorkflowInstanceRecord;
   2: if (instance != null)
   3: {
   4: Console.WriteLine(String.Format(" InstanceID: {0} State: {1}",instance.InstanceId, instance.State));
   5: }

BookmarkResumptionRecord contains data about the bookmark being resumed.

You can use this class to print the book mark name as shown in the below list of codes:

   1: BookmarkResumptionRecord bookmark = record as BookmarkResumptionRecord;
   2: if (bookmark != null)
   3: {
   4: Console.WriteLine(String.Format(" Bookmark {0} resumed",bookmark.BookmarkName));
   5: }

ActivityStateRecord contains data about a specific activity.

You can use this class to print information about activities hosted in the Workflow instance as shown in the below list of codes:

   1: ActivityStateRecord activity = record as ActivityStateRecord;
   2: if (activity != null)
   3: {
   4: IDictionary<String, object> variables = activity.Variables;
   5: StringBuilder s = new StringBuilder();
   6: if (variables.Count > 0)
   7: {
   8: s.AppendLine(" Variables:");
   9: foreach (KeyValuePair<string, object> v in variables)
  10: {
  11: s.AppendLine(String.Format(" {0} Value: [{1}]",
  12: v.Key, v.Value));
  13: }
  14: }
  15: Console.WriteLine(String.Format(" Activity: {0} State: {1} {2}",
  16: activity.Activity.Name, activity.State, s.ToString()));
  17: }

CustomTrackingRecord contains user-defined data.

You can use this class to print about user-defined data as shown in the below list of codes

   1: CustomTrackingRecord user = record as CustomTrackingRecord;
   2: if ((user != null) && (user.Data.Count > 0))
   3: {
   4: Console.WriteLine(String.Format(" User Data: {0}", user.Name));
   5: foreach (string data in user.Data.Keys)
   6: {
   7: Console.WriteLine(String.Format(" {0} : {1}", data, user.Data[data]));
   8: }
   9: }

To use the tracking extension you should add the tracking extension to the Workflow instance as shown in the below list of codes

   1: i.Extensions.Add(_tracking);
   2: //where i is an instance of WorkflowApplication  
   3: //and _tracking is an instance of class that inherits TrackingParticipant class

Then you should set up the tracking extensions participants by using TrackingProfile collections, A TrackingProfile defines a collection of queries that specify which events are to be tracked by the associated tracking participant. These queries are used to determine if an event is trackable. The queries are stored in the Queries property, which is a collection of classes derived from the abstract TrackingQuery class. There are four derived classes that correspond to the four types of tracking records:

WorkflowInstanceQuery

A WorkflowInstanceQuery is used to define the workflow instance events that should be tracked. These

are the process states that occur at the instance level such as Started, Completed, Unloaded, and so on, To do that you can write the below list of codes:

   1: TrackingProfile = new TrackingProfile()
   2: {
   3:     Name = "TrackingProfileName",
   4:     Queries =
   5:     {
   6:         // For instance data, only track the started and completed events
   7:         new WorkflowInstanceQuery()
   8:         {
   9:             States = { WorkflowInstanceStates.Started,WorkflowInstanceStates.Completed },
  10:         }
  11: }

BookmarkResumptionQuery

In a BookmarkResumptionQuery, you specify the name of the bookmark that you want to track whenever it is resumed. You can specify only a single bookmark in a query. If you want to track multiple bookmarks,

you should create multiple queries—one for each bookmark, To do that you can write the below list of codes:

   1: TrackingProfile = new TrackingProfile()
   2: {
   3:     Name = "TrackingProfileName",
   4:     Queries =
   5:     {
   6:         new BookmarkResumptionQuery()
   7:                       {
   8:                           Name = "GetAssignment"
   9:                       }
  10: }

ActivityStateQuery

An ActivityStateQuery class specifies both the Name of the activity and the State collection (events) that

should be tracked. You can specify an asterisk (*) for either, which indicates that all activities and/or

states should be tracked, To do that you can write the below list of codes:

   1: TrackingProfile = new TrackingProfile()
   2:                 {
   3:                     Name = "ListBoxTrackingProfile",
   4:                     Queries =
   5:                     {
   6:                         // For activity data, track all states of the InvokeMethod
   7:                        new ActivityStateQuery()
   8:                        {
   9:                            ActivityName = "InvokeMethod",
  10:                            States = { "*" },
  11:                        }
  12:                     }
  13: }

CustomTrackingQuery

The CustomTrackingQuery specifies the ActivityName, which indicates the activity that generated the

CustomTrackingRecord and the Name property, which indicates the name given to the CustomTrackingRecord,You can specify an asterisk for either (or both) as the example, above does. When

both are set to *, it indicates that all user events should be tracked, you can do that by typing the below of codes:

   1: TrackingProfile = new TrackingProfile()
   2:                 {
   3:                     Name = "ListBoxTrackingProfile",
   4:                     Queries =
   5:                     {
   6:                         new CustomTrackingQuery()
   7:                         {
   8:                             Name = "*",
   9:                             ActivityName = "*"
  10:                         }
  11:                     }
  12: }

In this post we have understood the Tracking extension and we have learned how to use it also.now you can visit the orher posts about Workflow Foundation for here

I hope that helped.

September 26, 2010 Posted by | .Net 2010 | , , , , , , | 2 Comments

C# 4.0 new features

The major theme for C# 4.0 is Dynamic programming.first i am going to describe Dynamic is an object that their structure and behavior is not captured by a static type, or at least not one that the compiler knows about when compiling your program this information knows in run time.we have a lot of dynamic objects as COM objects,objects from dynamic programming languages, such as Python or Ruby,ordinary .NET types accessed through reflection and objects with changing structure, such as HTML DOM objects.
The new features in C# 4.0 fall into four groups:

1- Dynamic lookup


Dynamic lookup allows you to invoking things dynamically. With dynamic lookup, when you have an object in your hand you do not need to worry about whether it comes from COM, IronPython, the HTML DOM or reflection; you just apply operations to it and leave it to the runtime to figure out what exactly those operations mean for that particular object.
at the old days we was used the following code to invoke method dynamically from objects.
  

object calc = GetCalculator();
Type calcType = calc.GetType();
object res = calcType.InvokeMember(“Add”, BindingFlags.InvokeMethod, null, new object[] { 10, 20 });
int sum = Convert.ToInt32(res);
object calc = GetCalculator();
Type calcType = calc.GetType();
object res = calcType.InvokeMember(“Add”, BindingFlags.InvokeMethod, null, new object[] { 10, 20 });
int sum = Convert.ToInt32(res);

but now with the new feature in c# 4.0 we can do the same as follows
dynamic calc = GetCalculator();
int sum = calc.Add(10, 20);
Dynamic operations

object calc = GetCalculator();
Type calcType = calc.GetType();
object res = calcType.InvokeMember(“Add”, BindingFlags.InvokeMethod, null, new object[] { 10, 20 });
int sum = Convert.ToInt32(res);

object calc = GetCalculator();
Type calcType = calc.GetType();
object res = calcType.InvokeMember(“Add”, BindingFlags.InvokeMethod, null, new object[] { 10, 20 });
int sum = Convert.ToInt32(res);

Not only method calls, but also field and property accesses, indexer and operator calls and even delegate invocations can be dispatched dynamically:
dynamic d = GetDynamicObject(…);
d.M(7);
// calling methods
d.f = d.P; // getting and settings fields and properties
d[“one”] = d[“two”]; // getting and setting thorugh indexers
int i = d + 3; // calling operators
string s = d(5,7); // invoking as a delegate
The role of the C# compiler here is simply to package up the necessary information about “what is being done to d”, so that the runtime can pick it up and determine what the exact meaning of it is given an actual object d. Think of it as deferring part of the compiler’s job to runtime.
Dynamic methods can talk Dynamic objects as parameter also as shown:
dynamic d1 = new Foo();
dynamic d2 =
new Bar();
string s;
d1.M(s, d2, 3,
null);

The Dynamic Language Runtime

An important component in the underlying implementation of dynamic lookup is the Dynamic Language Runtime (DLR), which is a new API in .NET 4.0.
The DLR provides most of the infrastructure behind not only C# dynamic lookup but also the implementation of several dynamic programming languages on .NET, such as IronPython and IronRuby. 
However, if you want to implement your own dynamically dispatched objects, the IDynamicObject interface allows you to interoperate with the DLR and plug in your own behavior. you can look at the IDynamicObject as below
public abstract class DynamicObject : IDynamicObject
{
public virtual object GetMember(GetMemberBinder info);
public virtual object SetMember(SetMemberBinder info, object value);
public virtual object DeleteMember(DeleteMemberBinder info);
public virtual object UnaryOperation(UnaryOperationBinder info);
public virtual object BinaryOperation(BinaryOperationBinder info, object arg);
public virtual object Convert(ConvertBinder info);
public virtual object Invoke(InvokeBinder info, object[] args);
public virtual object InvokeMember(InvokeMemberBinder info, object[] args);
public virtual object CreateInstance(CreateInstanceBinder info, object[] ags);
public virtual object GetIndex(GetIndexBinder info, object[] indices);
public virtual object SetIndex(SetIndexBinder info, object[] indices, object value);
public virtual object DeleteIndex(DeleteIndexBinder info, object[] indices);
public MetaObject IDynamicObject.GetMetaObject();
}
2- Named and Optional Arguments

Named and optional parameters are really two distinct features, but are often useful together. Optional parameters allow you to omit arguments to member invocations, whereas named arguments is a way to provide an argument using the name of the corresponding parameter instead of relying on its position in the parameter list.
Sometimes you find yourself compelled to write many overloads of a method with different combinations of parameters, in order to provide maximum usability to the callers. Optional parameters are a useful alternative for these situations.
A parameter is declared optional simply by providing a default value for it:
public void M(int x, int y = 5, int z = 7);
Here y and z are optional parameters and can be omitted in calls:
M(1, 2, 3); // ordinary call of M
M(1, 2); // omitting z – equivalent to M(1, 2, 7)
M(1); // omitting both y and z – equivalent to M(1, 5, 7)

Named and optional arguments
you can call method by specifying the parameter name as follows
M(1, z: 3); // passing z by name
or
M(x: 1, z: 3); // passing both x and z by name
or even
M(z: 3, x: 1); // reversing the order of arguments
Note,Optional and named arguments can be used not only with methods but also with indexers and constructors.

3- Features for COM interop

Many COM methods accept and return variant types, which are represented in the PIAs as object. Now you can easily access members directly off a returned object, or you can assign it to a strongly typed local variable without having to cast.
excel.Cells[1, 1].Value = “Hello”;
instead of
((Excel.Range)excel.Cells[1, 1]).Value2 = “Hello”;
and
Excel.Range range = excel.Cells[1, 1];
instead of
Excel.Range range = (Excel.Range)excel.Cells[1, 1];

Compiling without PIAs

Primary Interop Assemblies are large .NET assemblies generated from COM interfaces to facilitate strongly typed interoperability. They provide great support at design time, where your experience of the interop is as good as if the types where really defined in .NET. The no-PIA feature allows you to continue to use PIAs at design time without having them around at runtime. Instead, the C# compiler will bake the small part of the PIA that a program actually uses directly into its assembly. At runtime the PIA does not have to be loaded.
Many COM APIs contain a lot of reference parameters. Contrary to refs in C#.It therefore seems unreasonable that a C# programmer should have to create temporary variables for all such ref parameters and pass these by reference. Instead, specifically for COM methods, the C# compiler will allow you to pass arguments by value to such a method, and will automatically generate temporary variables to hold the passed-in values, subsequently discarding these when the call returns. In this way the caller sees value semantics, and will not experience any side effects so you can replace the following code
object fileName = “Test.docx”;
object missing  = System.Reflection.Missing.Value;
doc.SaveAs(ref fileName,ref missing, ref missing, ref missing,ref missing, ref missing, ref missing,ref missing, ref missing, ref missing,ref missing, ref missing, ref missing,ref missing, ref missing, ref missing);

by this one code line doc.SaveAs(“Test.docx”);

February 1, 2009 Posted by | .Net 2010 | , , , , , | Leave a comment