Problem modifying XML view definitions from installed C# Add-in

  • Thread starter Thread starter Michael
  • Start date Start date
M

Michael

I am writing an Outlook COM Add-in in C# (Visual Studio .NET 2003) which
attempts to modify an XML view definition for an Outlook folder (similar to
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnout2k2/html/odc_customviews.asp )
..

It works fine on my development machine, but when I distribute the add-in
using a setup project, the view definition change does not work (both
Windows XP SP1 and Outlook 2003 SP1), though no errors are reported. Other
parts of my add-in do work; only the view definition change does not appear
to work.

I have installed the Office XP PIAs on my system, since I want my add-in to
work for Outlook XP as well as Outlook 2003. I reference them directly (
which I'm not supposed to do according to the PIA readme file and
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnoxpta/html/odc_oxppias.asp )
, though I tried it the proper way with the same results. The 4 PIAs
related to Outlook are included in my setup project (as Detected
Dependencies), I have imported the registry entries, and I have them
installing to the GAC. I suspect that the method for installation of my
program and/or the PIAs is related to my problem, but I could be wrong, of
course.

Below is a small program which demonstrates the issue I am encountering
(this is not my actual project, just a test program). All of the action
happens in the OnConnection method. The program creates a folder under the
Inbox, copies an email there, and modifies the view such that only the
Subject field is displayed (removing the From, Received, etc fields). Any
help/advice is appreciated. -- Michael

------------------------- Connect.cs -------------------------

namespace OutlookAddinTest
{
using System;
using Microsoft.Office.Core;
using Extensibility;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Xml;
using Outlook = Microsoft.Office.Interop.Outlook; // Office XP PIAs

[GuidAttribute("E08191FA-C5B7-4835-AB11-1F2C67A85EB7"),
ProgId("OutlookAddinTest.Connect")]
public class Connect : Object, Extensibility.IDTExtensibility2
{
public Connect()
{
}

/// <summary>
/// Implements the OnConnection method of the IDTExtensibility2
interface.
/// Receives notification that the Add-in is being loaded.
/// </summary>
/// <param term='application'>
/// Root object of the host application.
/// </param>
/// <param term='connectMode'>
/// Describes how the Add-in is being loaded.
/// </param>
/// <param term='addInInst'>
/// Object representing this Add-in.
/// </param>
/// <seealso class='IDTExtensibility2' />
public void OnConnection(object application, Extensibility.ext_ConnectMode
connectMode, object addInInst, ref System.Array custom)
{
// Get the application and namespace
Outlook.Application olApp = (Outlook.Application) application;
Outlook.NameSpace olNs = olApp.GetNamespace("MAPI");

// Find the Inbox
Outlook.MAPIFolder olInboxFolder =
olNs.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);

// Create a folder under the Inbox
Outlook.MAPIFolder newFolder = olInboxFolder.Folders.Add("Test Folder",
Outlook.OlDefaultFolders.olFolderInbox);

// Assume there is an email in the Inbox...
Outlook.MailItem randomEmail = (Outlook.MailItem) olInboxFolder.Items[1];

// Copy it to the new folder (by making a copy and then moving the copy).
// This will just make it easier to the see the results of the view
changes... it is not completely necessary.
Outlook.MailItem newEmail = (Outlook.MailItem) randomEmail.Copy();
newEmail = (Outlook.MailItem) newEmail.Move(newFolder);

// Create a new view
Outlook.View newView1 = newFolder.Views.Add("Test View",
Outlook.OlViewType.olTableView,
Outlook.OlViewSaveOption.olViewSaveOptionThisFolderOnlyMe);

// Let's look at the default XML (in the debugger)
Debug.WriteLine(newView1.XML, "View XML");

// Modify the XML
newView1.XML = XmlModifiedUsingXmlManipulation(newView1.XML);
// Note: I had also tried hand-editing the default XML and assigning it
here (rather than using the
// XmlModifiedUsingXmlManipulation method) with the same results.
newView1.Save();
newView1.Apply(); // Oddly, this line generates an error (for me) in
Office XP...

}

/// <summary>
/// Modify Outlook View XML using C# XML routines.
/// </summary>
/// <param name="xmlString">XML string from an Outlook View</param>
/// <returns></returns>
private string XmlModifiedUsingXmlManipulation(string xmlString)
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xmlString);

XmlNode docNode = xmlDoc.DocumentElement;
// Remove most columns
foreach (XmlNode column in docNode.SelectNodes("//column"))
{
if (column.SelectSingleNode("prop").InnerText !=
"urn:schemas:httpmail:subject" &&
column.SelectSingleNode("prop").InnerText != "DAV:href")
{
Debug.WriteLine("Deleting project column " + column.InnerXml, "XML
Column");
column.ParentNode.RemoveChild(column);
}
else
{
Debug.WriteLine("Leaving project column " + column.InnerXml, "XML
Column");
}
}

// Turn off new item row and "in cell" edit.
XmlNode x = docNode.SelectSingleNode("newitemrow");
if (x != null)
{
x.InnerText = "0";
}
x = docNode.SelectSingleNode("incelledit");
if (x != null)
{
x.InnerText = "0";
}

string newXML = xmlDoc.InnerXml;

// Let's look at the default XML
Debug.WriteLine(newXML, "New XML");

return newXML;
}


public void OnDisconnection(Extensibility.ext_DisconnectMode
disconnectMode, ref System.Array custom)
{
}

public void OnAddInsUpdate(ref System.Array custom)
{
}

public void OnStartupComplete(ref System.Array custom)
{
}

public void OnBeginShutdown(ref System.Array custom)
{
}

}
}
 
