• Wriju's BLOG

    Celebrating 200th MSDN Blog Post


    Wow experience!!! 200+ posts on MSDN with millions of hits it’s a great pleasure being at Microsoft with additional takeaways. I never thought in my life that I would be blogging. I had a dream that one day I will become writer (was not sure on what though). Blogging is a great tool to give values back to community for people with less power (like me or introvert).

    My journey has been always a pleasure (be it blogging or 5 day long on-road cross country cargo truck travel). But my greatest takeaway was when my blog was in MSDN C# Home page. Charlie was kind enough to put my blog in the same list with Scott Guthrie (http://weblogs.asp.net/scottgu/). I never had a clue on how Scott manages to write blog so regularly.

    You may find some of my selected and relevant past posts are at Charlie’s blog at Community Convergence and my journey stared from Community Convergence XXXV. I have no words to say thanks to Charlie (our very own C# Community Program Manager).  Many people have encouraged me in many ways, Program managers, friends, Microsoft Partners (with whom I work professionally), my super technical Microsoft teammates, people from everywhere over the web. Some of them have added my blog to their favorite list (priceless to me always).

    There are many things I have planned to write. I am a lazy person, so I need to be focused and keep on contributing to my blog.

    But I have promises to keep,

    And miles to go before I sleep,

    And miles to go before I sleep.


    I am not a good writer, but I love many things at Microsoft.



  • Wriju's BLOG

    How to copy my snippet in Visual Studio 2008


    I use Visual Studio 2008 code snippet a lot when I write code for my presentation. It saves a lot of time and it is very elegant. But I used to struggle a lot while changing my demo machine. Because I had to repeat the same process again and again from Tools > Snippet Manager, I find it very inconvenient if you have many snippets.

    There is an elegant way to do that, under

    C:\Documents and Settings\<<logged in user>>\My Documents\Visual Studio 2008\Code Snippets\Visual C#\My Code Snippets  

    Copy the files from your source machine and paste them to the destination machine’s same folder. You will get all the snippets. You do not have to use Snippet Manager anymore to upload snippet.


  • Wriju's BLOG

    ZoomIt : Fantastic Windows Zooming Application


    When I show demo using my desktop I often come across to the scenarios where things are very small. I was using Windows Magnifier. I found this tool later and this is very helpful. This tool was created by Microsoft Technical Fellow, Mark Russinovich.

    Some facts,

    Ø  ZoomIt runs on System Tray

    Ø  Allows you to use configurable shortcut key

    This is very lightweight and simple tool. You will enjoy if you use them.



  • Wriju's BLOG

    Visual Studio 2008 : How to zoom Class Diagram


    During my demos I have noticed that Class Diagram in Visual Studio gives a very detailed view with lot of information. Now this is hard for people sitting at the back of the room to see what is there.

    It’s very easy, if you press “CTRL” then scroll the mouse, this will zoom in and out the class diagram.


  • Wriju's BLOG

    LINQ to SQL : Missing Manual are at MSDN


    ADO.NET and LINQ to SQL

    Describes the relationship of ADO.NET and LINQ to SQL.


    Analyzing LINQ to SQL Source Code

    Describes how to analyze LINQ to SQL mapping by generating and viewing source code from the Northwind sample database.


    Customizing Insert, Update, and Delete Operations (LINQ to SQL)

    Describes how to add validation code and other customizations.


    Data Binding (LINQ to SQL)

    Describes how LINQ to SQL uses IListSource to support data binding.


    Inheritance Support (LINQ to SQL)

    Describes the role of inheritance in the LINQ to SQL object model, and how to use related operators in your queries.


    Local Method Calls (LINQ to SQL)

    Describes LINQ to SQL support for local method calls.


    Data Retrieval and CUD Operations in N-Tier Applications (LINQ to SQL)

    Provides detailed information for multi-tier applications that use LINQ to SQL.


    Object Identity (LINQ to SQL)

    Describes object identity in the LINQ to SQL object model, and explains how this feature differs from object identity in a database.


    The LINQ to SQL Object Model

    Describes the object model and its relationship to the relational data model.


    Object States and Change-Tracking (LINQ to SQL)

    Provides detailed information about how LINQ to SQL tracks changes.


    Optimistic Concurrency Overview (LINQ to SQL)

    Describes optimistic concurrency and defines terms.


    Query Concepts in LINQ to SQL

    Describes aspects of queries in LINQ to SQL that differ from queries in LINQ.


    Security in LINQ to SQL

    Describes the correct approach to security in database connections.


    Serialization (LINQ to SQL)

    Describes the serialization process in LINQ to SQL applications.


    Stored Procedures (LINQ to SQL)

    Describes how to map stored procedures at design time and how to call them from your application.


    Transactions (LINQ to SQL)

    Outlines the three models of transaction that LINQ to SQL supports.


    Type System Mismatches (LINQ to SQL)

    Describes the challenges of mingling different type systems.


    User-Defined Functions (LINQ to SQL)

    Describes how to map user-defined functions at design time and how to call them from your application.




  • Wriju's BLOG

    LINQ to SQL : Troubleshooting


    Problem with LINQ to SQL? Want to troubleshoot?



  • Wriju's BLOG



    List of FAQs are at MSDN http://msdn.microsoft.com/en-us/library/bb386929.aspx


  • Wriju's BLOG

    What do I have to do if I install IIS after Visual Studio


    What happens if you install you Visual Studio then realize that you need IIS for you application to test and run. We often do this. I have seen people uninstalling Visual Studio and then installing it again after IIS to make sure ASP.NET works fine.

    Wow!! There is an easy way to do it,

    Open the command prompt for Visual Studio 2008. Run the following command

    aspnet_regiis –i


    Install this version of ASP.NET and update scriptmaps at  the IIS metabase root and for all scriptmaps below the root. Existing scriptmaps of lower version are upgraded to

    this version. (this is from product documentation help text)


    You can also check if the specific ASP.Net version is already attached with IIS by using –lv.




  • Wriju's BLOG

    How to find public key token for a .NET DLL or assembly


    Many times we need to get the Public key token for a strongly named assembly in .NET. FAQ on that “how to get the public key token?”. Answer is very simple use the .NET Framework tools sn.exe. So open the Visual Studio 2008 Command Prompt and then point to the dll’s folder you want to get the public key,

    Use the following command,

    sn –T myDLL.dll

    This will give you the public key token. Remember one thing this only works if the assembly has to be strongly signed.


    C:\WINNT\Microsoft.NET\Framework\v3.5>sn -T EdmGen.exe

    Microsoft (R) .NET Framework Strong Name Utility  Version 3.5.21022.8

    Copyright (c) Microsoft Corporation.  All rights reserved.


    Public key token is b77a5c561934e089


  • Wriju's BLOG

    LINQ to Entity : Querying data using ADO.NET Entity Framework


    ADO.NET Entity Framework have evolved since we have released it first time. Now with the Visual Studio 2008 if you install the .NET Framework 3.5 SP1 and Visual Studio 2008 SP1 you will get the fully functional version of ADO.NET Entity Framework. This is post Beta 3 release.

    To create a .edmx file you have template in Visual Studio 2008,

    Project > Add New Item






    After creating the .edmx file, write the below query,

    using (ObjectContext objC = new ObjectContext("name=NorthwindEntities"))


        ObjectQuery<Customers> custs =



        foreach (Customers cust in custs)





    Note that this returns Object ObjectQuery<T> which implements IQueryable<T>, which means it will also allow you to write LINQ and this LINQ supports external source. Meaning it will translate the code to T-SQL (if you use MS SQL Server database).

    I feel more comfortable if I use LINQ,

    using (ObjectContext objC = new ObjectContext("name=NorthwindEntities"))


        var custs = from c in


                    where c.City == "London"

                    select c;


        foreach (Customers cust in custs)





    Now this is already strongly typed and I do not have to use ObjectContext and ObjectQuery anymore.

    So my pure LINQ to Entity will look like,

    using (NorthwindEntities db = new NorthwindEntities())


        var custs = from c in db.Customers                 

                    where c.City == "London"

                    select c;


        foreach (Customers cust in custs)







  • Wriju's BLOG

    Bill Gates The Last Day At Microsoft : Bill, we will miss you!!


    Today is the last day for Bill Gates at Microsoft. Bill says “Good Bye” to all Microsoft, his baby, his dream.


    Bill we will all miss you.


  • Wriju's BLOG

    LINQ to SQL: Making it N-Tier


    You can create your application use LINQ to SQL and make it N-Tier. Go ahead and watch out the MSDN Documents

    N-Tier and Remote Applications with LINQ to SQL

    LINQ to SQL N-Tier with ASP.NET

    LINQ to SQL N-Tier with Web Services

    LINQ to SQL with Tightly-Coupled Client-Server Applications

    Implementing Business Logic (LINQ to SQL)

    Data Retrieval and CUD Operations in N-Tier Applications (LINQ to SQL)


  • Wriju's BLOG

    Must watch “Gates Looks Back”


    Narrated by Bill Gates himself,



  • Wriju's BLOG

    Aspiring Architect Webcast Series 2008


    Dear Architects,


    Please block you calendar….


    June 16th, 2008 – 12:00 p.m. to 1:00 p.m. – Introduction to the aspiring architect Web Cast series



    June 17th, 2008 – 12:00 p.m. to 1:00 p.m. – Services Oriented Architecture and Enterprise Service Bus – Beyond the hype



    June 18th, 2008 – 12:00 p.m. to 1:00 p.m. – TOGAF and Zachman, a real-world perspective



    June 19th, 2008 – 12:00 p.m. to 1:00 p.m. – Services Oriented Architecture (Web Cast in French)



    June 20th, 2008 – 12:00 p.m. to 1:00 p.m. – Interoperability (Web Cast in French)



    June 23rd , 2008 – 12:00 p.m. to 1:00 p.m. – Realizing dynamic systems



    June 24th, 2008 – 12:00 p.m. to 1:00 p.m. – Web 2.0, beyond the hype



    June 25th, 2008 – 12:00 p.m. to 1:00 p.m. – Architecting for the user experience



    June 26th, 2008 – 12:00 p.m. to 1:00 p.m. – Conclusion and next steps




  • Wriju's BLOG

    Architecture Journal April 2008 : An A-Z Guide to Being an Architect


    While coming to office today I was reading the last article An A-Z Guide to Being an Architect of April 2008 issue. This one is probably the most realistic thought I have ever read about being true architect.

    Some of the cool thoughts,

    Knowledge of technology is only one, albeit important, domain that an architect needs to command.

    As team leader, an architect may not be required to perform line management duties, but may be called upon to be an icon for the rest of the team, providing confidence, insight, motivation, and inspiration.

    Well, not quite. N-tier is a vague term at best

    An architecture framework is a structure that removes some of the wheel reinvention that would otherwise occur.

    This one is a must read article.


  • Wriju's BLOG

    LINQ to XML : Querying XML with Namespaces


    This question arises in one of discussions. If you have a XML document with “xmlns” then LINQ to XML does not return any IEnumerable<T> J. This is strange but true for XPath and XQuery.

    There is a trick to get it done,

    Let us assume that you have a XML as follows,

    <?xml version="1.0" encoding="utf-8"?>

    <products xmlns="myns-com">

      <product ProductID="1" CategoryID="1">



      <product ProductID="2" CategoryID="1">




    Now this code holds namespace and all the child element’s default namespace would be that one “myns-com”.

    So if you try to write query against this XML

    var query = from lst in XElement.Load(@"c:\NS.xml").Elements(“product")

                select (int)lst.Attribute("ProductID");


    foreach (var k in query)




    This seems correct though it will not give you any output.

    What you need to do is, you need to the namespace in the query,

    XNamespace ns = "myns-com";


    var query = from lst in XElement.Load(@"c:\NS.xml").Elements(ns+"product")

                select (int)lst.Attribute("ProductID");


    foreach (var k in query)




    You will get the desired output as you may expect.


  • Wriju's BLOG

    Internet Explorer 8 : Will the existing sites break?


    With IE 8 and strong CSS 2.1 compliance, the sites which used to run perfectly fine with IE 7 might break. The error typically could be like, formatting, alignment or JavaScript issues. This is beta and there are ways to prevent all such problems easily.

    We do not have to follow the CSS 2.1 standard to be able to run it in IE 8. If your site runs on IE 7 without any issue the same will run on IE 8 with some simple effort. This has been described well in the KB Article # 952030.

    Option 1:

    In IIS you can add the following header info,

    X-UA-Compatible: IE=EmulateIE7

    Option 2:

    In the web.config under configuration section you can add  add,




          <clear />

          <add name="X-UA-Compatible" value="IE=EmulateIE7" />





    Option 3:

    You can modify a single page by adding meta tag,

    <html xmlns="http://www.w3.org/1999/xhtml" >

    <head runat="server">

        <title>Untitled Page</title>

        <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />



        <form id="form1" runat="server">







    Find more on Microsoft's Interoperability Principles and IE8.


  • Wriju's BLOG

    Internet Explorer 8: Start of a new era


    Being web developer I am super excited about the release of Internet Explorer 8. There are lots of talks and already we have Beta 1. Now there are some thousands features with this version and many are planned for the new version. Excitements anxiousness and many more..

    The two major goals for this release are

    Ø  Developer productivity

    Ø  User productivity

    This version of IE allows us (anyone regardless he is pro/dev) to be able to customize. There were bugs in IE7 that are addressed here apart from the new features.

    The WebSlice and Activity are the most amazing things here. If you install it you will enjoy them.

    Some start up resources,

    Find more on,




  • Wriju's BLOG

    Visual Studio 2008 Product Comparison


    One of the mostly asked questions in the Visual Studio adopters group is “what am I not getting with my version?”. This probably sometimes leads to a business decision towards buying.

    cover image: Visual Studio 2008 Product Comparison
    Download the data sheet (from MSDN)

    One place for all your queries, at http://msdn.microsoft.com/en-us/vstudio/products/cc149003.aspx


  • Wriju's BLOG

    LINQ : IEnumerable<T> and IQueryable<T>


    IEnumerable<T> and IQueryable<T> are the two most used terms of any LINQ discussion. What I am trying to here is that I am trying to simplify the two interfaces depending on their behavior. In LINQ world we generally have few providers available within .NET Framework, like LINQ to Object, LINQ to SQL, LINQ to XML.


    It is a statement that every LINQ statement returns IEnumerable<T>. IEnumerable works in steps. Meaning, when you write,


    var q = from a in b

               where a > 5

               select a;

    It creates a list out “b” depending on “where” then it creates another list for “select”. This is the behavior of LINQ to Object and LINQ to XML.




    When you use LINQ to SQL it uses IQueryable<T>. This interface inherits from IEnumerable<T> but typically any LINQ to SQL generates T-SQL at the backend to be able to get the data for us. This evaluate and generates the query at one shot and gives us the whole data.





  • Wriju's BLOG

    LINQ to SQL : FAQ Answer By Matt Warren


    Wonderful composition of FAQ is available at http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2769747&SiteID=1 by Matt Warren.


    Q: How do I get default values from the database when inserting new entities?

    A: LINQ to SQL does not support using default values from the database.  The values in the entity at the time SubmitChanges is called are used instead.  You can override how LINQ to SQL inserts entities by implementing an insert method on the DataContext.  For an entity type called ‘Entity’ implement a function with the signature of ‘InsertEntity(Entity instance)’. 

    Q:  How do I attach and update entities?  When I attach and call SubmitChanges nothing happens.

    A:  Attaching entities to a DataContext may not work as you intend.  An attached entity is merely the equivalent of an entity that has just been queried from the database and not yet modified.  In order to instruct the DataContext that you intend to have the entity updated you must provide it with information describing how the entity has changed.  You can do this in a variety of ways.  1) You can call Attach to add the entity to the DataContext and then modify individual properties.  This assumes the entity is not already in a modified state.  2) You can call the form of Attach that takes both a current and original instance of the entity.  The DataContext will recognize that individual properties values differ.  3) You can call the form of Attach that takes an additional Boolean parameter set to true to indicate that the DataContext should treat the entity as all properties modified.  The option requires that the object have a version property.

     Q: How do I serialize entities using .Net Remoting?

    A: LINQ to SQL does not support serialization using .Net Remoting.  Key data types such as EntityRef and EntitySet are not serializable. 

    Q: How do I serialize entities using WCF (Windows Communication Foundation)?

    A: LINQ to SQL supports serialization as XML via WCF by generating WCF serialization attributes and special serialization specific logic during code-generation.  You can turn on this feature in the designer by setting serialization mode to ‘Unidirectional’.  Note this is not a general solution for serialization as unidirectional mode may be insufficient for many use cases.

    Q: How do I move entities between tiers in my multi-tier application?

    A:  While it is possible to use WCF serialization to move entities between tiers it may be insufficient for your application as it will not allow for round-tripping of changes.  Defining a custom data exchange contract as part of your web service API is a better all around solution.

     Q: Should I create a new DataContext in every business logic method?

    A: The DataContext conforms to the Unit of Work design pattern.  Unless you are moving data between physical tiers between each operation you should keep your DataContext alive for the duration of work.

    Q: Should I keep my DataContext in a static/global/shared variable?

    A: The DataContext is not thread safe and is not meant to be shared.  A DataContext is meant to be used for a single unit or work or at most  for multiple consecutive units of work.

    Q: Where should I put my business logic?  The system I’m currently developing uses static methods on the entities themselves for loading, saving and other operations.

    A: The DataContext conforms to the Unit of Work design pattern.  A work context must exist and be maintained separate from the entities themselves.  You should either place all your business logic as methods on the DataContext or devise a separate business context that encapsulates a DataContext instance.  You should not be using static methods.

    Q: Are LINQ to SQL entities Business Entities or Data Transfer Objects?  How do I build a business layer on top of LINQ to SQL?

    A: LINQ to SQL entities are both business entities and data transfer objects.  LINQ to SQL takes the place of your Data Access Layer and is the basis for your Business Layer.  You can add business logic directly to the DataContext or encapsulate the DataContext in your own business context.  The purpose for making a separate business context would be to restrict access to other DataContext methods.  If this is not an issue for you, putting all business logic methods on the DataContext is the best choice.

     Q: How can I keep entities cached beyond the lifetime of a single DataContext?  I want to keep a collection of entities in a cache so that all subsequent requests can read from this cache instead of going back to the database each time.

    A: It is possible to cache entities beyond the lifetime of a single DataContext.  However, it is dangerous to do this for entities with defer loaded properties as you are likely to get accesses back to the originating DataContext if these properties are ever navigated.  You are also likely to unintentionally retain all entities materialized via that same DataContext causing what may appear to be a memory leak.  To alleviate these problems you can either turn deferred loading off when first retrieving these entities or you can dispose the DataContext after the entities are fully loaded using an operation such as ToList or ToArray.

     Q: How can I re-attach an entity to a new DataContext?  When I try to do this I get an exception thrown.

    A: LINQ to SQL does not support re-attaching entities.  Entities are never actually detached from their originating DataContexts. The Attach methods are intended to be used with entity instances that are newly created after round-tripping data from another physical tier.  LINQ to SQL detects that an entity belongs to another DataContext if any deferred properties are still unloaded.  It is possible to trick the DataContext into accepting entities from another DataContext by either not having deferred properties, pre-loading all of them or turning deferred loading off on the originating DataContext.

     Q: How can I use globally cached entities to initialize the association properties of a new entity instance or to change an association property in order make an update?  When I try this I get strange behaviors like inserts I did not intend or exceptions thrown during SubmitChanges.

    A: LINQ to SQL does not support mixing and matching entities loaded from different DataContext instances together in the same object graph.  Trying to do so is generally a bad idea.  Most association properties are bi-directional, so assigning one to a property of another or adding one to a collection property changes state and references in both entities.  This means that globally cached entities are being modified potentially on multiple threads at the same time (when running as a service).  As a general rule of thumb, a single connected entity graph should only be associated to a single unit of work at a time.  Instead of using globally cached entities to assign association properties, use entities retrieved from the DataContext you are using to perform the insert or update, or assign values to the foreign key fields directly to avoid extra round-trips to the database server.



  • Wriju's BLOG

    MSDN Magazine Topics Online


    • C# (566)

  • Wriju's BLOG

    LINQ to XML : Modifying XML document


    You have XML document now you want to modify that XML file using LINQ to XML. It is as easy as you generally modify any database column value.


    Let us create a dummy XML stream,


    //Create dummy XML to work

    var root = new XElement("parent",

        from i in new int[] { 1, 2, 3, 4, 5, 6 }

        select new XElement("child",

            new XAttribute("number", i)));


    This will create XML like,

    <?xml version="1.0" encoding="utf-8"?>


      <child number="1" />

      <child number="2" />

      <child number="3" />

      <child number="4" />

      <child number="5" />

      <child number="6" />



    Let us play with this XML file,


    //Get the element (child3)

    XElement child3 = root.Descendants("child").First(

        el => (int)el.Attribute("number") == 3);


    //Add element before the child3

    child3.AddBeforeSelf(new XElement("child25"));


    //Add sub-element to the child3

    child3.Add(new XElement("grandchild"));


    //Add element after the child3

    child3.AddAfterSelf(new XElement("child35"));


    //Add attribute to the child3

    child3.Add(new XAttribute("attr", "something"));


    //Change the existing attribute

    child3.SetAttributeValue("number", 100);


    After all these activities you will get the following output,


    <?xml version="1.0" encoding="utf-8"?>


      <child number="1" />

      <child number="2" />

      <child25 />

      <child number="100" attr="something">

        <grandchild />


      <child35 />

      <child number="4" />

      <child number="5" />

      <child number="6" />



    Highlighted part is the modified portion of your XML. You can also remove an element,





  • Wriju's BLOG

    LINQ to XML : Changing connectionString in app.config


    When you create data bind application using wizard in Windows Forms application and connection string gets added to you settings file. Now you may be interested in changing that connection string but problems,

    1)     The connection string in settings has an Application Scope so it is ReadOnly property. You modify and remove “ReadOnly” from .vb file but it gets refreshed whenever you try to add new or modify anything.

    2)     Things in Settings gets stored into <applicationName>.exe.config file.


    I took the challenge to alter the app.config file and save it again. During my try I found that LINQ to XML is the easiest way to alter with its powerful API. So the sample I have created does looks for the first <connectionString> in the <connectionStrings> section and then alters the connectionString attribute of <add element.


    Actually in app.config the section looks like,


        <add name="AppConfigChange.My.MySettings.Connstr"


    "Data Source=wghosh2k3\sqlexpress;Initial Catalog=Northwind;Integrated Security=True"

            providerName="System.Data.SqlClient" />


    I am changing the highlighted part and saving it back to the same file.


    And the code looks like,


    Dim sNewConnStr As String = ""


    'Get the file info

    Dim config As System.Configuration.Configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None)


    'Load the file info

    Dim xml = XElement.Load(config.FilePath)


    'Get the first config section (first connection string info)

    Dim connStrXML = xml.Descendants("connectionStrings").Elements().First()


    'Get the connection string value

    Dim connStr = connStrXML.Attribute("connectionString").Value


    'Create an array with ';'

    Dim arrConn() As String = connStr.Split(";")


    For i As Int16 = 0 To arrConn.Length - 1

        'Get the attribute and value splitted by "="

        Dim arrSubConn() As String = arrConn(i).Split("=")

        If (arrSubConn.Length = 2) Then

            Dim sConnAttr As String = ""

            Dim sConnValue As String = ""

            sConnAttr = arrSubConn(0)

            sConnValue = arrSubConn(1)


            'Change Database name

            If (sConnAttr = "Initial Catalog") Then

                'This is the place where you will be changing the database name

                sConnValue = "NewDBName"       

       End If


            'Generate newly altered connection string

            sNewConnStr += sConnAttr + "=" + sConnValue + ";"

        End If



    After doing everything you need to save it back to the same file,


    'Modify the existing connection string information

    connStrXML.SetAttributeValue("connectionString", sNewConnStr)


    'Saving config at the same place





  • Wriju's BLOG

    The Developer Highway Code Free E Book


    The Developer Highway Code, written by Paul Maher of DPE, is a concise handbook that captures and summarizes the key security engineering activities that should be an integral part of the software development process. This companion guide should be a must for any Developer, Architect, Tester etc. undertaking software development...The book is presented in easy to read checklist form, covering essential guidance on writing and releasing secure code. And it is available for free!

    “Developers are a most critical component to a more safe computing experience for all computer users in the UK and around the world. Code written for a program or operating system, or process must be able to withstand the most aggressive attempts to ‘break it’.  From games to mission-critical operations, secure code will form the base for success or disaster.  The Developer Highway Code should be a required reading." Edward P Gibson, Chief Security Advisor, Microsoft Ltd

    Where can you get The Developer Highway Code?

    Download full book only as a pdf or Download full book only as an xps

    I got the information from here.


Page 18 of 26 (626 items) «1617181920»