How to get all categories from the master category list in Outlook 2010 with C#

If you want the get all categories from the master category list in Outlook 2010, use the Session object from the application:

            Categories categories = Globals.ThisAddIn.Application.Session.Categories;
            foreach (Category category in categories)
            {
                string name = category.Name;
            }

This will list all categories from the dialog “All Categories…”:

 

image

How to get the current selected MailItem, TaskItem or AppointmentItem in C#, when contextmenu item is clicked in Microsoft Outlook 2010

If you use a contextmenu in you’re Microsoft Outlook 2010 C# add-in and want to use the item the user clicked on, you should use the first object in the

Globals.ThisAddIn.Application.ActiveExplorer().Selection

image

 

Note

The Selection collection does not start at index 0 but index 1, if you use Selection[0] an index out of bounds exception will occur.

 

ContextMenu.xml

<?xml version="1.0" encoding="UTF-8"?>
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui" onLoad="Ribbon_Load">
    <contextMenus>
        <contextMenu idMso="ContextMenuFolder">
            <button idMso="FolderPropertiesContext" getVisible="IsVisible" />
            
        </contextMenu>
        <contextMenu idMso="ContextMenuMailItem">
            <button id="MyContextMenuMailItem"
            label="Start Timer"
            onAction="OnMyButtonClick"/>
        </contextMenu>
        <contextMenu idMso="ContextMenuTaskItem">
            <button id="MyContextMenuTaskItem"
                    label="Start Timer"
                    onAction="OnMyButtonClick"/>
        </contextMenu>
        <contextMenu idMso="ContextMenuCalendarItem">
            <button id="MyContextMenuCalendarItem"
          label="Start Timer"
          onAction="OnMyButtonClick"/>
        </contextMenu>
    </contextMenus>
</customUI>

 

ContextMenu.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.Office.Interop.Outlook;
using Office = Microsoft.Office.Core;
using Ada.Tip.WpfUserControls.BC;

namespace Ada.Tip.OutlookAddIn
{
    [ComVisible(true)]
    public class ContextMenuRibbon : Office.IRibbonExtensibility
    {
        private Office.IRibbonUI ribbon;

        public ContextMenuRibbon()
        {
        }        
        public bool IsVisible(Office.IRibbonControl control)
        {
            //string foldername = ((Microsoft.Office.Interop.Outlook.Folder)control.Context).Name;
            //if (foldername == "Inbox")
            //{
            //  return false;
            //}
            return true;
        }
        #region IRibbonExtensibility Members

        public string GetCustomUI(string ribbonID)
        {
            return GetResourceText("Ada.Tip.OutlookAddIn.contextMenuRibbon.xml");
        }

        #endregion

        #region Ribbon Callbacks
        //Create callback methods here. For more information about adding callback methods, select the Ribbon XML item in Solution Explorer and then press F1
        public void Ribbon_Load(Office.IRibbonUI ribbonUI)
        {
            this.ribbon = ribbonUI;
            Globals.ThisAddIn.RibbonUI = ribbonUI;
        }
        /// <summary>
        /// Event fires when user clicks in the ContextMenu on "Start Timer"
        /// </summary>
        /// <param name="control"></param>
        public void OnMyButtonClick(Office.IRibbonControl control)
        {
            Globals.ThisAddIn.dashboardUserControl.dashboard.StopCurrentWorkItem();

            // Determine subject of selected item
            string subject = string.Empty;
            Explorer explorer = Globals.ThisAddIn.app.ActiveExplorer();
            if (explorer != null && explorer.Selection != null && explorer.Selection.Count > 0)
            {
                object item = explorer.Selection[1];
                if (item is MailItem)
                {
                    MailItem mailItem = item as MailItem;
                    subject = mailItem.Subject;
                }
                if (item is TaskItem)
                {
                    TaskItem taskItem = item as TaskItem;
                    subject = taskItem.Subject;
                }
                if (item is AppointmentItem)
                {
                    AppointmentItem appointmentItem = item as AppointmentItem;
                    subject = appointmentItem.Subject;
                }
            }

            
        }
        #endregion

        #region Helpers
        
        private static string GetResourceText(string resourceName)
        {
            Assembly asm = Assembly.GetExecutingAssembly();
            string[] resourceNames = asm.GetManifestResourceNames();
            for (int i = 0; i < resourceNames.Length; ++i)
            {
                if (string.Compare(resourceName, resourceNames[i], StringComparison.OrdinalIgnoreCase) == 0)
                {
                    using (StreamReader resourceReader = new StreamReader(asm.GetManifestResourceStream(resourceNames[i])))
                    {
                        if (resourceReader != null)
                        {
                            return resourceReader.ReadToEnd();
                        }
                    }
                }
            }
            return null;
        }