Try debugging it and see what happens. Also, print out the definition
before and afterwards. The final thing you may want to do is select your
new view after you create it. Sounds like a weird problem.

Tom

--
Looking for a good book on programming Exchange, Outlook, ADSI and
SharePoint? Check out http://www.microsoft.com/MSPress/books/5517.asp

This posting is provided "AS IS" with no warranties, and confers no rights.



Michael said:
I am writing an Outlook COM Add-in in C# (Visual Studio .NET 2003) which
attempts to modify an XML view definition for an Outlook folder (similar
to
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnout2k2/html/odc_customviews.asp )
.

It works fine on my development machine, but when I distribute the add-in
using a setup project, the view definition change does not work (both
Windows XP SP1 and Outlook 2003 SP1), though no errors are reported.
Other
parts of my add-in do work; only the view definition change does not
appear
to work.

I have installed the Office XP PIAs on my system, since I want my add-in
to
work for Outlook XP as well as Outlook 2003. I reference them directly (
which I'm not supposed to do according to the PIA readme file and
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnoxpta/html/odc_oxppias.asp )
, though I tried it the proper way with the same results. The 4 PIAs
related to Outlook are included in my setup project (as Detected
Dependencies), I have imported the registry entries, and I have them
installing to the GAC. I suspect that the method for installation of my
program and/or the PIAs is related to my problem, but I could be wrong, of
course.

Below is a small program which demonstrates the issue I am encountering
(this is not my actual project, just a test program). All of the action
happens in the OnConnection method. The program creates a folder under
the
Inbox, copies an email there, and modifies the view such that only the
Subject field is displayed (removing the From, Received, etc fields). Any
help/advice is appreciated. -- Michael

------------------------- Connect.cs -------------------------

