• Pranav ... Blogging

    Programmatically adding a style assumes number format as “General”

    • 0 Comments

     

    Hello All,

    Few days back, I’ve seen an interesting scenario; If you add a “Style” programmatically, without specifying the number format as anything, it is assumed to be “General”.

    Something like below is fine ..

    Imports Excel = Microsoft.Office.Interop.Excel
    Public Class Form1
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Dim oXL As Excel.Application
            Dim oWB As Excel.Workbook
           
    
            Dim str As String
    
            str = "SomeStyle"
            Try
    
                oXL = CreateObject("Excel.Application")
                oXL.Visible = True
    
                ' Get a new workbook.
                oWB = oXL.Workbooks.Add
    
                oXL.ActiveWorkbook.Styles.Add(str) ' Add a new style to the workbook
    
                'Define the style formatings
    
                oXL.ActiveWorkbook.Styles(str).NumberFormat = "#,##0.0" 
                With oXL.ActiveWorkbook.Styles(str).Font
                    .Name = "Times New Roman"
                    .Size = 15
                    .Bold = True
                    .Italic = True   
                    .Strikethrough = False   
                End With
    
                With oXL.ActiveWorkbook.Styles(str)
                    .HorizontalAlignment = Excel.XlHAlign.xlHAlignLeft
                    .VerticalAlignment = Excel.XlVAlign.xlVAlignTop
                    .WrapText = False
                    .Orientation = 0
                    .AddIndent = False
                    .ShrinkToFit = False
                    .IncludeBorder = False
                End With
    
            Catch ex As Exception
                MessageBox.Show(ex.Message.ToString())
            End Try

    But if I comment out the line “.NumberFormat=”#,##0.0”, then the number format for “SomeStyle” is assumed to be “General”, which is .. well .. kind of fine in most cases.

    Now, imagine a scenario, where you have a lot of different number formatting in different cells, (e.g. 9.7489900 is displayed as 9.74), and then if you apply a style, which has a “General” format, it would reset the number format back .. which means, now you have 9.7489900! I’m sure you won’t like it .. if you specifically omitted NumberFormating.

    The only workaround I see is .. use something like below:

       Public Sub ApplyStyle(str As String)
    
            Select Case str
                Case "Style1"
                    With oXL.Selection.Font
                        .Name = "Times New Roman"
                        .Color = Color.Blue
                        .Strikethrough = False
                    End With
    
                    With oXL.Selection
                        .HorizontalAlignment = Excel.XlHAlign.xlHAlignLeft
                        .VerticalAlignment = Excel.XlVAlign.xlVAlignTop
    
                    End With
    
                Case "Style2"
    
                    With oXL.Selection.Font
                        .Name = "Times New Roman"
                        .Color = Color.Red
                        .Strikethrough = False
                    End With
    
                    With oXL.Selection
    
                        .HorizontalAlignment = Excel.XlHAlign.xlHAlignLeft
                        .VerticalAlignment = Excel.XlVAlign.xlVAlignTop
                        .NumberFormat = "General"
    
                        
    
                    End With
            End Select
    
        End Sub

    In this scenario .. you don’t really apply a style to the Workbook, you just have the code which decides as to, what is to be done @ runtime.

    Okay! Bye …

  • Pranav ... Blogging

    Dear readers - My Windows Phone 7 App is Live!

    • 0 Comments

     

    Hello All -

    I hope all of you've been doing fine! fantastic! supperb! well .. I am here to give you one more reason to feel more fantastic! supperb! and more empowered!!

    My Windows Phone 7 App is unveiled http://windowsphone.com/s?appid=7b8f683a-2dcf-47bb-8c9f-d3921250bcd0. It's called "Click Map".

    ClickMap is an answer of all of your questions like .. "Where did I park my car?", "Where is my "x" friend right now? Which place is he talking about? never heard of it ..", "This pic is fantastic .. where did I click it?", "One of my friend has a fantastic pic of a beach, but he doesn't remember which one .. how can we find it?"

    Please download it, use it .. give feedbacks! so that you get more goodness, and more love in the next version in the next version ..which is comming really really soon

     

    Bye!

  • Pranav ... Blogging

    Excel RTD Caching–Memory usage

    • 0 Comments

     

    Microsoft Office Excel provides a worksheet function, RealTimeData (RTD). This function enables you to call a Component Object Model (COM) Automation server  provides you with a way to view and update data in real time. This real-time data (RTD) feature is great for working with constantly-changing data such as stock quotes, currency exchange rates, inventory levels, price quotes, weather information, sports scores, and so on.

    To achieve high performance in such time critical scenarios, Excel has chosen to cache RTD topics related data structures at the application level (viz. they will be cached till the application lifetime). Though this offers the performance which is needed for real time scenarios, but as you can imagine, this does have an impact on the Excel memory usage in some scenarios, for example

    1)  When you are using Excel RTD with dynamic “topics”

    2) You may encounter same thing, if you happen to open multiple workbooks with large number unique RTD topics

    In both of these scenarios, if you happen to consume total addressable heap memory for that particular architecture, you may get error like “Out of virtual memory” or “There is not enough memory to complete the operation” etc. or even a crash.

    If you are running into any of the above scenario, the way to move forward is to close excel instance when there is a significant memory pressure.

    More about RTD Servers:

    Building a Real-Time Data Server in Excel 2002
    How to set up and use the RTD function in Excel

  • Pranav ... Blogging

    Manipulating Office document contents – On Steroids!

    • 0 Comments

    Yes, after a long time  .. sorry, whatever .. let’s not spend time on reasons. Not going to help anyone … Smile

     

    Here is the new story: How many time did you try manipulating document contents (for example adding something .. removing something etc), and the perf wasn’t something that you really expected. I’ve been there, part of the reason is: generally when things work great, I don’t get to see them Smile

    While working on an issue, I came across a way to manipulate Office documents with a great performance – OpenXML: Yes, I know what are you thinking, because I thought the same thing – “How on earth can you use OpenXML to manipulate a loaded document!! you can’t even open it with OpenXML SDK!!”.  The answer lies in one of my previous post where I talked about FlatOPC, (not explicitly though). I am using the same thing for document manipulation. The core idea is -

    1. Get “System.IO.Packaging.Package”  stream for the document
    2. Open it using OpenXML SDK (Yes! you can open memory stream using OpenXML SDK)
    3. Convert it to FlatOPC
    4. Manipulate whatever you want ..
    5. Use InsertXML to insert it back to the document

    Now, this is the idea – how to use it, is left to your imagination. Though I have already built a reusable library that you can use for achieving the same results without bothering what’s going on under the hoods, but it’s still in need of a good plugin system. But, you’ll get it for sure

    Below is one example of what are the things that you can achieve using this: In this example I am removing all the “Editors” from the document (because having a lot of editors might mean, a lot of network calls)

     1:       private void button1_Click(object sender, RibbonControlEventArgs e)
     2:         {
     3:             wdApp.ScreenUpdating = false;
     4:             wdApp.ActiveDocument.Content.Select();
     5:             string openxml = string.Empty;
     6:  
     7:             //Get stream for the range. This is the System.IO.Packaging.Package stream
     8:             Stream packageStream = OpcHelper.GetPackageStreamFromRange(wdApp.Selection.Range);
     9:  
     10:             //Stream packageStream = this.Paragraphs[1].Range.GetPackageStreamFromRange();
     11:             //Use Open Xml SDK to process it.
     12:             using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(packageStream, true))
     13:             {
     14:                 //Convert to flat opc using this in-memory package
     15:                 XDocument xDoc = OpcHelper.OpcToFlatOpc(wordDoc.Package);
     16:  
     17:                 XmlNamespaceManager xnm = new XmlNamespaceManager(xDoc.CreateReader().NameTable);
     18:                 xnm.AddNamespace("w", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
     19:  
     20:                 xDoc.XPathSelectElements("//w:permStart", xnm).ToList().ForEach(a => a.Remove());
     21:                 xDoc.XPathSelectElements("//w:permEnd", xnm).ToList().ForEach(a => a.Remove());
     22:  
     23:                 openxml = xDoc.ToString();
     24:             }
     25:  
     26:             
     27:  
     28:             //Insert this flat opc Xml
     29:             wdApp.ActiveDocument.Select();
     30:  
     31:             try
     32:             {
     33:                 object nullstring = "";
     34:                 wdApp.ActiveDocument.Unprotect(ref nullstring);
     35:             }
     36:             catch (Exception)
     37:             {
     38:                 throw;
     39:             }
     40:  
     41:  
     42:             wdApp.Selection.Range.InsertXML(openxml, ref missing);
     43:             wdApp.ScreenUpdating = true;
     44:         }

    Now, I am sure you are looking for explanation for some of the things here .. which I would do surely: but in the next post. This one is for you to figure out what’s happening Smile . But, don’t worry, I am not going to throw you in the dark – Below is OpcHelper that is being used:

     

     1: using System;
     2: using System.IO;
     3: using System.IO.Packaging;
     4: using System.Linq;
     5: using System.Text;
     6: using System.Xml;
     7: using System.Xml.Linq;
     8: using Microsoft.Office.Interop.Word;
     9:  
     10:  
     11: namespace WordAddIn2
     12: {
     13:     public static class OpcHelper
     14:     {
     15:     /// <summary>
     16:     /// Returns the part contents in xml
     17:     /// </summary>
     18:     /// <param name="part">System.IO.Packaging.Packagepart</param>
     19:     /// <returns></returns>
     20:     static XElement GetContentsAsXml(PackagePart part)
     21:     {
     22:         XNamespace pkg = 
     23:            "http://schemas.microsoft.com/office/2006/xmlPackage";
     24:         if (part.ContentType.EndsWith("xml"))
     25:         {
     26:             using (Stream partstream = part.GetStream())
     27:             using (StreamReader streamReader = new StreamReader(partstream))
     28:             {
     29:                 string streamString = streamReader.ReadToEnd();
     30:                 XElement newXElement = 
     31:                     new XElement(pkg + "part", new XAttribute(pkg + "name", part.Uri), 
     32:                         new XAttribute(pkg + "contentType", part.ContentType), 
     33:                         new XElement(pkg + "xmlData", XElement.Parse(streamString)));
     34:                 return newXElement;
     35:             }
     36:          }
     37:         else
     38:         {
     39:             using (Stream str = part.GetStream())
     40:             using (BinaryReader binaryReader = new BinaryReader(str))
     41:             {
     42:                 int len = (int)binaryReader.BaseStream.Length;
     43:                 byte[] byteArray = binaryReader.ReadBytes(len);
     44:                 // the following expression creates the base64String, then chunks
     45:                 // it to lines of 76 characters long
     46:                 string base64String = (System.Convert.ToBase64String(byteArray))
     47:                     .Select
     48:                     (
     49:                         (c, i) => new
     50:                         {
     51:                             Character = c,
     52:                             Chunk = i / 76
     53:                         }
     54:                     )
     55:                     .GroupBy(c => c.Chunk)
     56:                     .Aggregate(
     57:                         new StringBuilder(),
     58:                         (s, i) =>
     59:                             s.Append(
     60:                                 i.Aggregate(
     61:                                     new StringBuilder(),
     62:                                     (seed, it) => seed.Append(it.Character),
     63:                                     sb => sb.ToString()
     64:                                 )
     65:                             )
     66:                             .Append(Environment.NewLine),
     67:                         s => s.ToString()
     68:                     );
     69:  
     70:                 return new XElement(pkg + "part",
     71:                     new XAttribute(pkg + "name", part.Uri),
     72:                     new XAttribute(pkg + "contentType", part.ContentType),
     73:                     new XAttribute(pkg + "compression", "store"),
     74:                     new XElement(pkg + "binaryData", base64String)
     75:                 );
     76:             }
     77:         }
     78:     }
     79:     /// <summary>
     80:     /// Returns an XDocument
     81:     /// </summary>
     82:     /// <param name="package">System.IO.Packaging.Package</param>
     83:     /// <returns></returns>
     84:     public static XDocument OpcToFlatOpc(Package package)
     85:     {
     86:         XNamespace 
     87:             pkg = "http://schemas.microsoft.com/office/2006/xmlPackage";
     88:         XDeclaration 
     89:             declaration = new XDeclaration("1.0", "UTF-8", "yes");
     90:         XDocument doc = new XDocument(
     91:             declaration,
     92:             new XProcessingInstruction("mso-application", "progid=\"Word.Document\""),
     93:             new XElement(pkg + "package",
     94:                 new XAttribute(XNamespace.Xmlns + "pkg", pkg.ToString()),
     95:                 package.GetParts().Select(part => GetContentsAsXml(part))
     96:             )
     97:         );
     98:         return doc;
     99:     }
     100:     /// <summary>
     101:     /// Returns a System.IO.Packaging.Package stream for the given range.
     102:     /// </summary>
     103:     /// <param name="range">Range in word document</param>
     104:     /// <returns></returns>
     105:     public static Stream GetPackageStreamFromRange(Range range)
     106:     {
     107:         XDocument doc = XDocument.Parse(range.WordOpenXML);
     108:         XNamespace pkg =
     109:            "http://schemas.microsoft.com/office/2006/xmlPackage";
     110:         XNamespace rel =
     111:             "http://schemas.openxmlformats.org/package/2006/relationships";
     112:         Package InmemoryPackage = null;
     113:         MemoryStream memStream = new MemoryStream();
     114:         using (InmemoryPackage = Package.Open(memStream, FileMode.Create))
     115:         {
     116:             // add all parts (but not relationships)
     117:             foreach (var xmlPart in doc.Root
     118:                 .Elements()
     119:                 .Where(p =>
     120:                     (string)p.Attribute(pkg + "contentType") !=
     121:                     "application/vnd.openxmlformats-package.relationships+xml"))
     122:             {
     123:                 string name = (string)xmlPart.Attribute(pkg + "name");
     124:                 string contentType = (string)xmlPart.Attribute(pkg + "contentType");
     125:                 if (contentType.EndsWith("xml"))
     126:                 {
     127:                     Uri u = new Uri(name, UriKind.Relative);
     128:                     PackagePart part = InmemoryPackage.CreatePart(u, contentType,
     129:                         CompressionOption.SuperFast);
     130:                     using (Stream str = part.GetStream(FileMode.Create))
     131:                     using (XmlWriter xmlWriter = XmlWriter.Create(str))
     132:                         xmlPart.Element(pkg + "xmlData")
     133:                             .Elements()
     134:                             .First()
     135:                             .WriteTo(xmlWriter);
     136:                 }
     137:                 else
     138:                 {
     139:                     Uri u = new Uri(name, UriKind.Relative);
     140:                     PackagePart part = InmemoryPackage.CreatePart(u, contentType,
     141:                         CompressionOption.SuperFast);
     142:                     using (Stream str = part.GetStream(FileMode.Create))
     143:                     using (BinaryWriter binaryWriter = new BinaryWriter(str))
     144:                     {
     145:                         string base64StringInChunks =
     146:                        (string)xmlPart.Element(pkg + "binaryData");
     147:                         char[] base64CharArray = base64StringInChunks
     148:                             .Where(c => c != '\r' && c != '\n').ToArray();
     149:                         byte[] byteArray =
     150:                             System.Convert.FromBase64CharArray(base64CharArray,
     151:                             0, base64CharArray.Length);
     152:                         binaryWriter.Write(byteArray);
     153:                     }
     154:                 }
     155:             }
     156:             foreach (var xmlPart in doc.Root.Elements())
     157:             {
     158:                 string name = (string)xmlPart.Attribute(pkg + "name");
     159:                 string contentType = (string)xmlPart.Attribute(pkg + "contentType");
     160:                 if (contentType ==
     161:                     "application/vnd.openxmlformats-package.relationships+xml")
     162:                 {
     163:                     // add the package level relationships
     164:                     if (name == "/_rels/.rels")
     165:                     {
     166:                         foreach (XElement xmlRel in
     167:                             xmlPart.Descendants(rel + "Relationship"))
     168:                         {
     169:                             string id = (string)xmlRel.Attribute("Id");
     170:                             string type = (string)xmlRel.Attribute("Type");
     171:                             string target = (string)xmlRel.Attribute("Target");
     172:                             string targetMode =
     173:                                 (string)xmlRel.Attribute("TargetMode");
     174:                             if (targetMode == "External")
     175:                                 InmemoryPackage.CreateRelationship(
     176:                                     new Uri(target, UriKind.Absolute),
     177:                                     TargetMode.External, type, id);
     178:                             else
     179:                                 InmemoryPackage.CreateRelationship(
     180:                                     new Uri(target, UriKind.Relative),
     181:                                     TargetMode.Internal, type, id);
     182:                         }
     183:                     }
     184:                     else
     185:                     // add part level relationships
     186:                     {
     187:                         string directory = name.Substring(0, name.IndexOf("/_rels"));
     188:                         string relsFilename = name.Substring(name.LastIndexOf('/'));
     189:                         string filename =
     190:                             relsFilename.Substring(0, relsFilename.IndexOf(".rels"));
     191:                         PackagePart fromPart = InmemoryPackage.GetPart(
     192:                             new Uri(directory + filename, UriKind.Relative));
     193:                         foreach (XElement xmlRel in
     194:                             xmlPart.Descendants(rel + "Relationship"))
     195:                         {
     196:                             string id = (string)xmlRel.Attribute("Id");
     197:                             string type = (string)xmlRel.Attribute("Type");
     198:                             string target = (string)xmlRel.Attribute("Target");
     199:                             string targetMode =
     200:                                 (string)xmlRel.Attribute("TargetMode");
     201:                             if (targetMode == "External")
     202:                                 fromPart.CreateRelationship(
     203:                                     new Uri(target, UriKind.Absolute),
     204:                                     TargetMode.External, type, id);
     205:                             else
     206:                                 fromPart.CreateRelationship(
     207:                                     new Uri(target, UriKind.Relative),
     208:                                     TargetMode.Internal, type, id);
     209:                         }
     210:                     }
     211:                 }
     212:             }
     213:             InmemoryPackage.Flush();
     214:         }
     215:         return memStream;
     216:     }
     217: }
     218: }

    Stay tuned for the next set of entries where I’d attempt to explains some of the things that we’ve used here – and we’d have a full fledged library (which supports addins – and you’ll be able to do the contribution)

  • Pranav ... Blogging

    How to find all the strings in the thread stack?

    • 0 Comments

    To find the all the strings in the thread stack, you’ll need to know about a few things before we jump into code, in windbg there is something called as pseudo registers, and they are very handy to use, one of them is “$csp”, This is the current call stack pointer. This pointer is the register that is most representative of call stack depth; then there is something known as $teb, this points to thread environment block and poi(@$teb+4) always points to the stack base. You can also confirm it using !teb

    Here is the output:

    0:002> ?poi(@$teb+4)
    Evaluate expression: 40566784 = 026b0000
    0:002> !teb
    TEB at 7ffda000
        ExceptionList:        026affdc
     
      StackBase:            026b0000
        StackLimit:           026af000
        SubSystemTib:         00000000
        FiberData:            00001e00
        ArbitraryUserPointer: 00000000
        Self:                 7ffda000
        EnvironmentPointer:   00000000
        ClientId:             00000c70 . 00000c90
        RpcHandle:            00000000
        Tls Storage:          0023db88
        PEB Address:          7ffd4000
        LastErrorValue:       1008
        LastStatusValue:      c000007c
        Count Owned Locks:    0
        HardErrorMode:        0

    Now, there are a few more things to know, which would be pretty clearer after seeing the code.

    1) You can set the value of an inbuilt alias using “r <alias_name> =” notation (e.g. r@$t0 = 2, sets the value of inuilt alias $t0 to 2)
    2) “s” is a command to search strings, use –su or –sa to look for unicode or ascii strings respectively. @$t0 and @$t1 tells the command to search in the range starting from the value of @$t0 and ending at @$t1

    Using the above concepts, you can easily construct the command below easily.

    r @$t0=@$csp;r @$t1=poi(@$teb+4);s- sa @$t0 @$t1
    r @$t0=@$csp;r @$t1=poi(@$teb+4);s- su @$t0 @$t1

     

    Bye, got to get back to my work ..

  • Pranav ... Blogging

    Blog maintenance going on …

    • 0 Comments
    Changing a few things here and there, working on the bar below the blog, and adding a comment moderation system, thinking about disqus, and as usual as it's not my hosted blog I'll need to fight a lot with scripts etc.
  • Pranav ... Blogging

    Replacement of !runaway

    • 0 Comments

    !runway is a beautiful command which tells you the time taken by specific threads, very useful in hang scenarios, this is the sample output of the command:

    0:004> !runaway
    User Mode Time
      Thread       Time
       0:11b8      0 days 0:00:05.656
       6:5f8       0 days 0:00:00.265
       9:9a8       0 days 0:00:00.156
       4:1200      0 days 0:00:00.109
      12:1418      0 days 0:00:00.015
      11:1018      0 days 0:00:00.000
      10:1028      0 days 0:00:00.000
      .

      .

    But, what if you do not have this command? and no, I am not trying to reinvent the wheal, actually, this command was broken in one of the internal builds of windbg, so I had to use an alternative. Here is the alternative, with the sample output (nowadays, I prefer to use this command rather than !runaway)

    0:004> ~*e .block{~.;.ttime}
    .  0  Id: df4.11b8 Suspend: 1 Teb: 7ffdf000 Unfrozen
          Start: EXCEL!Ordinal40+0x2f74 (30002f74)
          Priority: 0  Priority class: 32  Affinity: 3
    Created: Wed Dec  9 20:18:13.610 2009 (UTC + 5:30)
    Kernel:  0 days 0:00:04.484
    User:    0 days 0:00:05.656
    .  1  Id: df4.14a4 Suspend: 1 Teb: 7ffdd000 Unfrozen
          Start: csma_ldr!WlnDisconnect+0x28c7 (611052cb)
          Priority: 0  Priority class: 32  Affinity: 3
    Created: Wed Dec  9 20:18:13.641 2009 (UTC + 5:30)
    Kernel:  0 days 0:00:00.000
    User:    0 days 0:00:00.000
    .  2  Id: df4.1700 Suspend: 1 Teb: 7ffde000 Unfrozen
          Start: EXCEL!Ordinal40+0x13681 (30013681)
          Priority: 0  Priority class: 32  Affinity: 3
    Created: Wed Dec  9 20:18:13.750 2009 (UTC + 5:30)
    Kernel:  0 days 0:00:00.000
    User:    0 days 0:00:00.000
    .  3  Id: df4.5d8 Suspend: 1 Teb: 7ffdc000 Unfrozen
          Start: EXCEL!Ordinal40+0x13681 (30013681)
          Priority: 0  Priority class: 32  Affinity: 3
    Created: Wed Dec  9 20:18:13.750 2009 (UTC + 5:30)
    Kernel:  0 days 0:00:00.000
    User:    0 days 0:00:00.000
    .  4  Id: df4.1200 Suspend: 1 Teb: 7ffdb000 Unfrozen
          Start: <Unloaded_DLL>+0xe927f (001284c7)
          Priority: 0  Priority class: 32  Affinity: 3
    Created: Wed Dec  9 20:18:13.844 2009 (UTC + 5:30)
    Kernel:  0 days 0:00:00.484
    User:    0 days 0:00:00.109

    .

    .

    Btw, there is a rather funny story regarding this command, I’ll tell you about it latter …

  • Pranav ... Blogging

    News: It’s the time to change my “about” page, I am a Support Escalation Engineer now

    • 0 Comments

    Hello Friends,

    Today, let me try to give you a few tips about my favourite part of job, dump analysis. All of us know that a problem is the mother of all inventions (or reinventions). So, what’s the problem with me? My problem is, I am lazy, very very lazy, not in everything, but in anything redundant which makes me try to automate anything and everything possible, here are a few attempts.

    Problem: Lot of dumps to analyze for the exact same problem, (say, 10 -12) and I’ve got to open all of them, find out if the dump is worth examining or not, very painstaking and believe me, the pain is directly proportional to the number of dumps.  

    Solution: Write a nifty piece of code, that does the work for you ..

    Code:

    REM: "This batch file (*.bat) is intended to do an auto analysis of multiple dumps. REM: It will just do enough analysis to get you started. "
    REM: "The problem I am trying to solve here is, how to find a needle from a haystack."
    REM: "This is just a first pass of the haystack :)"
     
    REM: "This batch file needs two parameters."
    REM: "First parameter: The directory, in which either you have the dumps, or you have subdirectories with the dumps."
    REM: "Second parameter: A log file name, in which you want to dump the analysis"
     
    FOR /R %1 %%x IN (*.dmp) DO C:\debuggers\cdb.exe -c ".echo -------------------------------------------------------------;.echo --------------------| Start Analysis   |--------------------;.echo --------------------| Start kvnL |--------------------;kvnL;.echo --------------------| End kvnL |--------------------;.echo --------------------| Start .ecxr |--------------------;.ecxr;.echo --------------------| End .ecxr |--------------------;.echo --------------------| Start !locks |--------------------;!locks;.echo --------------------| End !locks |--------------------;.echo --------------------| Start !cs -l |--------------------;!cs -l;.echo --------------------| End !cs -l |--------------------;.echo --------------------| Start !analyze -v |--------------------;!analyze -v;.echo --------------------| End !analyze -v   |--------------------;.echo --------------------| End Analysis      |--------------------;.echo -------------------------------------------------------------;qd" -loga %2 -y "srv*C:\pubsym*http://msdl.microsoft.com/downloads/symbols" -z %%x
     

     

    Isn’t it a good one, it uses just the common commands, !analyze, .ecxr, !locks, !cs –l and the output file tells you which dump(s) to analyze.

    Next Script, in my next post …

  • Pranav ... Blogging

    Project Natal: A move from “Video Gaming” to “Video Sporting”!

    • 0 Comments

    Yes .. that’s how I look @ it .. check it out if you don’t believe (or if you do ..) and spread the love!

    Xbox: "Project Natal" Home

    and here is what my fellow bloggers are saying about it …

    Hands – and Body – on with Project Natal
    XBOX Announces Project Natal- Revolutionary Gaming Experience
    Microsoft’s Project Natal in Action

    Digg This
  • Pranav ... Blogging

    So, do you really know the difference? Try blindsearch!

    • 0 Comments

    I haven’t seen the algorithm to generate three anonymous columns, but if it’s using random numbers, I’d not call it blind search, I’d call it double blind  search engine perception, experience and search experiment or DBSEPESE; Hey! I coined an acronym .. :)

    Here is the link .. have fun, http://blindsearch.fejus.com/  for more information on this experiment Blind Search- The Search Taste Test

    Digg This
  • Pranav ... Blogging

    How to take the dump for a process which crashes randomly?

    • 0 Comments

    Got this question a few times this month …  to go in a bit detail,  the question is, how to I take the dump of  winword (or any other exe for that matter), let’s say that you are automating winword and creating a new document, after creation of every document, you kill the word and restart it again .. when this code is kept running for an hr, winword crashes intermittently

    We can’t use adplus.vbs –crash –pn winword.exe, because it will attach cdb.exe to winword and will take the dump only if the crash happens in the first invocation ..

    We can’t use Image File Execution Options to attach the debugger every time winword is launched, because for one .. it makes the customer code very slow .. two .. and most of the time, it’s not unsuitable to use this on the production environment (isn’t even reliable on a client either J )

    So, the answer is – use userdump.exe, the User Mode Process Dumper (userdump) dumps any running Win32 processes memory image (including system processes such as csrss.exe, winlogon.exe, services.exe, etc) on the fly, without attaching a debugger, or terminating target processes. Generated dump file can be analyzed or debugged by using the standard debugging tools.
    The userdump generates dump file by several triggers;

    • Dump by specifying PID or process name from command line
    • Dump automatically when process being monitored caused exceptions
    • Dump automatically when process being monitored exited
    • Dump by pressing hot key sequence

    Although, this doesn’t work well with x64, but this is a boon for i386 ( "Dump on Process Termination" is implemented by hooking into the System Service Table, but x64 Windows does not allow this type of hooking. Thus, "Dump on termination" is not supported on x64 systems. )

    You can download it from User Mode Process Dumper Version 8.1

  • Pranav ... Blogging

    Under The Hood: Excel hung on SaveAs

    • 1 Comments

    I am sorry for being inactive for a long time, as a “come-back-gift” I am starting a few new sections on my blog, I am sure you’ll enjoy ’em all. This post marks the beginning of series named “Under The Hood” (yeah, sure … I am guilty for being inactive for a long time, and I will do a pleading filled post ASAP :) )

    So, the case was, “Whenever you click on “Save As” in excel, it hangs. No dialog box pops up”

    My initial troubleshooting was based on the fact that more then likely it’s caused because of an ill behaving addin. I disabled all the addins, xla’s etc but, guess what! Still he could reproduce the issue.

    At this point I was stuck and needed some more clues desperately .. so I reviewed every point in the case again and I do see a few interesting things ..

    1) Initially issues was exhibiting only on a few boxes, but now it’s on a few hundred boxes.
    2) Issue is reproducible in excel as well as in word (Although, it’s not always reproducible in word …)

    The first clue is something that might point to a danger – the issue is spreading! what could spread? either a planned deployment or a virus!! I kept my figures crossed that it’s not the latter …

    The other clue points to a fact that the issue is in some common code base, the first-n-closest-to-office-common-code-base that I could think of is – mso.dll.

    Now, to move further – customer helped me with a memory dump. Here is the stack

    0:005> k100
    ChildEBP RetAddr 
    0b87e458 77f6946c
    ole32!CoCreateInstance+0x32 <— Creating instance of something
    0b87e480 7c9f1695 shlwapi!SHCoCreateInstanceAC+0x3a
    0b87e864 7c9ef619 shell32!_SHCoCreateInstance+0x127
    0b87e8a4 7ca025bc shell32!SHCoCreateInstance+0x40
    0b87e8c0 7ca0253f shell32!DCA_CreateInstance+0x2c
    0b87ee2c 7ca02379 shell32!CFSIconOverlayManager::_LoadIconOverlayIdentifiers+0xd7
    0b87ee3c 7ca02319 shell32!CFSIconOverlayManager::_InitializeHdsaIconOverlays+0x33
    0b87ee50 7c9ef3ac shell32!CFSIconOverlayManager::CreateInstance+0x3f
    0b87ee64 7c9f29d2 shell32!CCF_CreateInstance+0x2b
    0b87ee80 7c9f299c shell32!_CreateFromDllGetClassObject+0x2d
    0b87ee9c 7c9f2961 shell32!_CreateFromShell+0x1b
    0b87f27c 7c9ef619 shell32!_SHCoCreateInstance+0x4e
    0b87f2bc 7ca022b7 shell32!SHCoCreateInstance+0x40
    0b87f2dc 7c9f41f2 shell32!IconOverlayManagerInit+0x26 <— Icon Overlay Manager calls
    0b87f2e8 7ca02864 shell32!GetIconOverlayManager+0x10

    0b87f750 7ca02063 shell32!_ShellImageListInit+0x29b
    0b87f794 7ca31618 shell32!FileIconInit+0x19b
    0b87f7a0 7ca2d215 shell32!Shell_GetImageLists+0x14
    0b87f7f0 7ca2b0cf shell32!_GetFileInfoSections+0xe4
    0b87fc78 327403f0 shell32!SHGetFileInfoW+0x13a
    WARNING: Stack unwind information not available. Following frames may be wrong.
    0b87ff60 3274027b mso!Ordinal6579+0x2c5
    0b87ff78 326172d1 mso!Ordinal6579+0x150
    <— MSO Calls … most likely “save as”
    0b87ffac 3261710f mso!Ordinal577+0x1bc
    0b87ffb4 7c80b713 mso!Ordinal320+0x31

    0b87ffec 00000000 kernel32!BaseThreadStart+0x37

    Looking at this stack, I can tell a few things  …

    1)  Initial mso callstack tells us that excel were doing something with mso, which lead to the call shell32!SHGetFileInfoW, and we know what it could be as we clicked on “Save As”.
    2) Then we do something with IconOverlayManager, I don’t know why; yet ..
    3) Then we go for creating an instance of something .. I don’t what what for; yet ..

    Let’s find out the “don’t knows” ..

    0:005> ub <— When ub Address is used, the disassembled range will be the eight or nine byte range ending with Address
    ole32!CoCreateInstance+0x1e:
    77500599 8945f4          mov     dword ptr [ebp-0Ch],eax
    7750059c 8d45f4          lea     eax,[ebp-0Ch]
    7750059f 50              push    eax
    775005a0 6a01            push    1
    775005a2 6a00            push    0
    775005a4 ff7510          push    dword ptr [ebp+10h]
    775005a7 ff750c          push    dword ptr [ebp+0Ch]
    775005aa ff7508          push    dword ptr [ebp+8]
    <— Pushing parameters on the stack

    0:005>
    u <— When u Address is used, the disassembly begins at the current Address and extends eight instructions
    ole32!CoCreateInstance+0x32:
    775005ad e874ffffff      call    ole32!CoCreateInstanceEx (77500526) <— Call CoCreateInstanceEx
    775005b2 8b4df8          mov     ecx,dword ptr [ebp-8]
    775005b5 890e            mov     dword ptr [esi],ecx
    775005b7 5e              pop     esi
    775005b8 c9              leave
    775005b9 c21400          ret     14h
    775005bc 90              nop
    775005bd 90              nop

    Looked up for the function definition of  CoCreateInstanceEx;

    HRESULT CoCreateInstanceEx(
      REFCLSID rclsid, /*[in] CLSID of the object to be created.*/
    
      IUnknown * punkOuter, 
      /*[in] When non-NULL, indicates the instance 
      is being created as part of an aggregate, and punkOuter is to be 
      used as the new instance's controlling IUnknown. Aggregation is currently 
      not supported cross-process or cross-machine. When instantiating an object
      out of process, CLASS_E_NOAGGREGATION will be returned if punkOuter is non-NULL. */
    
      DWORD dwClsCtx, /*[in] Values taken from the CLSCTX enumeration.*/
    
      COSERVERINFO * pServerInfo,
      /*[in] Information about the computer on which to instantiate 
      the object. May be NULL, in which case the object is instantiated
      on the local computer or at the computer specified in the registry 
      under the class's RemoteServerName named value, according to the 
      interpretation of the dwClsCtx parameter. See the CLSCTX documentation
      for details).*/
    
      ULONG cmq,/*[in] Number of MULTI_QI structures in pResults. Must be greater than zero.*/
    
      MULTI_QI * pResults 
      /*[in] Array of MULTI_QI structures. Each structure has three members: the
      identifier for a requested interface (pIID), the location to return the 
      interface pointer (pItf) and the return value of the call to QueryInterface (hr).*/
    );

    Looking at this description, we can surely say that ebp+8 should contain the address of a _GUID structure variable (which contains the clsid of the object to be created) … let’s see what it is!

    0:005> dt poi(ebp+8) _GUID
    ntdll!_GUID
     {3cec3e6d-ecf2-4b49-8a41-3b16df8b9c3f}
       +0x000 Data1            : 0x3cec3e6d
       +0x004 Data2            : 0xecf2
       +0x006 Data3            : 0x4b49
       +0x008 Data4            : [8]  "???"

    We’ve got it!!!

    Now, I don’t know what this clsid refers to, I checked in my registry, it wasn’t there. Then I remembered that customer also gave me his procmon log (You might already know about procmon, but if not , please don’t forget to visit Sysinternals ).

    I had a look at the procmon log with the following filters

    image

    and this is what I see …

    image

    So, I got the name of the dll that is being instantiated  (name doesn’t matter, it’s the one I removed from the picture above – say foo.dll). I suggested the customer to unregister this dll and see if it helps, he came back with the information that, the path and the dll name we gave him are not present on his machine, he told us that he did install this component (which is basically an Icon Overlay Handler), but they have uninstalled it ….

    Next action plan is to know, how did we get the reference to this component, checked again in the promon, changing the filter a bit -

    image

    This tells me

    image

    Huh, that means this GUID was picked up from a subkey of “HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers”

    Then I suggested the customer to take a backup of his registry, and remove this subkey from ShellIconOverlayIdentifiers and remove the GUID key ({3CEC3E6D-ECF2-4B49-8A41-3B16DF8B9C3F}” ) from “HKCR\CLSID”.

    This worked like a charm!! The case is resolved!!

    (btw, if you remember our first clue, this information is almost similar to our assumptions, we assumed deployments, this was uninstallation … so, maybe in this specific case, uninstaller wasn’t removing all the entries, this in turn rendered SaveAs useless for excel whenever you uninstalled this specific product!

    Talk to you latter ..bye!

  • Pranav ... Blogging

    OpenXMLDiff vNxt - Just an easy way of doing things

    • 10 Comments

     

    Hello Guys – As I told you in my previous blog post, that I am working with Eric on the updated version of OpenXMLDiff. The good news is, I have it ready! It’s uploaded on http://code.msdn.com/openxmldiff. Go, Play with it … 

    So, I am sure you’ll have many questions – what’s different? what’s changed? is it a console app? how can you use it? et cetera .. answering em’ all below:

    The initial idea behind OpenXMLDiff was to find a easy way of comparing two office files. Once you start writing you OpenXML code, sometimes you’ll find it very necessary to know what’s changed when you changed “X”.

    Eric, me and a lot of people struggled with this issue multiple times, e.g. when I wanted to compare two files, to know why only one of a few seemingly similar files work, and others throw an error.

    Granted – we have other ways, but nothing (that I found ) was easy enough to say - “Hey! comparing OpenXML files is easy …”

    image

    OpenXMLDiff.dll

    This is the core file which does the actual job. I’ve build it as a class library so that you can use it directly from your code if you wish to .. you are free to write you own PowerShell scripts, Winforms apps, Wrapper dlls around it. It’s a simple object model, just one method (Generate) with a couple of overloads to give you more flexibility. This method get’s the job done. But, before you call this method, you’ll need to pass on some options and algorithm to use (basically the options decide, what should be ignored while doing a diff between files).

    While generating the report, you’ll also need to tell what sort of output you want? Text or HTML. I’d recommend using the HTML output, because it can highlight the changes in the files which makes things a lot easier.

    Once the output is generated, It will fire an event to notify you about the outcome, (or you can just ignore the event if you are planning to to a synchronous call, but presence of event means that you can also use it asynchronously). You catch the event or you don’t -  you will be able to get all the generated output either by using the event parameters, or the read only properties css, js, diffs, sourceparts, targetparts and output

    We’ll talk about the CSS and JS afterwards, but sourceparts,targetparts and diffs are dictionaries, which will contain the parts which had differences and the diffgram explaining the differences. The output is the actual report detailing the differences (In the format you’ve selected).

    OpenXMLComparer.exe 

    Class library given above is a facility; not a compulsion – I’ve also build this Winforms application which uses above dll to generate a report.

    image

    I’ll go into further details in the next post, but first I’d want you to play with this thing and give me the feedbacks – It’s a beta, need to do a few changes yet, still, I’m sure you’ll like it!

     



     

    Not responsible for errors in content, meaning, tact, or judgment. Live and let live. Toes go in first. I didn't do it. Enjoy.

  • Pranav ... Blogging

    Here is a news, I am acting as a volunteer

    • 2 Comments

    Surely, I am volunteering for something that we (you and me) like playing with

    Here is the story – I really liked the utility that Eric is working on http://blogs.msdn.com/ericwhite/archive/2008/06/14/openxmldiff-exe-a-utility-to-find-the-differences-between-two-open-xml-documents.aspx.

    Going through the post, I noticed that Eric is looking for volunteers for converting the project to GUI to work on some possible enhancements, I pinged Eric and he agreed to let me work on it!

    so, I started working on it …. in this week (or next at max) there should be a few updates from my side.

     



    Not responsible for errors in content, meaning, tact, or judgment. Live and let live. Toes go in first. I didn't do it. Enjoy.

  • Pranav ... Blogging

    How to get a list of updates

    • 2 Comments

    Today of my team members asked me, how to get a list of Office and Windows updates.

    Surprisingly, I realized, that there is no easy way to do it (or at least I couldn’t find it ) – finally came up with following code snippets:

    'For getting a list of office updates
    '--- --- --- --- --- --- --- --- --- 
    On Error Resume Next
    strComputer = "."
    Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
    
    Set colItems = objWMIService.ExecQuery("Select * from Win32Reg_AddRemovePrograms where DisplayName Like '%update%office%' OR DisplayName Like '%update%visio%' OR DisplayName Like '%update%word%' OR DisplayName Like '%update%excel%' OR DisplayName Like '%update%powerpoint%' OR DisplayName Like '%update%project%' ",,48 )
    For Each objItem in colItems
        Wscript.Echo "DisplayName: " & objItem.DisplayName
        Wscript.Echo "InstallDate: " & objItem.InstallDate
        Wscript.Echo "ProdID: " & objItem.ProdID
        Wscript.Echo "Publisher: " & objItem.Publisher
        Wscript.Echo "Version: " & objItem.Version
    Next
    
    '--- --- --- --- --- --- --- --- --- 
    ' For getting a list of  Windows Updates
    
    ' -----------------------------------
    On Error Resume Next
    strComputer = "."
    Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
    Set colItems = objWMIService.ExecQuery("Select * from Win32_QuickFixEngineering",,48)
    For Each objItem in colItems
        Wscript.Echo "Caption: " & objItem.Caption
        Wscript.Echo "CSName: " & objItem.CSName
        Wscript.Echo "Description: " & objItem.Description
        Wscript.Echo "FixComments: " & objItem.FixComments
        Wscript.Echo "HotFixID: " & objItem.HotFixID
        Wscript.Echo "InstallDate: " & objItem.InstallDate
        Wscript.Echo "InstalledBy: " & objItem.InstalledBy
        Wscript.Echo "InstalledOn: " & objItem.InstalledOn
        Wscript.Echo "Name: " & objItem.Name
        Wscript.Echo "ServicePackInEffect: " & objItem.ServicePackInEffect
        Wscript.Echo "Status: " & objItem.Status
    Next
    
    '-----------------------------------

     

     



    Not responsible for errors in content, meaning, tact, or judgment. Live and let live. Toes go in first. I didn't do it. Enjoy.

  • Pranav ... Blogging

    The Open XML SDK download and online docs are now available

    • 0 Comments

    Let’s see what the OpenXML guru’s take about it ..

    Here is full description from none other then …Erika
    Doug Mahugh: Open XML SDK Version 1 released
    Look at it … Eric  released PowerShell cmdlets to manipulate OpenXML docs (using OpenXML SDK). WoW.. 



    Not responsible for errors in content, meaning, tact, or judgment. Live and let live. Toes go in first. I didn't do it. Enjoy.

  • Pranav ... Blogging

    My blog UI might suck for a few days

    • 0 Comments

    Yep. I am working on some changes on my blog and you might see some things broken, out of place or just plain ugly for a few days. Please bear with me for a few days.

    I am thinking of using a good JavaScript library which can ease my some of my troubles. For now, I am playing with the idea of using www.mootools.com. Let’s see how it goes.



    Not responsible for errors in content, meaning, tact, or judgment. Live and let live. Toes go in first. I didn't do it. Enjoy.

  • Pranav ... Blogging

    One more step in the right direction, native ODF support in Office 2007 SP2

    • 1 Comments

    imageDid’ya see dat! I am pretty exited about these developments, As soon as these this is out I want to play with it and see how can this feature be utilized in Office Programmability scenarios

    Are you surprised ? WHY ? It’s fairly consistent with our idea of promoting & encouraging freedom of choice.

    Also, Microsoft will join the OASIS ODF Technical Committee, and users will be able to set ODF to be the default format in their Office Applications.

    For more details have a look at following posts.

    · Office support for document format standards – Doug Mahugh,

    · Microsoft Announces Support for More Document Format Standards, including ODF – Eric White

    · Microsoft adds “Save as ODF” to Office 2007 Service Pack 2 – Gray Knowlton

    · Open XML, ODF, PDF, and XPS in Office – Jason Matusow

    · OpenXML & ODF was never a zero-sum game – Stephen McGibbon

    · Open XML Formats: ODF support in Office – Brian Jones

    · More Interop for Microsoft Office (ODF, PDF, PDF/A, XPS) – Oliver Bell



     

    Not responsible for errors in content, meaning, tact, or judgment. Live and let live. Toes go in first. I didn't do it. Enjoy.

  • Pranav ... Blogging

    What’s "Works on My Machine" Certification Program anyways ?

    • 0 Comments

    A few of my readers asked me, what’s do I mean by "Works on My Machine certified”, in my previous post. Here is the ans -  All of this thing started with Joseph Cooney – He got an interestingly funny and brilliant idea. Which, in itself, works-on-my-machine-stampedserves as a code disclaimer. Then Jeff Atwood(coding horror  fame …) zazzed things up and came up with following images!

    Maybe this is really a disclaimerworks-on-my-machine-starburst that I was looking for  -

     

     



                                                         

     

    Not responsible for errors in content, meaning, tact, or judgment. Live and let live. Toes go in first. I didn't do it. Enjoy.

     

     

  • Pranav ... Blogging

    Creating a new presentation by pulling slides from a presentation

    • 3 Comments

    You’ll remember that a few days back I’ve posted a code snippet which demonstrates how to create a PowerPoint presentation from scratch using System.IO.Packaging.

    Here is the next part of the same code which is “works on my machine” certified :)

    This is a simple WinForms Application which demonstrates how to  pull the slides from a presentation and creates a new presentation.

    In simplest terms this is what the code is doing -

    1. It let’s you browse to a PowerPoint presentation, iterates through all the slides and displays the slide heading  (GetSlideTitles)

    2. Once you select the slides you want from the presentation, it pulls those slides and associated slide layouts from the presentation. Then it adds the slides to a new presentation. (PullSlide, GetURIFromTitle, AddSlide)

    Imports System.IO
    Imports System.IO.Packaging
    Imports System.Xml
    Public Class Form1
        Dim ppt As New pptHelper
        Private Sub SelectFile_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SelectFile.Click
            Dim rs As DialogResult
            Dim items() As Object = Nothing
    
            OpenFileDialog1.Filter = "PowerPoint Presentation|*.pptx"
            rs = OpenFileDialog1.ShowDialog()
    
            If rs = Windows.Forms.DialogResult.OK Then
                SlideList.Items.Clear()
                items = ppt.GetSlideTitles(OpenFileDialog1.FileName).ToArray()
                SlideList.Items.AddRange(items)
            End If
        End Sub
    
        Public Sub MoveSlide(ByVal filename As String, ByVal slidetitle As String, ByVal remove As Boolean) ' function which will be called from "move" and "move all" 
    
            SelectedSlides.Items.Add(slidetitle) ' add it to the selected slide list
            If remove Then
                SlideList.Items.Remove(SlideList.SelectedItem) ' removing it from the slidelist (just to ensure that you don't add slides multiple times)
            End If
        End Sub
        Private Sub Move_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SelectSlide.Click
            MoveSlide(OpenFileDialog1.FileName, SlideList.SelectedItem.ToString, True)
        End Sub
        Private Sub MoveAll_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SelectAll.Click
    
            For Each o As Object In SlideList.Items ' Iterating through the listbox and moving everything to selected file list
                MoveSlide(OpenFileDialog1.FileName, o.ToString, False)
            Next o
    
            SlideList.Items.Clear() ' clearing the list
        End Sub
    
    
    
        Private Sub CreatePresentation_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CreatePresentation.Click
            Dim rs As DialogResult
            Dim source As Package = Nothing
            Dim target As Package = Nothing
            'Dim p As Package = Nothing
    
            SaveFileDialog1.Filter = "PowerPoint Presentation|*.pptx"
            rs = SaveFileDialog1.ShowDialog()
    
            If rs = Windows.Forms.DialogResult.OK Then
                target = Package.Open(SaveFileDialog1.FileName, FileMode.Create, FileAccess.ReadWrite)
                source = Package.Open(OpenFileDialog1.FileName, FileMode.Open, FileAccess.Read)
            End If
    
            ppt.CreateBasicPresentation(target)
    
            For Each s As Object In SelectedSlides.Items
                ppt.CopySlide(source, target, s.ToString(), pptHelper.relations.slidePart)
            Next
            target.Flush()
            target.Close()
            MsgBox("Done!")
        End Sub
    End Class
    
    
    
    Public Class pptHelper
    
     
    
        Public Class contents
            Public Shared presentation = "application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml"
            Public Shared slidemaster = "application/vnd.openxmlformats-officedocument.presentationml.slideMaster+xml"
            Public Shared slideLayout = "application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"
            Public Shared slidePart = "application/vnd.openxmlformats-officedocument.presentationml.slide+xml"
            Public Shared themePart = "application/vnd.openxmlformats-officedocument.theme+xml"
        End Class
    
        Public Class relations
            Public Shared officedocument = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"
            Public Shared slidemaster = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster"
            Public Shared slidelayout = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout"
            Public Shared slidePart = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide"
            Public Shared themePart = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme"
            Public Shared mainPart = "http://schemas.openxmlformats.org/presentationml/2006/main"
            Public Shared relationship = "http://schemas.openxmlformats.org/officeDocument/2006/relationships"
        End Class
    
    
    
        Dim id As Integer = CInt(New Random().NextDouble * 10000)
    
        Public Function AddSlide(ByVal pkg As Package, ByVal sldPart As PackagePart) As Boolean
            Dim xmlDoc As New XmlDocument
            Dim rId As String
            Dim xNode As XmlNode
            Dim partUri As Uri
    
    
            ' manage namespaces to perform Xml XPath queries.
            Dim nt As New NameTable()
            Dim nsManager As New XmlNamespaceManager(nt)
            nsManager.AddNamespace("p", relations.mainPart)
            nsManager.AddNamespace("r", relations.relationship)
            ' end manage
    
            Dim slide As PackagePart = pkg.CreatePart(sldPart.Uri, sldPart.ContentType)
    
    
            ' connect it with doc part and update document.xml
            Dim doc As PackagePart = pkg.GetPart(New Uri("/ppt/presentation.xml", UriKind.Relative))
            rId = doc.CreateRelationship(slide.Uri, TargetMode.Internal, relations.slidePart).Id
    
            xmlDoc.Load(doc.GetStream())
            xNode = xmlDoc.CreateNode(XmlNodeType.Element, "p", "sldId", relations.mainPart)
            Dim attrId As XmlAttribute = xmlDoc.CreateAttribute("id")
            attrId.Value = id.ToString()
            Dim attrRId As XmlAttribute = xmlDoc.CreateAttribute("r:id", relations.relationship)
            attrRId.Value = rId
            xNode.Attributes.SetNamedItem(attrId)
            xNode.Attributes.SetNamedItem(attrRId)
            'xNode.Attributes. = "<p:sldId id=" & id.ToString() & " r:id=" & rId & "/>"
            id = id + 1
    
            xmlDoc.SelectSingleNode("//p:sldIdLst", nsManager).AppendChild(xNode)
            xmlDoc.Save(doc.GetStream(FileMode.Create, FileAccess.ReadWrite))
            ' end connect
    
            'get slide layout part from the slide
            For Each r As PackageRelationship In sldPart.GetRelationshipsByType(relations.slidelayout)
                Console.WriteLine(r.TargetUri.OriginalString)
                partUri = PackUriHelper.ResolvePartUri(r.SourceUri, r.TargetUri)
                Exit For ' only one layout
            Next
            Dim lyt_src As PackagePart = sldPart.Package.GetPart(partUri)
            Dim layout As PackagePart = Nothing
    
            Try
                layout = pkg.CreatePart(lyt_src.Uri, lyt_src.ContentType)
                xmlDoc.Load(lyt_src.GetStream())
                xmlDoc.Save(layout.GetStream(FileMode.Create, FileAccess.ReadWrite))
                ' add relationships
                Dim master As PackagePart = pkg.GetPart(New Uri("/ppt/slideMasters/slideMaster1.xml", UriKind.Relative))
                rId = master.CreateRelationship(layout.Uri, TargetMode.Internal, relations.slidelayout).Id
                xNode = xmlDoc.CreateNode(XmlNodeType.Element, "p", "sldLayoutId", relations.mainPart)
                attrId = xmlDoc.CreateAttribute("id")
    
                ''BUGBUG: id attribute of <sldLayoutId> element needs to be pulled from the source presentation/package
                Dim srcSldMasterPart As PackagePart = sldPart.Package.GetPart(New Uri("/ppt/slideMasters/slideMaster1.xml", UriKind.Relative))
                Dim xmlDocSrcMaster As New XmlDocument
                Dim sSldLayourRId As String = ""
                Dim sldLytPartUri As Uri
                xmlDocSrcMaster.Load(srcSldMasterPart.GetStream())
                For Each r As PackageRelationship In srcSldMasterPart.GetRelationshipsByType(relations.slidelayout)
    
                    Console.WriteLine(r.TargetUri.OriginalString)
                    sldLytPartUri = PackUriHelper.ResolvePartUri(r.SourceUri, r.TargetUri)
                    If Uri.Compare(sldLytPartUri, partUri, UriComponents.Path, UriFormat.Unescaped, StringComparison.CurrentCulture) = 0 Then
                        sSldLayourRId = r.Id
                        Exit For
                    End If
    
                Next
    
                Dim xmlNodeSrcLayoutId As XmlNode = xmlDocSrcMaster.SelectSingleNode("//p:sldLayoutIdLst/p:sldLayoutId[@r:id='" & sSldLayourRId & "']", nsManager)
    
                Dim sSlideLayoutId As String = xmlNodeSrcLayoutId.Attributes.GetNamedItem("id").Value
                attrId.Value = sSlideLayoutId
                attrRId = xmlDoc.CreateAttribute("r:id", relations.relationship)
                attrRId.Value = rId
                xNode.Attributes.SetNamedItem(attrId)
                xNode.Attributes.SetNamedItem(attrRId)
                'xNode.Value = "<p:sldLayoutId id=" & id.ToString & " r:id=" & rId & "/>"
                id = id + 1
    
                layout.CreateRelationship(master.Uri, TargetMode.Internal, relations.slidemaster)
    
    
    
                xmlDoc.Load(master.GetStream())
                xmlDoc.SelectSingleNode("//p:sldLayoutIdLst", nsManager).AppendChild(xNode)
                xmlDoc.Save(master.GetStream(FileMode.Create, FileAccess.ReadWrite))
                ' end add
    
    
            Catch ex As Exception
                layout = pkg.GetPart(lyt_src.Uri)
            End Try
    
            'end get
            slide.CreateRelationship(layout.Uri, TargetMode.Internal, relations.slidelayout)
    
            xmlDoc.Load(sldPart.GetStream())
            xmlDoc.Save(slide.GetStream(FileMode.Create, FileAccess.ReadWrite))
        End Function
    
    
        Public Function PullSlide(ByRef pkg As Package, ByVal uri As Uri, ByVal relationship As String) As PackagePart
            Dim p As PackagePart = pkg.GetPart(uri)
            Return p
        End Function
    
        Public Function CopySlide(ByRef sourcePkg As Package, ByRef tgtPkg As Package, ByVal sourceSlide As String, ByVal relationship As String) As Boolean
            Dim sourceUri As Uri = GetUriByTitle(sourcePkg, sourceSlide)
            Dim p As PackagePart = PullSlide(sourcePkg, sourceUri, relationship)
            Return AddSlide(tgtPkg, p)
        End Function
        Public Sub CreateBasicPresentation(ByRef p As Package)
            Dim xmlDoc As New XmlDocument
            xmlDoc.LoadXml(My.Resources.presentation)
    
            Dim docUri As Uri = PackUriHelper.CreatePartUri(New Uri("ppt/presentation.xml", UriKind.Relative))
            Dim docPart As PackagePart = p.CreatePart(docUri, contents.presentation)
            p.CreateRelationship(docPart.Uri, TargetMode.Internal, relations.officedocument)
    
            xmlDoc.Save(docPart.GetStream(FileMode.Create, FileAccess.ReadWrite))
    
            Dim themeUri As Uri = PackUriHelper.CreatePartUri(New Uri("ppt/theme/theme1.xml", UriKind.Relative))
            Dim themePart As PackagePart = p.CreatePart(themeUri, contents.themePart)
            docPart.CreateRelationship(themePart.Uri, TargetMode.Internal, relations.themePart)
    
            xmlDoc.LoadXml(My.Resources.theme1)
            xmlDoc.Save(themePart.GetStream(FileMode.Create, FileAccess.ReadWrite))
    
    
            Dim slideMasterUri As Uri = PackUriHelper.CreatePartUri(New Uri("/ppt/slidemasters/slidemaster1.xml", UriKind.Relative))
            Dim slideMasterPart As PackagePart = p.CreatePart(slideMasterUri, contents.slidemaster)
            docPart.CreateRelationship(slideMasterPart.Uri, TargetMode.Internal, relations.slidemaster, "rId1")
    
            xmlDoc.LoadXml(My.Resources.slideMaster1)
    
            slideMasterPart.CreateRelationship(themePart.Uri, TargetMode.Internal, relations.themePart)
            xmlDoc.Save(slideMasterPart.GetStream(FileMode.Create, FileAccess.ReadWrite))
        End Sub
    
        Public Function GetSlideTitles(ByVal fileName As String) As List(Of String)
            ' Return a generic list containing all the slide titles.        
            ' Fill this collection with a list of all the titles
            ' of all the slides in the requested slide deck.
            Dim titles As New List(Of String)
            Dim documentPart As PackagePart = Nothing
            Dim documentUri As Uri = Nothing
    
            Using pptPackage As Package = Package.Open(fileName, FileMode.Open, FileAccess.Read)
                ' Get the main document part (presentation.xml).
                For Each relationship As PackageRelationship In pptPackage.GetRelationshipsByType(relations.officedocument)
                    documentUri = PackUriHelper.ResolvePartUri(New Uri("/", UriKind.Relative), relationship.TargetUri)
                    documentPart = pptPackage.GetPart(documentUri)
    
                    ' There's only one document part. Get out now.
                    Exit For
                Next
    
                ' Manage namespaces to perform Xml XPath queries.
                Dim nt As New NameTable()
                Dim nsManager As New XmlNamespaceManager(nt)
                nsManager.AddNamespace("p", relations.mainPart)
    
                '  Iterate through the slides and extract the title string from each.
                Dim xDoc As New XmlDocument(nt)
                xDoc.Load(documentPart.GetStream())
    
                Dim sheetNodes As XmlNodeList = xDoc.SelectNodes("//p:sldIdLst/p:sldId", nsManager)
                If sheetNodes IsNot Nothing Then
                    Dim relAttr As XmlAttribute = Nothing
                    Dim sheetRelationship As PackageRelationship = Nothing
                    Dim sheetPart As PackagePart = Nothing
                    Dim sheetUri As Uri = Nothing
                    Dim sheetDoc As XmlDocument = Nothing
                    Dim titleNode As XmlNode = Nothing
    
                    ' Look at each sheet node, retrieving the relationship id.
                    For Each xNode As XmlNode In sheetNodes
                        relAttr = xNode.Attributes("r:id")
                        If relAttr IsNot Nothing Then
                            ' Retrieve the PackageRelationship object for the sheet:
                            sheetRelationship = documentPart.GetRelationship(relAttr.Value)
                            If sheetRelationship IsNot Nothing Then
                                sheetUri = PackUriHelper.ResolvePartUri(documentUri, sheetRelationship.TargetUri)
                                sheetPart = pptPackage.GetPart(sheetUri)
                                If sheetPart IsNot Nothing Then
                                    ' You've got a reference to the sheet. Now load its contents and
                                    ' find the title.
                                    sheetDoc = New XmlDocument(nt)
                                    sheetDoc.Load(sheetPart.GetStream())
    
                                    titleNode = sheetDoc.SelectSingleNode("//p:sp//p:ph[@type='title' or @type='ctrTitle']", nsManager)
                                    If titleNode IsNot Nothing Then
                                        titles.Add(titleNode.ParentNode.ParentNode.ParentNode.InnerText)
                                    End If
                                End If
                            End If
                        End If
                    Next
                End If
            End Using
            Return titles
        End Function
    
        Public Function GetUriByTitle(ByRef pptPackage As Package, ByVal slideTitle As String) As Uri
            ' Given a slide document and a slide title, retrieve the 0-based index of the 
            ' first slide with a matching title. Return -1 if the title isn't found.
    
            ' Note: This code assumes that the first text found is the title.
            ' Also note that if the title contains more than one font,
            ' or is in any way anything other than plain text, PowerPoint
            ' breaks it up into multiple elements. This code won't find a match
            ' in that case.
    
    
            Dim returnValue As Uri
            Dim documentPart As PackagePart = Nothing
    
            'Using pptPackage As Package = package
            ' Get the main document part (presentation.xml).
            For Each relationship As PackageRelationship In pptPackage.GetRelationshipsByType(relations.officedocument)
                Dim documentUri As Uri = PackUriHelper.ResolvePartUri(New Uri("/", UriKind.Relative), relationship.TargetUri)
                documentPart = pptPackage.GetPart(documentUri)
                ' There is only one document.
                Exit For
            Next
    
            ' Manage namespaces to perform Xml XPath queries.
            Dim nt As New NameTable()
            Dim nsManager As New XmlNamespaceManager(nt)
            nsManager.AddNamespace("p", relations.mainPart)
            nsManager.AddNamespace("r", relations.relationship)
    
            ' Get the contents of the presentation part.
            Dim presentationDoc As New XmlDocument(nt)
            presentationDoc.Load(documentPart.GetStream())
    
            '  Iterate through the slides and extract the title string from each.
            Dim slidePart As PackagePart = Nothing
            Dim slideUri As Uri = Nothing
    
            ' Select each slide document part (slides/slideX.xml)
            ' via relationship with document part.
            For Each relation As PackageRelationship In documentPart.GetRelationshipsByType(relations.slidePart)
                slideUri = PackUriHelper.ResolvePartUri(documentPart.Uri, relation.TargetUri)
                slidePart = pptPackage.GetPart(slideUri)
    
                ' Get the slide part from the package.
                Dim doc As XmlDocument = New XmlDocument(nt)
    
                ' Load the slide contents:
                doc.Load(slidePart.GetStream())
    
                ' Locate the slide title using XPath.
                Dim titleNode As XmlNode = doc.SelectSingleNode("//p:sp//p:ph[@type='title' or @type='ctrTitle']", nsManager)
                If titleNode IsNot Nothing Then
                    ' Perform a case-insensitive comparison.
                    Dim titleText As String = titleNode.ParentNode.ParentNode.ParentNode.InnerText
                    If String.Compare(titleText, slideTitle, True) = 0 Then
                        ' You've found the slide part with a matching title.
                        ' Get the relationship ID, and find the corresponding item in the 
                        ' document part:
                        Dim searchString As String = String.Format("//p:sldIdLst/p:sldId[@r:id='{0}']", relation.Id)
                        Dim node As XmlNode = presentationDoc.SelectSingleNode(searchString, nsManager)
                        If node IsNot Nothing Then
                            ' Retrieve the index of the selected node.
                            ' To do that, count the number of preceding
                            ' nodes by retrieving a reference to those nodes.
                            returnValue = slidePart.Uri
                        End If
    
                        ' Only retrieve information about the first slide that matches the specified title.
                        Exit For
                    End If
                End If
            Next
            'End Using
            Return returnValue
        End Function
        Public Function GetUriByTitle(ByVal fileName As String, ByVal slideTitle As String) As String
            ' Given a slide document and a slide title, retrieve the 0-based index of the 
            ' first slide with a matching title. Return -1 if the title isn't found.
    
            ' Note: This code assumes that the first text found is the title.
            ' Also note that if the title contains more than one font,
            ' or is in any way anything other than plain text, PowerPoint
            ' breaks it up into multiple elements. This code won't find a match
            ' in that case.
    
            Dim returnValue As String = ""
            Dim documentPart As PackagePart = Nothing
    
            Using pptPackage As Package = Package.Open(fileName, FileMode.Open, FileAccess.ReadWrite)
                ' Get the main document part (presentation.xml).
                GetUriByTitle(pptPackage, slideTitle)
    
            End Using
            Return returnValue
        End Function
    
    End Class

     

     

    Not responsible for errors in content, meaning, tact, or judgment. Live and let live. Toes go in first. I didn't do it. Enjoy.

  • Pranav ... Blogging

    Word 2007 “Save As Word XML document” and back without automation – 1

    • 4 Comments

    Did you even had a look at new Word XML File? or … like me, you also assumed that it’s going to be same or similar to Word 2003 XML?

    Yesterday … one of my fellow MSFT was  working on Packaging API to create and modify a document.

    We had a quick conversation …

    Manjunath Khatawkar‎‎ [11:32 PM]:
    Hi Pranav.. We are storing the WordOpenXml in database and I'm trying to create a new Package from the stored WordOpenXml string.. I keep getting the "File contains corrupted data" error.. but if i open a normal .docx file it works fine..
    How can I create a Package from WordOpenXml string?

    ‎‎Pranav Wagh‎‎ [12:06 AM]:
      can you give me a sort of code snippet ..so that I can comment on it?

     

    He sent me an email -

    Hi Pranav,

    I’m storing the WordOpenXml (see attachment) of a Word 2007 document in database.

    During document assembly, I retrieve WordOpenXml from DB save it as a xml file on harddisk. When I try to create a Package, I get the "File contains corrupted data" exception. But if I open the xml in Word 2007 and save it as a .docx file, then I’m able to create a package.

    Following is the code snippet

    Package wordPackage = Package.Open(fileName);

    What am I doing wrong here? Do I need to create package from scratch and add individual ParakagePart by looping thro’ the Xml?

    Let me know.

    Thanks,

    Manju

     

    What !! I didn’t even understand this email till I have the super surprise in front of me, in the form of XML file that he sent me  -

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <?mso-application progid="Word.Document"?>
    <pkg:package xmlns:pkg="http://schemas.microsoft.com/office/2006/xmlPackage">
      <pkg:part pkg:name="/_rels/.rels" pkg:contentType="application/vnd.openxmlformats-package.relationships+xml" pkg:padding="512">
        <pkg:xmlData>
          <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
            <Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/>
            <Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/>
            <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/>
          </Relationships>
        </pkg:xmlData>
      </pkg:part>
      <pkg:part pkg:name="/word/_rels/document.xml.rels" pkg:contentType="application/vnd.openxmlformats-package.relationships+xml" pkg:padding="256">
        <pkg:xmlData>
          <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
            <Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings" Target="webSettings.xml"/>
            <Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings" Target="settings.xml"/>
            <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>
            <Relationship Id="rId5" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme" Target="theme/theme1.xml"/>
            <Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable" Target="fontTable.xml"/>
          </Relationships>
        </pkg:xmlData>
      </pkg:part>
      <pkg:part pkg:name="/word/document.xml" pkg:contentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml">
        <pkg:xmlData>
          <w:document xmlns:ve="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml">
            <w:body>
              <w:p w:rsidR="00C507F1" w:rsidRDefault="000B50AA">
                <w:r>
                  <w:t>ABC</w:t>
                </w:r>
              </w:p>
              <w:sectPr w:rsidR="00C507F1" w:rsidSect="00262153">
                <w:pgSz w:w="12240" w:h="15840"/>
                <w:pgMar w:top="1440" w:right="1440" w:bottom="1440" w:left="1440" w:header="720" w:footer="720" w:gutter="0"/>
                <w:cols w:space="720"/>
                <w:docGrid w:linePitch="360"/>
              </w:sectPr>
            </w:body>
          </w:document>
        </pkg:xmlData>
      </pkg:part>
      <pkg:part pkg:name="/word/theme/theme1.xml" pkg:contentType="application/vnd.openxmlformats-officedocument.theme+xml">
        <pkg:xmlData>
          <a:theme name="Office Theme" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
            <a:themeElements>
              <a:clrScheme name="Office">
                <a:dk1>
                  <a:sysClr val="windowText" lastClr="000000"/>
                </a:dk1>
                <a:lt1>
                  <a:sysClr val="window" lastClr="FFFFFF"/>
                </a:lt1>
                <a:dk2>
                  <a:srgbClr val="1F497D"/>
                </a:dk2>
                <a:lt2>
                  <a:srgbClr val="EEECE1"/>
                </a:lt2>
                <a:accent1>
                  <a:srgbClr val="4F81BD"/>
                </a:accent1>
                <a:accent2>
                  <a:srgbClr val="C0504D"/>
                </a:accent2>
                <a:accent3>
                  <a:srgbClr val="9BBB59"/>
                </a:accent3>
                <a:accent4>
                  <a:srgbClr val="8064A2"/>
                </a:accent4>
                <a:accent5>
                  <a:srgbClr val="4BACC6"/>
                </a:accent5>
                <a:accent6>
                  <a:srgbClr val="F79646"/>
                </a:accent6>
                <a:hlink>
                  <a:srgbClr val="0000FF"/>
                </a:hlink>
                <a:folHlink>
                  <a:srgbClr val="800080"/>
                </a:folHlink>
              </a:clrScheme>
              <a:fontScheme name="Office">
                <a:majorFont>
                  <a:latin typeface="Cambria"/>
                  <a:ea typeface=""/>
                  <a:cs typeface=""/>
                  <a:font script="Jpan" typeface="MS ゴシック"/>
                  <a:font script="Hang" typeface="맑은 고딕"/>
                  <a:font script="Hans" typeface="宋体"/>
                  <a:font script="Hant" typeface="新細明體"/>
                  <a:font script="Arab" typeface="Times New Roman"/>
                  <a:font script="Hebr" typeface="Times New Roman"/>
                  <a:font script="Thai" typeface="Angsana New"/>
                  <a:font script="Ethi" typeface="Nyala"/>
                  <a:font script="Beng" typeface="Vrinda"/>
                  <a:font script="Gujr" typeface="Shruti"/>
                  <a:font script="Khmr" typeface="MoolBoran"/>
                  <a:font script="Knda" typeface="Tunga"/>
                  <a:font script="Guru" typeface="Raavi"/>
                  <a:font script="Cans" typeface="Euphemia"/>
                  <a:font script="Cher" typeface="Plantagenet Cherokee"/>
                  <a:font script="Yiii" typeface="Microsoft Yi Baiti"/>
                  <a:font script="Tibt" typeface="Microsoft Himalaya"/>
                  <a:font script="Thaa" typeface="MV Boli"/>
                  <a:font script="Deva" typeface="Mangal"/>
                  <a:font script="Telu" typeface="Gautami"/>
                  <a:font script="Taml" typeface="Latha"/>
                  <a:font script="Syrc" typeface="Estrangelo Edessa"/>
                  <a:font script="Orya" typeface="Kalinga"/>
                  <a:font script="Mlym" typeface="Kartika"/>
                  <a:font script="Laoo" typeface="DokChampa"/>
                  <a:font script="Sinh" typeface="Iskoola Pota"/>
                  <a:font script="Mong" typeface="Mongolian Baiti"/>
                  <a:font script="Viet" typeface="Times New Roman"/>
                  <a:font script="Uigh" typeface="Microsoft Uighur"/>
                </a:majorFont>
                <a:minorFont>
                  <a:latin typeface="Calibri"/>
                  <a:ea typeface=""/>
                  <a:cs typeface=""/>
                  <a:font script="Jpan" typeface="MS 明朝"/>
                  <a:font script="Hang" typeface="맑은 고딕"/>
                  <a:font script="Hans" typeface="宋体"/>
                  <a:font script="Hant" typeface="新細明體"/>
                  <a:font script="Arab" typeface="Arial"/>
                  <a:font script="Hebr" typeface="Arial"/>
                  <a:font script="Thai" typeface="Cordia New"/>
                  <a:font script="Ethi" typeface="Nyala"/>
                  <a:font script="Beng" typeface="Vrinda"/>
                  <a:font script="Gujr" typeface="Shruti"/>
                  <a:font script="Khmr" typeface="DaunPenh"/>
                  <a:font script="Knda" typeface="Tunga"/>
                  <a:font script="Guru" typeface="Raavi"/>
                  <a:font script="Cans" typeface="Euphemia"/>
                  <a:font script="Cher" typeface="Plantagenet Cherokee"/>
                  <a:font script="Yiii" typeface="Microsoft Yi Baiti"/>
                  <a:font script="Tibt" typeface="Microsoft Himalaya"/>
                  <a:font script="Thaa" typeface="MV Boli"/>
                  <a:font script="Deva" typeface="Mangal"/>
                  <a:font script="Telu" typeface="Gautami"/>
                  <a:font script="Taml" typeface="Latha"/>
                  <a:font script="Syrc" typeface="Estrangelo Edessa"/>
                  <a:font script="Orya" typeface="Kalinga"/>
                  <a:font script="Mlym" typeface="Kartika"/>
                  <a:font script="Laoo" typeface="DokChampa"/>
                  <a:font script="Sinh" typeface="Iskoola Pota"/>
                  <a:font script="Mong" typeface="Mongolian Baiti"/>
                  <a:font script="Viet" typeface="Arial"/>
                  <a:font script="Uigh" typeface="Microsoft Uighur"/>
                </a:minorFont>
              </a:fontScheme>
              <a:fmtScheme name="Office">
                <a:fillStyleLst>
                  <a:solidFill>
                    <a:schemeClr val="phClr"/>
                  </a:solidFill>
                  <a:gradFill rotWithShape="1">
                    <a:gsLst>
                      <a:gs pos="0">
                        <a:schemeClr val="phClr">
                          <a:tint val="50000"/>
                          <a:satMod val="300000"/>
                        </a:schemeClr>
                      </a:gs>
                      <a:gs pos="35000">
                        <a:schemeClr val="phClr">
                          <a:tint val="37000"/>
                          <a:satMod val="300000"/>
                        </a:schemeClr>
                      </a:gs>
                      <a:gs pos="100000">
                        <a:schemeClr val="phClr">
                          <a:tint val="15000"/>
                          <a:satMod val="350000"/>
                        </a:schemeClr>
                      </a:gs>
                    </a:gsLst>
                    <a:lin ang="16200000" scaled="1"/>
                  </a:gradFill>
                  <a:gradFill rotWithShape="1">
                    <a:gsLst>
                      <a:gs pos="0">
                        <a:schemeClr val="phClr">
                          <a:shade val="51000"/>
                          <a:satMod val="130000"/>
                        </a:schemeClr>
                      </a:gs>
                      <a:gs pos="80000">
                        <a:schemeClr val="phClr">
                          <a:shade val="93000"/>
                          <a:satMod val="130000"/>
                        </a:schemeClr>
                      </a:gs>
                      <a:gs pos="100000">
                        <a:schemeClr val="phClr">
                          <a:shade val="94000"/>
                          <a:satMod val="135000"/>
                        </a:schemeClr>
                      </a:gs>
                    </a:gsLst>
                    <a:lin ang="16200000" scaled="0"/>
                  </a:gradFill>
                </a:fillStyleLst>
                <a:lnStyleLst>
                  <a:ln w="9525" cap="flat" cmpd="sng" algn="ctr">
                    <a:solidFill>
                      <a:schemeClr val="phClr">
                        <a:shade val="95000"/>
                        <a:satMod val="105000"/>
                      </a:schemeClr>
                    </a:solidFill>
                    <a:prstDash val="solid"/>
                  </a:ln>
                  <a:ln w="25400" cap="flat" cmpd="sng" algn="ctr">
                    <a:solidFill>
                      <a:schemeClr val="phClr"/>
                    </a:solidFill>
                    <a:prstDash val="solid"/>
                  </a:ln>
                  <a:ln w="38100" cap="flat" cmpd="sng" algn="ctr">
                    <a:solidFill>
                      <a:schemeClr val="phClr"/>
                    </a:solidFill>
                    <a:prstDash val="solid"/>
                  </a:ln>
                </a:lnStyleLst>
                <a:effectStyleLst>
                  <a:effectStyle>
                    <a:effectLst>
                      <a:outerShdw blurRad="40000" dist="20000" dir="5400000" rotWithShape="0">
                        <a:srgbClr val="000000">
                          <a:alpha val="38000"/>
                        </a:srgbClr>
                      </a:outerShdw>
                    </a:effectLst>
                  </a:effectStyle>
                  <a:effectStyle>
                    <a:effectLst>
                      <a:outerShdw blurRad="40000" dist="23000" dir="5400000" rotWithShape="0">
                        <a:srgbClr val="000000">
                          <a:alpha val="35000"/>
                        </a:srgbClr>
                      </a:outerShdw>
                    </a:effectLst>
                  </a:effectStyle>
                  <a:effectStyle>
                    <a:effectLst>
                      <a:outerShdw blurRad="40000" dist="23000" dir="5400000" rotWithShape="0">
                        <a:srgbClr val="000000">
                          <a:alpha val="35000"/>
                        </a:srgbClr>
                      </a:outerShdw>
                    </a:effectLst>
                    <a:scene3d>
                      <a:camera prst="orthographicFront">
                        <a:rot lat="0" lon="0" rev="0"/>
                      </a:camera>
                      <a:lightRig rig="threePt" dir="t">
                        <a:rot lat="0" lon="0" rev="1200000"/>
                      </a:lightRig>
                    </a:scene3d>
                    <a:sp3d>
                      <a:bevelT w="63500" h="25400"/>
                    </a:sp3d>
                  </a:effectStyle>
                </a:effectStyleLst>
                <a:bgFillStyleLst>
                  <a:solidFill>
                    <a:schemeClr val="phClr"/>
                  </a:solidFill>
                  <a:gradFill rotWithShape="1">
                    <a:gsLst>
                      <a:gs pos="0">
                        <a:schemeClr val="phClr">
                          <a:tint val="40000"/>
                          <a:satMod val="350000"/>
                        </a:schemeClr>
                      </a:gs>
                      <a:gs pos="40000">
                        <a:schemeClr val="phClr">
                          <a:tint val="45000"/>
                          <a:shade val="99000"/>
                          <a:satMod val="350000"/>
                        </a:schemeClr>
                      </a:gs>
                      <a:gs pos="100000">
                        <a:schemeClr val="phClr">
                          <a:shade val="20000"/>
                          <a:satMod val="255000"/>
                        </a:schemeClr>
                      </a:gs>
                    </a:gsLst>
                    <a:path path="circle">
                      <a:fillToRect l="50000" t="-80000" r="50000" b="180000"/>
                    </a:path>
                  </a:gradFill>
                  <a:gradFill rotWithShape="1">
                    <a:gsLst>
                      <a:gs pos="0">
                        <a:schemeClr val="phClr">
                          <a:tint val="80000"/>
                          <a:satMod val="300000"/>
                        </a:schemeClr>
                      </a:gs>
                      <a:gs pos="100000">
                        <a:schemeClr val="phClr">
                          <a:shade val="30000"/>
                          <a:satMod val="200000"/>
                        </a:schemeClr>
                      </a:gs>
                    </a:gsLst>
                    <a:path path="circle">
                      <a:fillToRect l="50000" t="50000" r="50000" b="50000"/>
                    </a:path>
                  </a:gradFill>
                </a:bgFillStyleLst>
              </a:fmtScheme>
            </a:themeElements>
            <a:objectDefaults/>
            <a:extraClrSchemeLst/>
          </a:theme>
        </pkg:xmlData>
      </pkg:part>
      <pkg:part pkg:name="/word/settings.xml" pkg:contentType="application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml">
        <pkg:xmlData>
          <w:settings xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:sl="http://schemas.openxmlformats.org/schemaLibrary/2006/main">
            <w:zoom w:percent="100"/>
            <w:defaultTabStop w:val="720"/>
            <w:characterSpacingControl w:val="doNotCompress"/>
            <w:compat>
              <w:useFELayout/>
            </w:compat>
            <w:rsids>
              <w:rsidRoot w:val="000B50AA"/>
              <w:rsid w:val="000B50AA"/>
              <w:rsid w:val="000E30D5"/>
              <w:rsid w:val="00262153"/>
              <w:rsid w:val="00C507F1"/>
            </w:rsids>
            <m:mathPr>
              <m:mathFont m:val="Cambria Math"/>
              <m:brkBin m:val="before"/>
              <m:brkBinSub m:val="--"/>
              <m:smallFrac m:val="off"/>
              <m:dispDef/>
              <m:lMargin m:val="0"/>
              <m:rMargin m:val="0"/>
              <m:defJc m:val="centerGroup"/>
              <m:wrapIndent m:val="1440"/>
              <m:intLim m:val="subSup"/>
              <m:naryLim m:val="undOvr"/>
            </m:mathPr>
            <w:themeFontLang w:val="en-US"/>
            <w:clrSchemeMapping w:bg1="light1" w:t1="dark1" w:bg2="light2" w:t2="dark2" w:accent1="accent1" w:accent2="accent2" w:accent3="accent3" w:accent4="accent4" w:accent5="accent5" w:accent6="accent6" w:hyperlink="hyperlink" w:followedHyperlink="followedHyperlink"/>
            <w:shapeDefaults>
              <o:shapedefaults v:ext="edit" spidmax="3074"/>
              <o:shapelayout v:ext="edit">
                <o:idmap v:ext="edit" data="1"/>
              </o:shapelayout>
            </w:shapeDefaults>
            <w:decimalSymbol w:val="."/>
            <w:listSeparator w:val=","/>
          </w:settings>
        </pkg:xmlData>
      </pkg:part>
      <pkg:part pkg:name="/word/fontTable.xml" pkg:contentType="application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml">
        <pkg:xmlData>
          <w:fonts xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
            <w:font w:name="Calibri">
              <w:panose1 w:val="020F0502020204030204"/>
              <w:charset w:val="00"/>
              <w:family w:val="swiss"/>
              <w:pitch w:val="variable"/>
              <w:sig w:usb0="A00002EF" w:usb1="4000207B" w:usb2="00000000" w:usb3="00000000" w:csb0="0000009F" w:csb1="00000000"/>
            </w:font>
            <w:font w:name="Times New Roman">
              <w:panose1 w:val="02020603050405020304"/>
              <w:charset w:val="00"/>
              <w:family w:val="roman"/>
              <w:pitch w:val="variable"/>
              <w:sig w:usb0="20002A87" w:usb1="80000000" w:usb2="00000008" w:usb3="00000000" w:csb0="000001FF" w:csb1="00000000"/>
            </w:font>
            <w:font w:name="Cambria">
              <w:panose1 w:val="02040503050406030204"/>
              <w:charset w:val="00"/>
              <w:family w:val="roman"/>
              <w:pitch w:val="variable"/>
              <w:sig w:usb0="A00002EF" w:usb1="4000004B" w:usb2="00000000" w:usb3="00000000" w:csb0="0000009F" w:csb1="00000000"/>
            </w:font>
          </w:fonts>
        </pkg:xmlData>
      </pkg:part>
      <pkg:part pkg:name="/word/webSettings.xml" pkg:contentType="application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml">
        <pkg:xmlData>
          <w:webSettings xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
            <w:optimizeForBrowser/>
          </w:webSettings>
        </pkg:xmlData>
      </pkg:part>
      <pkg:part pkg:name="/docProps/app.xml" pkg:contentType="application/vnd.openxmlformats-officedocument.extended-properties+xml" pkg:padding="256">
        <pkg:xmlData>
          <Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes">
            <Template>Normal.dotm</Template>
            <TotalTime>0</TotalTime>
            <Pages>1</Pages>
            <Words>0</Words>
            <Characters>3</Characters>
            <Application>Microsoft Office Word</Application>
            <DocSecurity>0</DocSecurity>
            <Lines>1</Lines>
            <Paragraphs>1</Paragraphs>
            <ScaleCrop>false</ScaleCrop>
            <Company>Microsoft</Company>
            <LinksUpToDate>false</LinksUpToDate>
            <CharactersWithSpaces>3</CharactersWithSpaces>
            <SharedDoc>false</SharedDoc>
            <HyperlinksChanged>false</HyperlinksChanged>
            <AppVersion>12.0000</AppVersion>
          </Properties>
        </pkg:xmlData>
      </pkg:part>
      <pkg:part pkg:name="/docProps/core.xml" pkg:contentType="application/vnd.openxmlformats-package.core-properties+xml" pkg:padding="256">
        <pkg:xmlData>
          <cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:dcmitype="http://purl.org/dc/dcmitype/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <dc:title/>
            <dc:subject/>
            <dc:creator>Manjunath Khatawkar</dc:creator>
            <cp:keywords/>
            <dc:description/>
            <cp:lastModifiedBy>Manjunath Khatawkar</cp:lastModifiedBy>
            <cp:revision>2</cp:revision>
            <dcterms:created xsi:type="dcterms:W3CDTF">2008-05-06T17:59:00Z</dcterms:created>
            <dcterms:modified xsi:type="dcterms:W3CDTF">2008-05-06T17:59:00Z</dcterms:modified>
          </cp:coreProperties>
        </pkg:xmlData>
      </pkg:part>
      <pkg:part pkg:name="/word/styles.xml" pkg:contentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml">
        <pkg:xmlData>
          <w:styles xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
            <w:docDefaults>
              <w:rPrDefault>
                <w:rPr>
                  <w:rFonts w:asciiTheme="minorHAnsi" w:eastAsiaTheme="minorEastAsia" w:hAnsiTheme="minorHAnsi" w:cstheme="minorBidi"/>
                  <w:sz w:val="22"/>
                  <w:szCs w:val="22"/>
                  <w:lang w:val="en-US" w:eastAsia="en-US" w:bidi="ar-SA"/>
                </w:rPr>
              </w:rPrDefault>
              <w:pPrDefault>
                <w:pPr>
                  <w:spacing w:after="200" w:line="276" w:lineRule="auto"/>
                </w:pPr>
              </w:pPrDefault>
            </w:docDefaults>
            <w:latentStyles w:defLockedState="0" w:defUIPriority="99" w:defSemiHidden="1" w:defUnhideWhenUsed="1" w:defQFormat="0" w:count="267">
              <w:lsdException w:name="Normal" w:semiHidden="0" w:uiPriority="0" w:unhideWhenUsed="0" w:qFormat="1"/>
              <w:lsdException w:name="heading 1" w:semiHidden="0" w:uiPriority="9" w:unhideWhenUsed="0" w:qFormat="1"/>
              <w:lsdException w:name="heading 2" w:uiPriority="9" w:qFormat="1"/>
              <w:lsdException w:name="heading 3" w:uiPriority="9" w:qFormat="1"/>
              <w:lsdException w:name="heading 4" w:uiPriority="9" w:qFormat="1"/>
              <w:lsdException w:name="heading 5" w:uiPriority="9" w:qFormat="1"/>
              <w:lsdException w:name="heading 6" w:uiPriority="9" w:qFormat="1"/>
              <w:lsdException w:name="heading 7" w:uiPriority="9" w:qFormat="1"/>
              <w:lsdException w:name="heading 8" w:uiPriority="9" w:qFormat="1"/>
              <w:lsdException w:name="heading 9" w:uiPriority="9" w:qFormat="1"/>
              <w:lsdException w:name="toc 1" w:uiPriority="39"/>
              <w:lsdException w:name="toc 2" w:uiPriority="39"/>
              <w:lsdException w:name="toc 3" w:uiPriority="39"/>
              <w:lsdException w:name="toc 4" w:uiPriority="39"/>
              <w:lsdException w:name="toc 5" w:uiPriority="39"/>
              <w:lsdException w:name="toc 6" w:uiPriority="39"/>
              <w:lsdException w:name="toc 7" w:uiPriority="39"/>
              <w:lsdException w:name="toc 8" w:uiPriority="39"/>
              <w:lsdException w:name="toc 9" w:uiPriority="39"/>
              <w:lsdException w:name="caption" w:uiPriority="35" w:qFormat="1"/>
              <w:lsdException w:name="Title" w:semiHidden="0" w:uiPriority="10" w:unhideWhenUsed="0" w:qFormat="1"/>
              <w:lsdException w:name="Default Paragraph Font" w:uiPriority="1"/>
              <w:lsdException w:name="Subtitle" w:semiHidden="0" w:uiPriority="11" w:unhideWhenUsed="0" w:qFormat="1"/>
              <w:lsdException w:name="Strong" w:semiHidden="0" w:uiPriority="22" w:unhideWhenUsed="0" w:qFormat="1"/>
              <w:lsdException w:name="Emphasis" w:semiHidden="0" w:uiPriority="20" w:unhideWhenUsed="0" w:qFormat="1"/>
              <w:lsdException w:name="Table Grid" w:semiHidden="0" w:uiPriority="59" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Placeholder Text" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="No Spacing" w:semiHidden="0" w:uiPriority="1" w:unhideWhenUsed="0" w:qFormat="1"/>
              <w:lsdException w:name="Light Shading" w:semiHidden="0" w:uiPriority="60" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Light List" w:semiHidden="0" w:uiPriority="61" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Light Grid" w:semiHidden="0" w:uiPriority="62" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium Shading 1" w:semiHidden="0" w:uiPriority="63" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium Shading 2" w:semiHidden="0" w:uiPriority="64" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium List 1" w:semiHidden="0" w:uiPriority="65" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium List 2" w:semiHidden="0" w:uiPriority="66" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium Grid 1" w:semiHidden="0" w:uiPriority="67" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium Grid 2" w:semiHidden="0" w:uiPriority="68" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium Grid 3" w:semiHidden="0" w:uiPriority="69" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Dark List" w:semiHidden="0" w:uiPriority="70" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Colorful Shading" w:semiHidden="0" w:uiPriority="71" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Colorful List" w:semiHidden="0" w:uiPriority="72" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Colorful Grid" w:semiHidden="0" w:uiPriority="73" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Light Shading Accent 1" w:semiHidden="0" w:uiPriority="60" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Light List Accent 1" w:semiHidden="0" w:uiPriority="61" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Light Grid Accent 1" w:semiHidden="0" w:uiPriority="62" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium Shading 1 Accent 1" w:semiHidden="0" w:uiPriority="63" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium Shading 2 Accent 1" w:semiHidden="0" w:uiPriority="64" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium List 1 Accent 1" w:semiHidden="0" w:uiPriority="65" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Revision" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="List Paragraph" w:semiHidden="0" w:uiPriority="34" w:unhideWhenUsed="0" w:qFormat="1"/>
              <w:lsdException w:name="Quote" w:semiHidden="0" w:uiPriority="29" w:unhideWhenUsed="0" w:qFormat="1"/>
              <w:lsdException w:name="Intense Quote" w:semiHidden="0" w:uiPriority="30" w:unhideWhenUsed="0" w:qFormat="1"/>
              <w:lsdException w:name="Medium List 2 Accent 1" w:semiHidden="0" w:uiPriority="66" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium Grid 1 Accent 1" w:semiHidden="0" w:uiPriority="67" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium Grid 2 Accent 1" w:semiHidden="0" w:uiPriority="68" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium Grid 3 Accent 1" w:semiHidden="0" w:uiPriority="69" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Dark List Accent 1" w:semiHidden="0" w:uiPriority="70" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Colorful Shading Accent 1" w:semiHidden="0" w:uiPriority="71" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Colorful List Accent 1" w:semiHidden="0" w:uiPriority="72" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Colorful Grid Accent 1" w:semiHidden="0" w:uiPriority="73" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Light Shading Accent 2" w:semiHidden="0" w:uiPriority="60" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Light List Accent 2" w:semiHidden="0" w:uiPriority="61" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Light Grid Accent 2" w:semiHidden="0" w:uiPriority="62" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium Shading 1 Accent 2" w:semiHidden="0" w:uiPriority="63" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium Shading 2 Accent 2" w:semiHidden="0" w:uiPriority="64" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium List 1 Accent 2" w:semiHidden="0" w:uiPriority="65" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium List 2 Accent 2" w:semiHidden="0" w:uiPriority="66" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium Grid 1 Accent 2" w:semiHidden="0" w:uiPriority="67" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium Grid 2 Accent 2" w:semiHidden="0" w:uiPriority="68" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium Grid 3 Accent 2" w:semiHidden="0" w:uiPriority="69" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Dark List Accent 2" w:semiHidden="0" w:uiPriority="70" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Colorful Shading Accent 2" w:semiHidden="0" w:uiPriority="71" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Colorful List Accent 2" w:semiHidden="0" w:uiPriority="72" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Colorful Grid Accent 2" w:semiHidden="0" w:uiPriority="73" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Light Shading Accent 3" w:semiHidden="0" w:uiPriority="60" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Light List Accent 3" w:semiHidden="0" w:uiPriority="61" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Light Grid Accent 3" w:semiHidden="0" w:uiPriority="62" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium Shading 1 Accent 3" w:semiHidden="0" w:uiPriority="63" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium Shading 2 Accent 3" w:semiHidden="0" w:uiPriority="64" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium List 1 Accent 3" w:semiHidden="0" w:uiPriority="65" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium List 2 Accent 3" w:semiHidden="0" w:uiPriority="66" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium Grid 1 Accent 3" w:semiHidden="0" w:uiPriority="67" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium Grid 2 Accent 3" w:semiHidden="0" w:uiPriority="68" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium Grid 3 Accent 3" w:semiHidden="0" w:uiPriority="69" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Dark List Accent 3" w:semiHidden="0" w:uiPriority="70" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Colorful Shading Accent 3" w:semiHidden="0" w:uiPriority="71" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Colorful List Accent 3" w:semiHidden="0" w:uiPriority="72" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Colorful Grid Accent 3" w:semiHidden="0" w:uiPriority="73" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Light Shading Accent 4" w:semiHidden="0" w:uiPriority="60" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Light List Accent 4" w:semiHidden="0" w:uiPriority="61" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Light Grid Accent 4" w:semiHidden="0" w:uiPriority="62" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium Shading 1 Accent 4" w:semiHidden="0" w:uiPriority="63" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium Shading 2 Accent 4" w:semiHidden="0" w:uiPriority="64" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium List 1 Accent 4" w:semiHidden="0" w:uiPriority="65" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium List 2 Accent 4" w:semiHidden="0" w:uiPriority="66" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium Grid 1 Accent 4" w:semiHidden="0" w:uiPriority="67" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium Grid 2 Accent 4" w:semiHidden="0" w:uiPriority="68" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium Grid 3 Accent 4" w:semiHidden="0" w:uiPriority="69" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Dark List Accent 4" w:semiHidden="0" w:uiPriority="70" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Colorful Shading Accent 4" w:semiHidden="0" w:uiPriority="71" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Colorful List Accent 4" w:semiHidden="0" w:uiPriority="72" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Colorful Grid Accent 4" w:semiHidden="0" w:uiPriority="73" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Light Shading Accent 5" w:semiHidden="0" w:uiPriority="60" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Light List Accent 5" w:semiHidden="0" w:uiPriority="61" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Light Grid Accent 5" w:semiHidden="0" w:uiPriority="62" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium Shading 1 Accent 5" w:semiHidden="0" w:uiPriority="63" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium Shading 2 Accent 5" w:semiHidden="0" w:uiPriority="64" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium List 1 Accent 5" w:semiHidden="0" w:uiPriority="65" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium List 2 Accent 5" w:semiHidden="0" w:uiPriority="66" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium Grid 1 Accent 5" w:semiHidden="0" w:uiPriority="67" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium Grid 2 Accent 5" w:semiHidden="0" w:uiPriority="68" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium Grid 3 Accent 5" w:semiHidden="0" w:uiPriority="69" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Dark List Accent 5" w:semiHidden="0" w:uiPriority="70" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Colorful Shading Accent 5" w:semiHidden="0" w:uiPriority="71" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Colorful List Accent 5" w:semiHidden="0" w:uiPriority="72" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Colorful Grid Accent 5" w:semiHidden="0" w:uiPriority="73" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Light Shading Accent 6" w:semiHidden="0" w:uiPriority="60" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Light List Accent 6" w:semiHidden="0" w:uiPriority="61" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Light Grid Accent 6" w:semiHidden="0" w:uiPriority="62" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium Shading 1 Accent 6" w:semiHidden="0" w:uiPriority="63" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium Shading 2 Accent 6" w:semiHidden="0" w:uiPriority="64" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium List 1 Accent 6" w:semiHidden="0" w:uiPriority="65" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium List 2 Accent 6" w:semiHidden="0" w:uiPriority="66" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium Grid 1 Accent 6" w:semiHidden="0" w:uiPriority="67" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium Grid 2 Accent 6" w:semiHidden="0" w:uiPriority="68" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Medium Grid 3 Accent 6" w:semiHidden="0" w:uiPriority="69" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Dark List Accent 6" w:semiHidden="0" w:uiPriority="70" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Colorful Shading Accent 6" w:semiHidden="0" w:uiPriority="71" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Colorful List Accent 6" w:semiHidden="0" w:uiPriority="72" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Colorful Grid Accent 6" w:semiHidden="0" w:uiPriority="73" w:unhideWhenUsed="0"/>
              <w:lsdException w:name="Subtle Emphasis" w:semiHidden="0" w:uiPriority="19" w:unhideWhenUsed="0" w:qFormat="1"/>
              <w:lsdException w:name="Intense Emphasis" w:semiHidden="0" w:uiPriority="21" w:unhideWhenUsed="0" w:qFormat="1"/>
              <w:lsdException w:name="Subtle Reference" w:semiHidden="0" w:uiPriority="31" w:unhideWhenUsed="0" w:qFormat="1"/>
              <w:lsdException w:name="Intense Reference" w:semiHidden="0" w:uiPriority="32" w:unhideWhenUsed="0" w:qFormat="1"/>
              <w:lsdException w:name="Book Title" w:semiHidden="0" w:uiPriority="33" w:unhideWhenUsed="0" w:qFormat="1"/>
              <w:lsdException w:name="Bibliography" w:uiPriority="37"/>
              <w:lsdException w:name="TOC Heading" w:uiPriority="39" w:qFormat="1"/>
            </w:latentStyles>
            <w:style w:type="paragraph" w:default="1" w:styleId="Normal">
              <w:name w:val="Normal"/>
              <w:qFormat/>
              <w:rsid w:val="00262153"/>
            </w:style>
            <w:style w:type="character" w:default="1" w:styleId="DefaultParagraphFont">
              <w:name w:val="Default Paragraph Font"/>
              <w:uiPriority w:val="1"/>
              <w:semiHidden/>
              <w:unhideWhenUsed/>
            </w:style>
            <w:style w:type="table" w:default="1" w:styleId="TableNormal">
              <w:name w:val="Normal Table"/>
              <w:uiPriority w:val="99"/>
              <w:semiHidden/>
              <w:unhideWhenUsed/>
              <w:qFormat/>
              <w:tblPr>
                <w:tblInd w:w="0" w:type="dxa"/>
                <w:tblCellMar>
                  <w:top w:w="0" w:type="dxa"/>
                  <w:left w:w="108" w:type="dxa"/>
                  <w:bottom w:w="0" w:type="dxa"/>
                  <w:right w:w="108" w:type="dxa"/>
                </w:tblCellMar>
              </w:tblPr>
            </w:style>
            <w:style w:type="numbering" w:default="1" w:styleId="NoList">
              <w:name w:val="No List"/>
              <w:uiPriority w:val="99"/>
              <w:semiHidden/>
              <w:unhideWhenUsed/>
            </w:style>
          </w:styles>
        </pkg:xmlData>
      </pkg:part>
    </pkg:package>

     

    This is beautiful man! all the parts and relationships clubbed nicely in one XML file!

    While I was still looking and appreciating the beauty of this design decision, Manju already fought his way to create a actual package by parsing this file and sent me the code snippet -

    XPathDocument xpathDocument = new XPathDocument(new StringReader(openXml));
                XPathNavigator navigator = xpathDocument.CreateNavigator();
    
                XmlNamespaceManager namespaceManager = GetContentControlNamespaceManager(navigator);
                XPathNodeIterator iterator = navigator.Select("//pkg:part", namespaceManager);
    
                Package pkg = Package.Open(Environment.CurrentDirectory + @"/abc.docx", FileMode.Create);
    
                while (iterator.MoveNext())
                {
                    Uri partUri = new Uri(iterator.Current.GetAttribute("name", "http://schemas.microsoft.com/office/2006/xmlPackage"), UriKind.Relative);
    
                    if (pkg.PartExists(partUri))
                        pkg.DeletePart(partUri);
    
                    PackagePart part = pkg.CreatePart(
                                        partUri
                                        , iterator.Current.GetAttribute("contentType", "http://schemas.microsoft.com/office/2006/xmlPackage"));
    
                    string a = iterator.Current.InnerXml
                        .Replace("<pkg:xmlData xmlns:pkg=\"http://schemas.microsoft.com/office/2006/xmlPackage\">", "")
                        .Replace(@"</pkg:xmlData>", "");
                    byte[] buffer = Encoding.UTF8.GetBytes(a);
                    part.GetStream().Write(buffer, 0, buffer.Length);
                }
    
                
                pkg.Flush();

    Good one, can be done in a few more ways – but this worked for manju, You can use it as well. In the next part, I’ll try to do the opposite, create this XML file from the Package, without automation.

    Test for you – do you think you can easily write code for converting the sample in previous post to match Word XML file format?

     



     

    Not responsible for errors in content, meaning, tact, or judgment. Live and let live. Toes go in first. I didn't do it. Enjoy.

  • Pranav ... Blogging

    Open XML for primary school goers

    • 3 Comments

    Ok ..I agree! I was not a simple-sober-studious-obedient-goodie-good student.

    I do remember when I was a primary school goer, whenever me or any of my friends wanted a leave, we almost always used the same letter template, just modifying a few fields.

    Yesterday, I was thinking about this. While working on an Open XML issue and thought of creating a sample which primary school goers can use to generate application templates.

    This sample just takes the fields that you are finally going to modify and creates the application docx for you. Oh .. well it will also demonstrate how to modify CustomXML attached to a docx file.

     

    Here is it. Have fun -

     

     

    Imports System.IO
    Imports System.IO.Packaging
    Imports System.Xml
    Public Class AddFields

    Private Sub Cancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Cancel.Click
    Me.Close()
    End Sub

    Private Sub OK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OK.Click
    Dim fieldscollection As New Collection
    fieldscollection.Add(AddressTo.Text, "AddressTo")
    fieldscollection.Add(Place.Text, "Place")
    fieldscollection.Add(Teacher.Text, "Teacher")
    fieldscollection.Add(Sickness.Text, "Sickness")
    fieldscollection.Add(TimeFrame.Text, "TimeFrame")
    fieldscollection.Add(Days.Text, "Days")
    fieldscollection.Add(StudentName.Text, "StudentName")
    fieldscollection.Add(Dated.Text, "Dated")
    UpdateXML(fieldscollection)

    End Sub

    Public Sub UpdateXML(ByRef fs As Collection)

    ' Given a file name, retrieve the officeDocument part.
    Dim fileName As String = "C:\Users\username\Desktop\test\application.docx"

    Const documentRelationshipType As String = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"
    Const customRelationshipType As String = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml"

    ' Open the package with read/write access.
    Using myPackage As Package = Package.Open(fileName, FileMode.Open, FileAccess.ReadWrite)
    ' Get the main document part (workbook.xml, document.xml, presentation.xml).
    For Each relationship As PackageRelationship In myPackage.GetRelationshipsByType(documentRelationshipType)
    ' There should only be one document part in the package.
    Dim documentUri As Uri = PackUriHelper.ResolvePartUri(New Uri("/", UriKind.Relative), relationship.TargetUri)
    Dim documentPart As PackagePart = myPackage.GetPart(documentUri)
    Dim customPart As PackagePart = Nothing 'declare a custom part
    'Get the custom xml part
    For Each crelation As PackageRelationship In documentPart.GetRelationshipsByType(customRelationshipType)
    'There should be only one customxml part in the package
    Dim customUri As Uri = PackUriHelper.ResolvePartUri(New Uri("/", UriKind.Relative), crelation.TargetUri)
    customPart = myPackage.GetPart(customUri)
    Exit For
    Next

    Dim customDoc As XmlDocument = New XmlDocument()
    customDoc.Load(customPart.GetStream())
    'Update XML
    customDoc.SelectSingleNode("/root/addressto").InnerXml = fs.Item("AddressTo")
    customDoc.SelectSingleNode("/root/place").InnerXml = fs.Item("Place")
    customDoc.SelectSingleNode("/root/teacher").InnerXml = fs.Item("Teacher")
    customDoc.SelectSingleNode("/root/sickness").InnerXml = fs.Item("Sickness")
    customDoc.SelectSingleNode("/root/timeframe").InnerXml = fs.Item("TimeFrame")
    customDoc.SelectSingleNode("/root/days").InnerXml = fs.Item("Days")
    customDoc.SelectSingleNode("/root/name").InnerXml = fs.Item("StudentName")
    customDoc.SelectSingleNode("/root/date").InnerXml = fs.Item("Dated")


    ' Save the modified customxml back into its part.
    customDoc.Save(customPart.GetStream(FileMode.Create, FileAccess.ReadWrite))


    ' Only one customXML part, so get out now.
    Exit For
    Next
    myPackage.Flush()
    myPackage.Close()
    End Using
    MsgBox("Done!")
    End Sub


    End Class

     

    docx that it modifies is also attached to the post.

     

     


     

    Not responsible for errors in content, meaning, tact, or judgment. Live and let live. Toes go in first. I didn't do it. Enjoy.

  • Pranav ... Blogging

    Creating a Open XML PowerPoint presentation from scratch using System.IO.Packaging

    • 3 Comments

    Here is how I’ve got to create this sample – One of my customer had a similar requirement when I tried to search a sample for him to demonstrate, I couldn’t find one (blame it on my searching capabilities or whatever .. )

    While creating a sample there are a few titbits that I came to know -

    1)  In order to create a valid presentation you’ve got to have following parts - presentation, slide, slideLayout, slideMaster and theme

    2) By default when you create a package using Packaging API it’s NOT compressed. To have a compressed package you need to specify compression option in CreatePart. Something like this   …

    Dim pPart As PackagePart = p.CreatePart(pURI, contentType,CompressionOption.Fast)
    'or
    Dim pPart As PackagePart = p.CreatePart(pURI, contentType,CompressionOption.Maximum)
    'or
    Dim pPart As PackagePart = p.CreatePart(pURI, contentType,CompressionOption.Normal)
    'or
    Dim pPart As PackagePart = p.CreatePart(pURI, contentType,CompressionOption.NotCompressed)
    'or
    Dim pPart As PackagePart = p.CreatePart(pURI, contentType,CompressionOption.SuperFast)

     

    The real fun part here is – you can have different parts compressed in different CompressionOption (that implies that I can have a few parts compressed and a few parts uncompressed!) – well at least this is what my testing says.

    Here is the code snippet (the code is dependent on a few xmlfiles which are attached as a zip)-

     

    Public Class Form1

    #Region "NamespaceConstants"
    Private Structure constants
    Dim dummy
    Shared presentationmlNamespace As String = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"
    Shared relationshipNamespace As String = "http://schemas.openxmlformats.org/officeDocument/2006/relationships"
    Shared corePropertiesSchema As String = "http://schemas.openxmlformats.org/package/2006/metadata/core-properties"
    Shared docPropsVTypes As String = "http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"
    Shared slidePartNamespace As String = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide"
    Shared appPartNamespace As String = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties"
    Shared themePartNamespace As String = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme"
    Shared slidelayoutNamespace As String = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout"
    Shared slidemasterNamespace As String = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster"
    Shared mainpartNamespace As String = "http://schemas.openxmlformats.org/presentationml/2006/main"

    Shared mainPartContentType As String = "application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml"
    Shared slidePartContentType As String = "application/vnd.openxmlformats-officedocument.presentationml.slide+xml"
    Shared slideLayoutContentType As String = "application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"
    Shared appPartContentType As String = "application/vnd.openxmlformats-officedocument.extended-properties+xml"
    Shared corePartContentType As String = "application/vnd.openxmlformats-package.core-properties+xml"
    Shared themePartContentType As String = "application/vnd.openxmlformats-officedocument.theme+xml"
    Shared slidemasterContentType As String = "application/vnd.openxmlformats-officedocument.presentationml.slideMaster+xml"

    End Structure


    #End Region


    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    Using myPackage As Package = Package.Open("C:\somepath\GuineaPig.pptx", FileMode.Create, FileAccess.ReadWrite, FileShare.None)




    'Add package parts app,core and doc
    Dim docPart As PackagePart = CreateBasicPart(New StreamReader("C:\somepath\presentation.xml").BaseStream, myPackage, "ppt/presentation.xml", constants.mainPartContentType, constants.presentationmlNamespace)
    'end add


    'add other *required* parts slide,slidemaster,theme,slidelayout
    '
    Dim pp() As PackagePart

    'add slide part

    pp = New PackagePart() {docPart}
    Dim slidePart As PackagePart = CreateExtendedPart(myPackage, "C:\somepath\slide1.xml", "ppt/slides/slide1.xml", constants.slidePartContentType, constants.slidePartNamespace, pp)
    AdjustPartXML("//p:sldIdLst/p:sldId/@r:id", docPart, constants.slidePartNamespace)

    'end add slide part

    'add theme part

    pp = New PackagePart() {docPart}
    Dim themePart As PackagePart = CreateExtendedPart(myPackage, "C:\somepath\theme1.xml", "ppt/theme/theme1.xml", constants.themePartContentType, constants.themePartNamespace, pp)
    'end add theme part

    'add slide layout part
    pp = New PackagePart() {slidePart}
    Dim slidelayoutPart As PackagePart = CreateExtendedPart(myPackage, "C:\somepath\slidelayout1.xml", "ppt/slideLayouts/slideLayout1.xml", constants.slideLayoutContentType, constants.slidelayoutNamespace, pp)
    'end add slide layout part

    'add slide layout part
    pp = New PackagePart() {docPart, slidelayoutPart}
    Dim slidemasterPart As PackagePart = CreateExtendedPart(myPackage, "C:\somepath\slidemaster1.xml", "ppt/slideMasters/slideMaster1.xml", constants.slidemasterContentType, constants.slidemasterNamespace, pp)
    AdjustPartXML("//p:sldMasterIdLst/p:sldMasterId/@r:id", docPart, constants.slidemasterNamespace)
    'end add slide layout part

    'add other *required* parts slide,slidemaster,theme,slidelayout

    'add other relationships
    AddRelationship(slidemasterPart, themePart, constants.themePartNamespace)
    AddRelationship(slidemasterPart, slidelayoutPart, constants.slidelayoutNamespace)
    AdjustPartXML("//p:sldLayoutIdLst/p:sldLayoutId/@r:id", slidemasterPart, constants.slidelayoutNamespace)
    'end add other relationships


    End Using


    Me.Close()
    End Sub
    Public Sub AdjustPartXML(ByVal xpath As String, ByVal p As PackagePart, ByVal relationship As String)
    Dim nt As New NameTable
    Dim nsManager As New XmlNamespaceManager(nt)
    nsManager.AddNamespace("p", constants.mainpartNamespace)
    nsManager.AddNamespace("r", constants.relationshipNamespace)
    Dim adoc As New XmlDocument(nt)

    adoc.Load(p.GetStream())
    If Not IsNothing(adoc.SelectSingleNode(xpath, nsManager)) Then
    For Each r As PackageRelationship In p.GetRelationshipsByType(relationship)
    adoc.SelectSingleNode(xpath, nsManager).Value = r.Id
    adoc.Save(p.GetStream(FileMode.Create, FileAccess.ReadWrite))
    Next r
    End If
    End Sub
    Private Sub AddRelationship(ByVal frompart As PackagePart, ByVal topart As PackagePart, ByVal relationship As String)
    frompart.CreateRelationship(topart.Uri, TargetMode.Internal, relationship)
    End Sub
    Private Function CreateExtendedPart(ByVal p As Package, ByVal filename As String, ByVal uri As String, ByVal contenttype As String, ByVal relationship As String, ByVal relatewith() As PackagePart) As PackagePart
    Dim xmlDoc As New XmlDocument, xmlFile As New XmlDocument

    Dim pURI As Uri = PackUriHelper.CreatePartUri(New Uri(uri, UriKind.Relative))
    Dim pPart As PackagePart = p.CreatePart(pURI, contenttype)


    For Each pp As PackagePart In relatewith
    pp.CreateRelationship(pPart.Uri, TargetMode.Internal, relationship)
    Next

    xmlDoc.Load(filename)
    xmlDoc.Save(pPart.GetStream(FileMode.Create, FileAccess.Write))
    xmlDoc = Nothing
    Return pPart
    End Function


    Private Function CreateBasicPart(ByVal fileStream As Stream, ByVal pptPackage As Package, ByVal uri As String, ByVal contentType As String, ByVal relType As String) As PackagePart

    Dim documentUri As Uri = PackUriHelper.CreatePartUri(New Uri(uri, UriKind.Relative))

    Dim documentPart As PackagePart = pptPackage.CreatePart(documentUri, contentType)

    pptPackage.CreateRelationship(documentPart.Uri, TargetMode.Internal, relType)

    Dim xmlDoc As New XmlDocument

    xmlDoc.Load(fileStream)
    xmlDoc.Save(documentPart.GetStream(FileMode.Create, FileAccess.Write))


    Return documentPart
    End Function


    End Class

     

    Never mind my naming conventions or using structure as a hack – look at the juice :)

    By the way – when you work with Open XML one of the great help is sample documents from OpenXMLDeveloper

    Whenever I get more time, I’ll expand this code snippet in a more or less generic sample. Keep watching

     



     

    Not responsible for errors in content, meaning, tact, or judgment. Live and let live. Toes go in first. I didn't do it. Enjoy.

  • Pranav ... Blogging

    Couple of issues in PowerPoint 2007

    • 3 Comments

    One of my customer reported a couple of very interesting issues (bugs?) in PowerPoint 2007.

    If you have a presentation which has a shape with a gradient and you try to find out the color of each gradient using GradientStops.Color.RGB from .NET, you might get incorrect results. You can also reproduce this issue from VBA with the following steps.

    1) Create a new presentation with a single slide.
    2) Delete textboxes and anything else that's present on the slide.
    3) Click on Insert->Shapes, select rectangle.
    4) Right click on the shape, select "Format Shape"
    5) Click on gradient fill and click close.
    6) Hit Alt+F11 to go to VBA editer, if immediate window is not visible, hit Ctrl+G to make it visible.
    7) If watch window is not visible make it visible by clicking on View -> "Watch window"
    8) Now, in the immediate window try "?Application.ActivePresentation.Slides(1).Shapes(1).Fill.GradientStops(1).Color"
    9) Try this for all the gradients, YOU WILL GET DIFFERENT VALUES - EXPECTED RESULT
    10) Drag-n-Drop "Application.ActivePresentation.Slides(1).Shapes(1).Fill.GradientStops(1).Color" to the watch window (note:don't select "?" while drag-drop)
    11) Modify the immediate window to "?Application.ActivePresentation.Slides(1).Shapes(1).Fill.GradientStops(2).Color" (changed 1 to 2)
    12) Now drag-drop this statement (except "?") to watch window.
    13) Do this for all the gradients, YOU WILL SEE SAME VALUE FOR ALL THE GRADIENTS - UNEXPECTED
    14) Now, try steps (8) and (9) again, this time YOU WILL SEE SAME VALUE FOR ALL THE GRADIENTS - UNEXPECTED


    The same issue also reproduces with "RulerLevels" collection

    After some troubleshooting I found out that using Application.ActivePresentation.Slides(n).Shapes(n).Fill.GradientStops(n).Color.RGB gives correct values when you use it from VBA macro.

    Well , after finding this, I did the obvious fwd these issues to the bug database and the so that the concerned teams can take it from here (dev/test etc.)

    Now,  what can you do right now, especially  if you are programming in .NET. How does this finding helps you? It does, if you don't mind a bit patchy solution (Okay .. a workaround if I must say ). You can simply put a small macro in an PPA or PPAM addin (something like ...)

    Public Function getGradientStopColor(ByVal iSlide As Integer, ByVal iShape As Integer, ByVal iGS As Integer) As Long
          getGradientStopColor = ActivePresentation.Slides(iSlide).Shapes(iShape).Fill.GradientStops(iGS).Color.RGB
    End Function
    
    

    And call the macro from you .NET code, something like this ...

    object[] oParam = { 1, 1, 1 };
    object retVal = Globals.ThisAddIn.Application.Run("getGradientStopColor", ref oParam);
    Debug.WriteLine(retVal.ToString());
    
    oParam[0] = 1; oParam[1] = 1; oParam[2] = 2;
    retVal = Globals.ThisAddIn.Application.Run("getGradientStopColor", ref oParam);
    Debug.WriteLine(retVal.ToString());
    
    oParam[0] = 1; oParam[1] = 1; oParam[2] = 3;
    retVal = Globals.ThisAddIn.Application.Run("getGradientStopColor", ref oParam);
    Debug.WriteLine(retVal.ToString());

    Hold on ..I know, not a great way of doing things, but unfortunately I didn't find anything better.

    If you do find something better, please keep me posted.

     



     

     

    Not responsible for errors in content, meaning, tact, or judgment. Live and let live. Toes go in first. I didn't do it. Enjoy.

  • Pranav ... Blogging

    Open XML Format SDK April CTP - Released !!

    • 0 Comments

    It's there, Open XML SDK April CTP is released, it's for all of us - the proud office developers :) I was waiting for it!  Erica - thanks a lot ... (in fact I was searching for this last week, but couldn't find it ... well, I was a bit early). Also, you might want to look at the future plans (which looks concrete based on the previous experience with the team ... hey - you guys are doing a phenomenal job!). You can download it from here

     

    image

     

    And - why am I so exited? Because among all the other changes, there is the annotation thing which is super cool, this enables you to write efficient code by minimizing serialization and de-serialization.

    That is to say -  You can associate arbitrary data with a particular part(think of it as VB 6.0 tag property on steroids). For an example, After opening an Open XML document, you may want to read a part into a System.Xml.Linq.XDocument, query the XDocument object using LINQ to XML, perhaps modify the XDocument, and then serialize the XDocument back into the package. If you need to read the XML from the part, parse it, modify it, and then serialize it back into the package every time that you want to access the XML, your code will not perform as well as if you read the XML from the part only once, then use it as appropriate, and then serialize back into the part only once. If, once having read the XML from the part, you add the XDocument instance as an annotation on the part, you can easily retrieve the annotation instead of rereading the XML each time you need to access it. Annotations allow you to associate any object with an OpenXmlPartContainer (the base class of OpenXmlPart) in a type safe way.

    An example code would be -

    Module LocalExtensions
        ' How to create and extension method
        <Extension()> _
        Function GetXDocument(ByVal part As OpenXmlPart) As XDocument
            Dim xdoc As XDocument = part.Annotation(Of XDocument)()
            If (xdoc Is Nothing = False) Then
                Return xdoc
            End If
    
            Using streamReader As StreamReader =
                                   new StreamReader(part.GetStream())
                xdoc = XDocument.Load(XmlReader.Create(streamReader))
                part.AddAnnotation(xdoc)
            End Using
    
            Return xdoc
        End Function
    End Module
    

    For more details regarding annotations, have a look at http://msdn2.microsoft.com/en-us/library/cc471941.aspx . Believe me, annotations is really a great thing, Eric also agrees with me 

     



     

     

    Not responsible for errors in content, meaning, tact, or judgment. Live and let live. Toes go in first. I didn't do it. Enjoy.

Page 1 of 8 (186 items) 12345»