        #endregion
    }
}

Remove item from Programs and Features list in Windows 7

If the uninstallation of an program fails, the item will not be removed from the “Programs and Features” list on the Control Panel in Windows 7.

To remove the item, remove the item from the registry key:

Windows 7 x64

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall

 

Windows 7 x86

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall

 

Note

Removing the key will only remove the item form the “Programs and Features” list, if you want to re-install the program you should also find the productcode and the corresponding upgrade code, then remove the entry from:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UpgradeCodes

How to deploy a report (*.rdl) file to SQL Server Reporting Services using PowerShell

If you want to deploy a report (*.rdl) file to SQL Server Reporting Services in PowerShell, use the following script:

 

PowerShell script

"Set execution policy to [Unrestricted]"
Set-ExecutionPolicy Unrestricted

"Load assembly"
[System.Reflection.Assembly]::LoadFrom("C:\Temp\Ada.Cdf.dll")

"Create report"
$report = New-Object Ada.Cdf.Deployment.SSRS.Report
$report.SSRSWebServiceUrl = "http://localhost/ReportServer/ReportService2005.asmx"
$report.SSRSFolder = "ADA Sales Reports"
$report.FileSystemPath = "C:\Reports\AanvragenStats.rdl"
$report.Create()

 

C# code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Ada.Cdf.ReportService2005;

namespace Ada.Cdf.Deployment.SSRS
{
    public class Report
    {
        public string FileSystemPath { get; set; }
        public string SSRSWebServiceUrl { get; set; }
        public string _ssrsFolder = string.Empty;
        public string SSRSFolder 
        {
            get
            {
                // Use "/" as default value
                string firstCharacter = "/";
                if (string.IsNullOrEmpty(_ssrsFolder))
                {
                    _ssrsFolder = firstCharacter;
                }

                // Report folder should start with one "/"
                _ssrsFolder = firstCharacter + _ssrsFolder.TrimStart(firstCharacter.ToCharArray());

                return _ssrsFolder;
            }
            set
            {
                _ssrsFolder = value;
            }
        }

        /// <summary>
        /// Create a report
        /// </summary>
        public void Create()
        {

            // Validate properties
            if (string.IsNullOrEmpty(this.FileSystemPath)) { throw new ArgumentNullException("this.FileSystemPath"); }
            if (!File.Exists(this.FileSystemPath)) { throw new ApplicationException(string.Format("The file [{0}] does not exist", this.FileSystemPath)); }
            if (string.IsNullOrEmpty(this.SSRSWebServiceUrl)) { throw new ArgumentNullException("this.SSRSWebServiceUrl"); }
            if (string.IsNullOrEmpty(this.SSRSFolder)) { throw new ArgumentNullException("this.SSRSFolder"); }

            // Initialize webservice proxy
            ReportService2005.ReportingService2005 rs = new ReportService2005.ReportingService2005();
            rs.Url = this.SSRSWebServiceUrl;
            rs.Credentials = System.Net.CredentialCache.DefaultCredentials;

            // Determine filename without extension (used as name in SSRS)
            FileInfo fileInfo = new FileInfo(this.FileSystemPath);
            string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileInfo.FullName);

            // Determine filecontents
            byte[] fileContents = File.ReadAllBytes(fileInfo.FullName);

            // Publish report
            Warning[] warnings = rs.CreateReport(fileNameWithoutExtension, this.SSRSFolder, true, fileContents, null);

            // Log warnings
            if (warnings != null)
            {
                foreach (Warning warning in warnings)
                {
                    Global.Logger.Warn(warning);
                }
            }

        }
        /// <summary>
        /// Delete a report
        /// </summary>
        public void Delete()
        {

            // Initialize webservice proxy
            ReportService2005.ReportingService2005 rs = new ReportService2005.ReportingService2005();
            rs.Url = this.SSRSWebServiceUrl;
            rs.Credentials = System.Net.CredentialCache.DefaultCredentials;

            // Determine filename without extension (used as name in SSRS)
            FileInfo fileInfo = new FileInfo(this.FileSystemPath);
            string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileInfo.FullName);

            // Determine full SSRS path
            string ssrsPath = string.Format("{0}/{1}", this.SSRSFolder, fileNameWithoutExtension.TrimStart("/".ToCharArray()));