namespace OutlookAddinTest
{
using System;
using Microsoft.Office.Core;
using Extensibility;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Xml;
using Outlook = Microsoft.Office.Interop.Outlook; // Office XP PIAs

[GuidAttribute("E08191FA-C5B7-4835-AB11-1F2C67A85EB7"),
ProgId("OutlookAddinTest.Connect")]
public class Connect : Object, Extensibility.IDTExtensibility2
{
public Connect()
{
}

/// <summary>
/// Implements the OnConnection method of the IDTExtensibility2
interface.
/// Receives notification that the Add-in is being loaded.
/// </summary>
/// <param term='application'>
/// Root object of the host application.
/// </param>
/// <param term='connectMode'>
/// Describes how the Add-in is being loaded.
/// </param>
/// <param term='addInInst'>
/// Object representing this Add-in.
/// </param>
/// <seealso class='IDTExtensibility2' />
public void OnConnection(object application,
Extensibility.ext_ConnectMode
connectMode, object addInInst, ref System.Array custom)
{
// Get the application and namespace
Outlook.Application olApp = (Outlook.Application) application;
Outlook.NameSpace olNs = olApp.GetNamespace("MAPI");

// Find the Inbox
Outlook.MAPIFolder olInboxFolder =
olNs.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);

// Create a folder under the Inbox
Outlook.MAPIFolder newFolder = olInboxFolder.Folders.Add("Test Folder",
Outlook.OlDefaultFolders.olFolderInbox);

// Assume there is an email in the Inbox...
Outlook.MailItem randomEmail = (Outlook.MailItem)
olInboxFolder.Items[1];

// Copy it to the new folder (by making a copy and then moving the
copy).
// This will just make it easier to the see the results of the view
changes... it is not completely necessary.
Outlook.MailItem newEmail = (Outlook.MailItem) randomEmail.Copy();
newEmail = (Outlook.MailItem) newEmail.Move(newFolder);

// Create a new view
Outlook.View newView1 = newFolder.Views.Add("Test View",
Outlook.OlViewType.olTableView,
Outlook.OlViewSaveOption.olViewSaveOptionThisFolderOnlyMe);

// Let's look at the default XML (in the debugger)
Debug.WriteLine(newView1.XML, "View XML");

// Modify the XML
newView1.XML = XmlModifiedUsingXmlManipulation(newView1.XML);
// Note: I had also tried hand-editing the default XML and assigning it
here (rather than using the
// XmlModifiedUsingXmlManipulation method) with the same results.
newView1.Save();
newView1.Apply(); // Oddly, this line generates an error (for me) in
Office XP...

}

/// <summary>
/// Modify Outlook View XML using C# XML routines.
/// </summary>
/// <param name="xmlString">XML string from an Outlook View</param>
/// <returns></returns>
private string XmlModifiedUsingXmlManipulation(string xmlString)
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xmlString);

XmlNode docNode = xmlDoc.DocumentElement;
// Remove most columns
foreach (XmlNode column in docNode.SelectNodes("//column"))
{
if (column.SelectSingleNode("prop").InnerText !=
"urn:schemas:httpmail:subject" &&
column.SelectSingleNode("prop").InnerText != "DAV:href")
{
Debug.WriteLine("Deleting project column " + column.InnerXml, "XML
Column");
column.ParentNode.RemoveChild(column);
}
else
{
Debug.WriteLine("Leaving project column " + column.InnerXml, "XML
Column");
}
}

// Turn off new item row and "in cell" edit.
XmlNode x = docNode.SelectSingleNode("newitemrow");
if (x != null)
{
x.InnerText = "0";
}
x = docNode.SelectSingleNode("incelledit");
if (x != null)
{
x.InnerText = "0";
}

string newXML = xmlDoc.InnerXml;

// Let's look at the default XML
Debug.WriteLine(newXML, "New XML");

return newXML;
}


public void OnDisconnection(Extensibility.ext_DisconnectMode
disconnectMode, ref System.Array custom)
{
}

public void OnAddInsUpdate(ref System.Array custom)
{
}

public void OnStartupComplete(ref System.Array custom)
{
}

public void OnBeginShutdown(ref System.Array custom)
{
}

}
}
 
Thank you for the suggestions, Tom. Here are my responses to your
suggestions (in hopes that you or others can provide further insight):

My view is already selected (I think the .Apply() does that). This can be
confirmed in the Outlook menus by clicking View --> Arrange By --> Current
View ... I can see that Test View is the current view. Switching to another
view and then back has no positive effect.