            // Delete report
            rs.DeleteItem(ssrsPath);

        }
    }
}

 

Result

image

How to deploy a datasource in SQL Server Reporting Services with PowerShell

If you want to use PowerShell to deploy a datasource in SQL Server Reporting Services use the following script:

 

PowerShell script

"Set execution policy to [Unrestricted]"
Set-ExecutionPolicy Unrestricted

"Load assembly"
[System.Reflection.Assembly]::LoadFrom("C:\Temp\Ada.Cdf.dll")

$datasource = New-Object Ada.Cdf.Deployment.SSRS.DataSource
$datasource.SSRSWebServiceUrl = "http://localhost/ReportServer/ReportService2005.asmx"
$datasource.ImpersonateUser = $false
$datasource.WindowsIntegratedSecurity = $true
$datasource.UserAccountName = "MyDomain\saAsaWeb"
$datasource.UserAccountPassword = "MyPassword"
$datasource.ConnectionString = "Data Source=.;Initial Catalog=AdaSales;Integrated Security=SSPI;"
$datasource.FileSystemPath = "C:\Temp\Reports\AdaSales.rds"
$datasource.SSRSFolder = "ADA Sales Reports"
$datasource.Create()

 

 

C# code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Ada.Cdf.ReportService2005;

namespace Ada.Cdf.Deployment.SSRS
{
    public class DataSource
    {
        public bool ImpersonateUser { get; set; }
        public bool WindowsIntegratedSecurity { get; set; }
        public string UserAccountName { get; set; }
        public string UserAccountPassword { get; set; }
        public string ConnectionString { get; set; }
        public string FileSystemPath { get; set; }
        public string SSRSWebServiceUrl { get; set; }
        public string _ssrsFolder = string.Empty;
        public string SSRSFolder
        {
            get
            {
                // Use "/" as default value
                string firstCharacter = "/";
                if (string.IsNullOrEmpty(_ssrsFolder))
                {
                    _ssrsFolder = firstCharacter;
                }

                // Report folder should start with one "/"
                _ssrsFolder = firstCharacter + _ssrsFolder.TrimStart(firstCharacter.ToCharArray());

                return _ssrsFolder;
            }
            set
            {
                _ssrsFolder = value;
            }
        }

        /// <summary>
        /// Create a DataSource
        /// </summary>
        public void Create()
        {

            // Validate properties
            if (string.IsNullOrEmpty(this.FileSystemPath)) { throw new ArgumentNullException("this.FileSystemPath"); }
            if (!File.Exists(this.FileSystemPath)) { throw new ApplicationException(string.Format("The file [{0}] does not exist", this.FileSystemPath)); }
            if (string.IsNullOrEmpty(this.SSRSWebServiceUrl)) { throw new ArgumentNullException("this.SSRSWebServiceUrl"); }
            if (string.IsNullOrEmpty(this.SSRSFolder)) { throw new ArgumentNullException("this.SSRSFolder"); }
            if (string.IsNullOrEmpty(this.UserAccountName)) { throw new ArgumentNullException("this.UserAccountName"); }
            if (string.IsNullOrEmpty(this.UserAccountPassword)) { throw new ArgumentNullException("this.UserAccountPassword"); }

            // Initialize webservice proxy
            ReportService2005.ReportingService2005 rs = new ReportService2005.ReportingService2005();
            rs.Url = this.SSRSWebServiceUrl;
            rs.Credentials = System.Net.CredentialCache.DefaultCredentials;

            // Determine filename without extension (used as name in SSRS)
            FileInfo fileInfo = new FileInfo(this.FileSystemPath);
            string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileInfo.FullName);    

            // Create DataSourceDefinition
            DataSourceDefinition definition = new DataSourceDefinition();
            definition.CredentialRetrieval = CredentialRetrievalEnum.Store;
            definition.ConnectString = this.ConnectionString;
            definition.UserName = this.UserAccountName;
            definition.Password = this.UserAccountPassword;
            definition.Enabled = true;
            definition.EnabledSpecified = true;
            definition.Extension = "SQL";
            definition.ImpersonateUser = this.ImpersonateUser;
            definition.ImpersonateUserSpecified = true;

            // Use the default prompt string
            definition.Prompt = null;
            definition.WindowsCredentials = this.WindowsIntegratedSecurity;

            // Create datasource
            rs.CreateDataSource(fileNameWithoutExtension, this.SSRSFolder, true, definition, null);

        }
        /// <summary>
        /// Delete a DataSource
        /// </summary>
        public void Delete()
        {
            // Validate properties
            if (string.IsNullOrEmpty(this.FileSystemPath)) { throw new ArgumentNullException("this.FileSystemPath"); }
            if (string.IsNullOrEmpty(this.SSRSWebServiceUrl)) { throw new ArgumentNullException("this.SSRSWebServiceUrl"); }
            if (string.IsNullOrEmpty(this.SSRSFolder)) { throw new ArgumentNullException("this.SSRSFolder"); }

            // Initialize webservice proxy
            ReportService2005.ReportingService2005 rs = new ReportService2005.ReportingService2005();
            rs.Url = this.SSRSWebServiceUrl;
            rs.Credentials = System.Net.CredentialCache.DefaultCredentials;

            // Determine filename without extension (used as name in SSRS)
            FileInfo fileInfo = new FileInfo(this.FileSystemPath);
            string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileInfo.FullName);

            // Determine full SSRS path
            string ssrsPath = string.Format("{0}/{1}", this.SSRSFolder, fileNameWithoutExtension.TrimStart("/".ToCharArray()));

            // Delete datasource
            rs.DeleteItem(ssrsPath);

        }
    }
}

 

 

Result

image

How to create a folder in SQL Server Reporting Services with PowerShell

If you want to use PowerShell to create a folder in SQL Server Reporting Services use the following script:

PowerShell script

"Set execution policy to [Unrestricted]"
Set-ExecutionPolicy Unrestricted

"Load assembly"
[System.Reflection.Assembly]::LoadFrom("C:\Temp\Ada.Cdf.dll")

$folder = New-Object Ada.Cdf.Deployment.SSRS.Folder
$folder.SSRSWebServiceUrl = "http://localhost/ReportServer/ReportService2005.asmx"
$folder.Name = "ADA Sales Reports"
$folder.Parent = "/"
$folder.Create()

 

 

 

C# Code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace Ada.Cdf.Deployment.SSRS
{
    public class Folder
    {
        public string SSRSWebServiceUrl { get; set; }
        public string _parent = "/";
        public string Parent
        {
            get
            {
                // Use "/" as default value
                string firstCharacter = "/";
                if (string.IsNullOrEmpty(_parent))
                {
                    _parent = firstCharacter;
                }

                // Parent should start with one "/"
                _parent = firstCharacter + _parent.TrimStart(firstCharacter.ToCharArray());

                return _parent;
            }
            set
            {
                _parent = value;
            }
        }
        public string _name = string.Empty;
        public string Name
        {
            get
            {
                
                if (string.IsNullOrEmpty(_name))
                {
                    _name = string.Empty;
                }

                // FolderName should not start with"/"
                _name = _name.TrimStart("/".ToCharArray());

                return _name;
            }
            set
            {
                _name = value;
            }
        }

        /// <summary>
        /// Create a report
        /// </summary>
        public void Create()
        {

            // Validate properties
            if (string.IsNullOrEmpty(this.SSRSWebServiceUrl)) { throw new ArgumentNullException("this.SSRSWebServiceUrl"); }
            if (string.IsNullOrEmpty(this.Name)) { throw new ArgumentNullException("this.Name"); }
            if (string.IsNullOrEmpty(this.Parent)) { throw new ArgumentNullException("this.Parent"); }

            // Initialize webservice proxy
            ReportService2005.ReportingService2005 rs = new ReportService2005.ReportingService2005();
            rs.Url = this.SSRSWebServiceUrl;
            rs.Credentials = System.Net.CredentialCache.DefaultCredentials;

            try
            {
                rs.
                // Create report folder, this will throw an exception if the folder already exists
                rs.CreateFolder(this.Name, this.Parent, null);
            }
            catch (Exception ex)
            {
                Global.Logger.Info("Folder already exists", ex);
            }

        }
        /// <summary>
        /// Delete a report
        /// </summary>
        public void Delete()
        {
            // Initialize webservice proxy
            ReportService2005.ReportingService2005 rs = new ReportService2005.ReportingService2005();
            rs.Url = this.SSRSWebServiceUrl;
            rs.Credentials = System.Net.CredentialCache.DefaultCredentials;

            // Determine full SSRS path
            string ssrsPath = string.Format("{0}/{1}", this.Parent.TrimStart("/".ToCharArray()), this.Name);

            // Delete report
            rs.DeleteItem(ssrsPath);

       }
    }
}

Result

image