I modified my test program to print the XML before and after the change.
The resulting XML appears correct, though the view appears to be ignoring
it. The "after" XML is included below. I had done this with my application
as well.

As far as debugging, the programs work fine in my development environment,
so debugging there has not helped. I tried remotely debugging my
application installed on a Virtual PC, but didn't have much luck actually
getting that to work well.

Michael

<?xml version="1.0"?>
<view type="table">
<viewname>Test View</viewname>
<viewstyle>table-layout:fixed;width:100%;font-family:Tahoma;font-style:normal;font-weight:normal;font-size:8pt;color:Black;font-charset:0</viewstyle> <viewtime>212341908</viewtime> <linecolor>8421504</linecolor> <linestyle>3</linestyle> <usequickflags>1</usequickflags> <collapsestate></collapsestate> <rowstyle>background-color:#FFFFFF</rowstyle> <headerstyle>background-color:#D3D3D3</headerstyle> <previewstyle>color:Blue</previewstyle> <arrangement> <autogroup>1</autogroup> <collapseclient></collapseclient> </arrangement> <column> <name>HREF</name> <prop>DAV:href</prop> <checkbox>1</checkbox> </column> <column> <heading>Subject</heading> <prop>urn:schemas:httpmail:subject</prop> <type>string</type> <width>120</width> <style>padding-left:3px;;text-align:left</style> </column> <orderby> <order> <heading>Received</heading> <prop>urn:schemas:httpmail:datereceived</prop> <type>datetime</type> <sort>desc</sort> </order> </orderby> <groupbydefault>2</groupbydefault> <previewpane> <visible>1</visible> <markasread>0</markasread> </previewpane></view>"Tom Rizzo [MSFT]" <[email protected]> wrote in messagenews:[email protected] debugging it and see what happens. Also, print out the definitionbefore and afterwards. The final thing you may want to do is select yournew view after you create it. Sounds like a weird problem.Tom--Looking for a good book on programming Exchange, Outlook, ADSI andSharePoint? Check out http://www.microsoft.com/MSPress/books/5517.aspThis posting is provided "AS IS" with no warranties, and confers no rights."Michael" <[email protected]> wrote in messagenews:[email protected]...>I am writing an Outlook COM Add-in in C# (Visual Studio .NET 2003) which> attempts to modify an XML view definition for an Outlook folder (similar> to>http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnout2k2/html/odc_customviews.asp )> .>> It works fine on my development machine, but when I distribute the add-in> using a setup project, the view definition change does not work (both> Windows XP SP1 and Outlook 2003 SP1), though no errors are reported.> Other> parts of my add-in do work; only the view definition change does not> appear> to work.>> I have installed the Office XP PIAs on my system, since I want my add-in> to> work for Outlook XP as well as Outlook 2003. I reference them directly (> which I'm not supposed to do according to the PIA readme file and>http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnoxpta/html/odc_oxppias.asp )> , though I tried it the proper way with the same results. The 4 PIAs> related to Outlook are included in my setup project (as Detected> Dependencies), I have imported the registry entries, and I have them> installing to the GAC. I suspect that the method for installation of my> program and/or the PIAs is related to my problem, but I could be wrong, of> course.>> Below is a small program which demonstrates the issue I am encountering> (this is not my actual project, just a test program). All of the action> happens in the OnConnection method. The program creates a folder under> the> Inbox, copies an email there, and modifies the view such that only the> Subject field is displayed (removing the From, Received, etc fields). Any> help/advice is appreciated. -- Michael>> ------------------------- Connect.cs ------------------------->> namespace OutlookAddinTest> {> using System;> using Microsoft.Office.Core;> using Extensibility;> using System.Runtime.InteropServices;> using System.Diagnostics;> using System.Xml;> using Outlook = Microsoft.Office.Interop.Outlook; // Office XP PIAs>> [GuidAttribute("E08191FA-C5B7-4835-AB11-1F2C67A85EB7"),> ProgId("OutlookAddinTest.Connect")]> public class Connect : Object, Extensibility.IDTExtensibility2> {> public Connect()> {> }>> /// <summary>> /// Implements the OnConnection method of the IDTExtensibility2> interface.> /// Receives notification that the Add-in is being loaded.> /// </summary>> /// <param term='application'>> /// Root object of the host application.> /// </param>> /// <param term='connectMode'>> /// Describes how the Add-in is being loaded.> /// </param>> /// <param term='addInInst'>> /// Object representing this Add-in.> /// </param>> /// <seealso class='IDTExtensibility2' />> public void OnConnection(object application,> Extensibility.ext_ConnectMode> connectMode, object addInInst, ref System.Array custom)> {> // Get the application and namespace> Outlook.Application olApp = (Outlook.Application) application;> Outlook.NameSpace olNs = olApp.GetNamespace("MAPI");>> // Find the Inbox> Outlook.MAPIFolder olInboxFolder => olNs.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);>> // Create a folder under the Inbox> Outlook.MAPIFolder newFolder = olInboxFolder.Folders.Add("Test Folder",> Outlook.OlDefaultFolders.olFolderInbox);>> // Assume there is an email in the Inbox...> Outlook.MailItem randomEmail = (Outlook.MailItem)> olInboxFolder.Items[1];>> // Copy it to the new folder (by making a copy and then moving the> copy).> // This will just make it easier to the see the results of the view> changes... it is not completely necessary.> Outlook.MailItem newEmail = (Outlook.MailItem) randomEmail.Copy();> newEmail = (Outlook.MailItem) newEmail.Move(newFolder);>> // Create a new view> Outlook.View newView1 = newFolder.Views.Add("Test View",> Outlook.OlViewType.olTableView,> Outlook.OlViewSaveOption.olViewSaveOptionThisFolderOnlyMe);>> // Let's look at the default XML (in the debugger)> Debug.WriteLine(newView1.XML, "View XML");>> // Modify the XML> newView1.XML = XmlModifiedUsingXmlManipulation(newView1.XML);> // Note: I had also tried hand-editing the default XML and assigning it> here (rather than using the> // XmlModifiedUsingXmlManipulation method) with the same results.> newView1.Save();> newView1.Apply(); // Oddly, this line generates an error (for me) in> Office XP...>> }>> /// <summary>> /// Modify Outlook View XML using C# XML routines.> /// </summary>> /// <param name="xmlString">XML string from an Outlook View</param>> /// <returns></returns>> private string XmlModifiedUsingXmlManipulation(string xmlString)> {> XmlDocument xmlDoc = new XmlDocument();> xmlDoc.LoadXml(xmlString);>> XmlNode docNode = xmlDoc.DocumentElement;> // Remove most columns> foreach (XmlNode column in docNode.SelectNodes("//column"))> {> if (column.SelectSingleNode("prop").InnerText !=> "urn:schemas:httpmail:subject" &&> column.SelectSingleNode("prop").InnerText != "DAV:href")> {> Debug.WriteLine("Deleting project column " + column.InnerXml, "XML> Column");> column.ParentNode.RemoveChild(column);> }> else> {> Debug.WriteLine("Leaving project column " + column.InnerXml, "XML> Column");> }> }>> // Turn off new item row and "in cell" edit.> XmlNode x = docNode.SelectSingleNode("newitemrow");> if (x != null)> {> x.InnerText = "0";> }> x = docNode.SelectSingleNode("incelledit");> if (x != null)> {> x.InnerText = "0";> }>> string newXML = xmlDoc.InnerXml;>> // Let's look at the default XML> Debug.WriteLine(newXML, "New XML");>> return newXML;> }>>> public void OnDisconnection(Extensibility.ext_DisconnectMode> disconnectMode, ref System.Array custom)> {> }>> public void OnAddInsUpdate(ref System.Array custom)> {> }>> public void OnStartupComplete(ref System.Array custom)> {> }>> public void OnBeginShutdown(ref System.Array custom)> {> }>> }> }>>
 
Back
Top