Explaining SSRS datasource options “Use as Windows credentials when connecting to the datasource” and “Impersonate the authenticated user after a connection has been made to the datasource”

In SSRS ther are two options you can set, when the credentials of the datasource are stored securely in the report server:

  • Use as Windows crendentials when connecting to the datasource

This option must be checked, when you want to use “Windows Integrated Security Authentication” and not “SQL Authentication”

  • Impersonate the authenticated user after a connection has been made to the datasource

This option must be checked, when you want to use the current user to query the database, instead of the given account. The given account is used to connect to the database, but after the connection has been made, the current user is used to query the database. If the current user does not have permissions an exception will occur.

image

How to make sure the first character of a string is one slash ‘/’ with C#, use the TrimStart function

If you want to make sure the first character of a string is one slash, use the function:

public string PrependPath(string path, string firstCharacter)
{
    return firstCharacter + path.TrimStart(firstCharacter.ToCharArray());
}

 

To test the function use:

string firstCharacter = "/";
Console.WriteLine(PrependPath("TestPath", firstCharacter));
Console.WriteLine(PrependPath("/TestPath", firstCharacter));
Console.WriteLine(PrependPath("//TestPath", firstCharacter));
Console.WriteLine(PrependPath("///TestPath", firstCharacter));    

 

Result

/TestPath

/TestPath

/TestPath

/TestPath

How to determine if a local user is member of a local computer group before adding, with PowerShell and C#

To dermine if a local user is member of a local group, before adding the user to the local group in PowerShell I use a C# class. The C# class could be converted to pure PowerShell code, but I prefer the C# class with it’s using statements:

 

[PowerShell script]

"Set execution policy to [Unrestricted]"
Set-ExecutionPolicy Unrestricted

$ComputerName = "."
$ServiceAccountWebUserName = "\saWeb",

"Check if user is member of IIS_IUSRS"
$localGroup = New-Object Ada.Cdf.Deployment.LocalGroup
$localGroup.ComputerName = $ComputerName
$localGroup.Name = "IIS_IUSRS"
if(!$localGroup.ContainsUser($ServiceAccountWebUserName))
{
    "Add user to the IIS_IUSRS group"
    $localGroup.AddUser($ServiceAccountWebUserName)
}

[C# Class]

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.DirectoryServices;
using System.Collections;

namespace Ada.Cdf.Deployment
{
    public class LocalGroup
    {
        /// <summary>
        /// Name of the computer use "." for executing computer
        /// </summary>
        string _computerName = Environment.MachineName;
        public string ComputerName 
        {
            get
            {
                if (!string.IsNullOrEmpty(_computerName) && _computerName.Equals("."))
                {
                    _computerName = Environment.MachineName;
                }
                return _computerName;
            }
            set
            {
                _computerName = value;
            }
        }
        public string Name { get; set; }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="userName"></param>
        /// <returns></returns>
        public bool ContainsUser(string userName)
        {

            // Validate properties
            if (string.IsNullOrEmpty(this.ComputerName)) { throw new ArgumentNullException("this.ComputerName"); }
            if (string.IsNullOrEmpty(this.Name)) { throw new ArgumentNullException("this.Name"); }

            bool result = false;
            using (DirectoryEntry groupEntry = new DirectoryEntry(string.Format("WinNT://{0}/{1},group", this.ComputerName, this.Name)))
            {
                // Get group members
                IEnumerable groupMembers = (IEnumerable)groupEntry.Invoke("Members");

                // Loop members
                foreach (object member in groupMembers)
                {
                    using (DirectoryEntry memberEntry = new DirectoryEntry(member))
                    {
                        if (memberEntry.Name.ToLower().Equals(userName.ToLower()))
                        {
                            result = true;
                        }
                    }
                }
            }

            return result;
        }
        /// <summary>
        /// Add a local user to a local group
        /// </summary>
        /// <param name="userName"></param>
        public void AddUser(string userName)
        {

            // Validate properties
            if (string.IsNullOrEmpty(this.ComputerName)) { throw new ArgumentNullException("this.ComputerName"); }
            if (string.IsNullOrEmpty(this.Name)) { throw new ArgumentNullException("this.Name"); }

            using (DirectoryEntry groupEntry = new DirectoryEntry(string.Format("WinNT://{0}/{1},group", this.ComputerName, this.Name)))
            {
              // Add user to group
              groupEntry.Invoke("Add", new object[] { string.Format("WinNT://{0}/{1}", this.ComputerName, userName) });
            }

        }
    }
}