Create folder in outlook | .Net - outlook

I am creating folder in microsoft outlook through .net application BUT it is getting displayed ONLY when I Restart outlook. New folder should be displayed without restarting outlook.
I am using below code:
Outlook.NameSpace nameSpace = OutlookApp.GetNamespace("MAPI");
Outlook.MAPIFolder folderInbox = nameSpace.GetDefaultFolder
(Outlook.OlDefaultFolders.olFolderInbox);
Outlook.Folders inboxFolders = folderInbox.Folders;
Outlook.MAPIFolder subfolderInbox = null;
Outlook.Application oApp;
oApp = nameSpace.Application;
Outlook.Explorer exp = oApp.ActiveExplorer();
subfolderInbox = inboxFolders.Add("InboxSubfolder",
Outlook.OlDefaultFolders.olFolderInbox);
exp.CurrentFolder = subfolderInbox;

I see you are using Add-in Express.
I attached your code to an adxRibbonButton control and it worked for me.
How are you calling this code?
I see some unnecessary object creation and removed them in my edited version below.
Also - you want to make sure to release the Office objects you create.
I recommend updating the code as follows:
private void adxRibbonButton1_OnClick(object sender, IRibbonControl control, bool pressed)
{
Outlook.NameSpace nameSpace = OutlookApp.Session; //OutlookApp.GetNamespace("MAPI");
Outlook.MAPIFolder folderInbox = nameSpace.GetDefaultFolder
(Outlook.OlDefaultFolders.olFolderInbox);
Outlook.Folders inboxFolders = folderInbox.Folders;
Outlook.MAPIFolder subfolderInbox = null;
//Outlook.Application oApp;
//oApp = nameSpace.Application;
Outlook.Explorer exp = OutlookApp.ActiveExplorer(); //oApp.ActiveExplorer();
subfolderInbox = inboxFolders.Add("InboxSubfolder",
Outlook.OlDefaultFolders.olFolderInbox);
exp.CurrentFolder = subfolderInbox;
//Release COM Objects
if (exp != null) Marshal.ReleaseComObject(exp);
if (subfolderInbox != null) Marshal.ReleaseComObject(subfolderInbox);
if (inboxFolders != null) Marshal.ReleaseComObject(inboxFolders);
if (folderInbox != null) Marshal.ReleaseComObject(folderInbox);
if (nameSpace != null) Marshal.ReleaseComObject(nameSpace);
}

Related

How to retrieve all contacts from Microsoft Exchange using EWS Managed API?

all I need to do is to retrieve all contacts from Microsoft Exchange. I did some research and the best possible option for me should be to use EWS Managed API. I am using Visual Studio and C# programming leanguage.
I think I am able to connect to Office365 account, because I am able to send a message in a program to specific email. But I am not able to retrieve the contacts.
If I create a contact directly in source code, the contact will be created in Office365->People aplication. But I don't know why! I thought I was working with Exchange aplication.
Summarize:
Is there any possibility how to get all contacts from Office365->Admin->Exchange->Acceptencers->Contacts ?
Here is my code:
class Program
{
static void Main(string[] args)
{
// connecting to my Exchange account
ServicePointManager.ServerCertificateValidationCallback = CertificateValidationCallBack;
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2007_SP1);
service.Credentials = new WebCredentials("office365email#test.com", "password123");
/*
// debugging
service.TraceEnabled = true;
service.TraceFlags = TraceFlags.All;
*/
service.AutodiscoverUrl("office365email#test.com", RedirectionUrlValidationCallback);
// send a message works good
EmailMessage email = new EmailMessage(service);
email.ToRecipients.Add("matoskok1#gmail.com");
email.Subject = "HelloWorld";
email.Body = new MessageBody("Toto je testovaci mail");
email.Send();
// Create the contact creates a contact in Office365 -> People application..Don't know why there and not in Office365 -> Exchange
/*Contact contact = new Contact(service);
// Specify the name and how the contact should be filed.
contact.GivenName = "Brian";
contact.MiddleName = "David";
contact.Surname = "Johnson";
contact.FileAsMapping = FileAsMapping.SurnameCommaGivenName;
// Specify the company name.
contact.CompanyName = "Contoso";
// Specify the business, home, and car phone numbers.
contact.PhoneNumbers[PhoneNumberKey.BusinessPhone] = "425-555-0110";
contact.PhoneNumbers[PhoneNumberKey.HomePhone] = "425-555-0120";
contact.PhoneNumbers[PhoneNumberKey.CarPhone] = "425-555-0130";
// Specify two email addresses.
contact.EmailAddresses[EmailAddressKey.EmailAddress1] = new EmailAddress("brian_1#contoso.com");
contact.EmailAddresses[EmailAddressKey.EmailAddress2] = new EmailAddress("brian_2#contoso.com");
// Specify two IM addresses.
contact.ImAddresses[ImAddressKey.ImAddress1] = "brianIM1#contoso.com";
contact.ImAddresses[ImAddressKey.ImAddress2] = " brianIM2#contoso.com";
// Specify the home address.
PhysicalAddressEntry paEntry1 = new PhysicalAddressEntry();
paEntry1.Street = "123 Main Street";
paEntry1.City = "Seattle";
paEntry1.State = "WA";
paEntry1.PostalCode = "11111";
paEntry1.CountryOrRegion = "United States";
contact.PhysicalAddresses[PhysicalAddressKey.Home] = paEntry1;
// Specify the business address.
PhysicalAddressEntry paEntry2 = new PhysicalAddressEntry();
paEntry2.Street = "456 Corp Avenue";
paEntry2.City = "Seattle";
paEntry2.State = "WA";
paEntry2.PostalCode = "11111";
paEntry2.CountryOrRegion = "United States";
contact.PhysicalAddresses[PhysicalAddressKey.Business] = paEntry2;
// Save the contact.
contact.Save();
*/
// msdn.microsoft.com/en-us/library/office/jj220498(v=exchg.80).aspx
// Get the number of items in the Contacts folder.
ContactsFolder contactsfolder = ContactsFolder.Bind(service, WellKnownFolderName.Contacts);
Console.WriteLine(contactsfolder.TotalCount);
// Set the number of items to the number of items in the Contacts folder or 50, whichever is smaller.
int numItems = contactsfolder.TotalCount < 50 ? contactsfolder.TotalCount : 50;
// Instantiate the item view with the number of items to retrieve from the Contacts folder.
ItemView view = new ItemView(numItems);
// To keep the request smaller, request only the display name property.
view.PropertySet = new PropertySet(BasePropertySet.IdOnly, ContactSchema.DisplayName);
// Retrieve the items in the Contacts folder that have the properties that you selected.
FindItemsResults<Item> contactItems = service.FindItems(WellKnownFolderName.Contacts, view);
// Display the list of contacts.
foreach (Item item in contactItems)
{
if (item is Contact)
{
Contact contact1 = item as Contact;
Console.WriteLine(contact1.DisplayName);
}
}
Console.ReadLine();
} // end of Main() method
/*===========================================================================================================*/
private static bool CertificateValidationCallBack(
object sender,
System.Security.Cryptography.X509Certificates.X509Certificate certificate,
System.Security.Cryptography.X509Certificates.X509Chain chain,
System.Net.Security.SslPolicyErrors sslPolicyErrors)
{
// If the certificate is a valid, signed certificate, return true.
if (sslPolicyErrors == System.Net.Security.SslPolicyErrors.None)
{
return true;
}
// If there are errors in the certificate chain, look at each error to determine the cause.
if ((sslPolicyErrors & System.Net.Security.SslPolicyErrors.RemoteCertificateChainErrors) != 0)
{
if (chain != null && chain.ChainStatus != null)
{
foreach (System.Security.Cryptography.X509Certificates.X509ChainStatus status in chain.ChainStatus)
{
if ((certificate.Subject == certificate.Issuer) &&
(status.Status == System.Security.Cryptography.X509Certificates.X509ChainStatusFlags.UntrustedRoot))
{
// Self-signed certificates with an untrusted root are valid.
continue;
}
else
{
if (status.Status != System.Security.Cryptography.X509Certificates.X509ChainStatusFlags.NoError)
{
// If there are any other errors in the certificate chain, the certificate is invalid,
// so the method returns false.
return false;
}
}
}
}
// When processing reaches this line, the only errors in the certificate chain are
// untrusted root errors for self-signed certificates. These certificates are valid
// for default Exchange server installations, so return true.
return true;
}
else
{
// In all other cases, return false.
return false;
}
}
private static bool RedirectionUrlValidationCallback(string redirectionUrl)
{
// The default for the validation callback is to reject the URL.
bool result = false;
Uri redirectionUri = new Uri(redirectionUrl);
// Validate the contents of the redirection URL. In this simple validation
// callback, the redirection URL is considered valid if it is using HTTPS
// to encrypt the authentication credentials.
if (redirectionUri.Scheme == "https")
{
result = true;
}
return result;
}
}
seems like you are already doing a good job doing a FindItems() method.
In order to get all contacts all you need to add is a SearchFilter, in this case I'd recommend doing the Exists() filter as you can simply say Find All contacts with an id.
See my example below if you need an example of a Full Windows Application dealing with contacts see my github page github.com/rojobo
Dim oFilter As New SearchFilter.Exists(ItemSchema.Id)
Dim oResults As FindItemsResults(Of Item) = Nothing
Dim oContact As Contact
Dim blnMoreAvailable As Boolean = True
Dim intSearchOffset As Integer = 0
Dim oView As New ItemView(conMaxChangesReturned, intSearchOffset, OffsetBasePoint.Beginning)
oView.PropertySet = BasePropertySet.IdOnly
Do While blnMoreAvailable
oResults = pService.FindItems(WellKnownFolderName.Contacts, oFilter, oView)
blnMoreAvailable = oResults.MoreAvailable
If Not IsNothing(oResults) AndAlso oResults.Items.Count > 0 Then
For Each oExchangeItem As Item In oResults.Items
Dim oExchangeContactId As ItemId = oExchangeItem.Id
//do something else
Next
If blnMoreAvailable Then oView.Offset = oView.Offset + conMaxChangesReturned
End If
Loop
How to retrieve all contacts from Microsoft Exchange using EWS Managed API?
If your question is how to retrieve the Exchange Contacts using EWS, you're already done with it.
Office365->People is just the right app to manipulate your Exchange contacts. If you check out the People app URL, it's something similar to https://outlook.office365.com/owa/?realm=xxxxxx#exsvurl=1&ll-cc=1033&modurl=2, owa is the synonym for outlook web app.

How to programmatically query if an SCCM 2012 Application is Active or Retired

We have an application that integrates with SCCM 2012 and saves custom SCCM applications to SCCM.
The problem I am having is that attempting to save one of our custom applications when the SCCM administrator has set the application to be in the retired state causes our application to fail the saving process.
I'd like to be able to query the SCCM application state in order to determine before we attempt the save operation whether the given application is Active or Retired.
I can find no reference to "retired" status in the SMS_Application Server WMI help or any of the other pages:
http://msdn.microsoft.com/en-us/library/hh949251.aspx
I have noticed that there is a Restore() method which looks like it will change the status of a Retired package back to Active, however that's not quite what I want to do.
Can anyone help me determine how to find an applications current status?
Thanks.
There's a method in the SCCM 2012 PowerShell cmdlets that appears to be retrieving the expired status. Here's the c# code (decompiled from the dll AppUI.PS.AppMan.dll on the SCCM server)
private bool IsApplicationRetired(IResultObject applicaction)
{
IResultObject[] resultObjectArray = null;
int integerValue = applicaction["CI_ID"].IntegerValue;
object[] objArray = new object[] { integerValue };
resultObjectArray = base.ExecuteQuery(string.Format(CultureInfo.InvariantCulture, "SELECT * FROM SMS_Application WHERE CI_ID = {0}", objArray));
IResultObject[] resultObjectArray1 = resultObjectArray;
int num = 0;
if (num < (int)resultObjectArray1.Length)
{
IResultObject resultObject = resultObjectArray1[num];
this.isApplicationRetired = resultObject["IsExpired"].BooleanValue;
}
if (this.isApplicationRetired)
{
object[] objArray1 = new object[] { integerValue };
IResultObject instance = base.ConnectionManager.GetInstance(string.Format(CultureInfo.InvariantCulture, "SMS_Application.CI_ID={0}", objArray1));
if (instance != null)
{
string stringValue = instance["ModelName"].StringValue;
instance.Dispose();
object[] objArray2 = new object[] { base.ConnectionManager.EscapeQueryString(stringValue, ConnectionManagerBase.EscapeQuoteType.SingleQuote) };
resultObjectArray = base.ExecuteQuery(string.Format(CultureInfo.InvariantCulture, "SELECT CI_ID FROM SMS_Application WHERE ModelName = '{0}' AND IsLatest = 1 AND IsExpired = 0", objArray2));
IResultObject[] resultObjectArray2 = resultObjectArray;
int num1 = 0;
if (num1 < (int)resultObjectArray2.Length)
{
IResultObject resultObject1 = resultObjectArray2[num1];
if (resultObject1["CI_ID"].IntegerValue != integerValue)
{
this.isApplicationRetired = false;
}
}
}
}
return this.isApplicationRetired;
}

ASP.Net MVC3 app downloading files to client from another network server

We currently use the code below to download files from a network server to the client in an old ASP.net page.
We have re-written the app in MVC3 and would like to upgrade this functionality. I have seen several posts that claim you can access the file from the network share by writing the following lines in web.config
<authentication mode="Windows"/>
<identity impersonate="true" userName="" password="" />
However, we are currently using Forms authentication mode to logon to the site. Would that interfere with the login functionality?
Here's our download code.
Partial Class DownloadFile2
Inherits System.Web.UI.Page
Private BufferSize As Integer = 32 * 1024
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim path As String = Request.Params("File")
path = "\\speedy\wanfiles\" + path.Substring(3)
Dim file As System.IO.FileInfo = New System.IO.FileInfo(path)
Dim Buffer(BufferSize) As Byte
Dim SizeWritten, fileindex As Integer
Response.Clear()
Response.AddHeader("Content-Disposition", "attachment; filename=" + file.Name)
Response.AddHeader("Content-Length", file.Length.ToString)
Response.ContentType = "application/octet-type"
Response.Flush()
fileindex = 0
Do
// not sure about this GM.AlasData code below
SizeWritten = GM.AlasData.ReadFileBlock(file.FullName, Buffer, fileindex, BufferSize)
Response.OutputStream.Write(Buffer, 0, SizeWritten)
Response.Flush()
If SizeWritten < BufferSize Then
Exit Do
Else
fileindex = fileindex + SizeWritten
End If
Loop
Response.End()
End Sub
End Class
I found this code to do downloads using MVC3 but cannot access the file because it is considered a local file.
public FileResult Download(string FilePath)
{
if (FilePath != null)
{
string path = FilePath;
string contentType;
// files are stored on network server named speedy
path = string.Concat(#"\\speedy\files\", HttpUtility.UrlDecode(path));
System.IO.FileInfo file = new System.IO.FileInfo(path);
Microsoft.Win32.RegistryKey rk = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(file.Extension.ToLower());
if (rk != null && rk.GetValue("Content Type") != null)
{
contentType = rk.GetValue("Content Type").ToString();
}
else
{
contentType = "application/octet-type";
}
//Parameters to file are
//1. The File Path on the File Server
//2. The content type MIME type
//3. The parameter for the file save by the browser
return File(file.FullName, contentType, file.Name);
}
else
{
return null;
}
}
What needs to be done to fix this where we can perform this functionality?
You can remove the Authentication mode = windows line since you are using forms authentication. Use the impersonation and make sure the account has read access to the network location you are trying to access. that should work.
http://www.codeproject.com/Articles/4051/Windows-Impersonation-using-C

Microsoft Interop Outlook c# - invalidcastexception?

Suddenly getting a System.invalidcastexception: unable to cast COM object of type 'system._object' to interface type 'Microsoft.office.interop.outlook.mailitem' ... to a program I wrote that was working fine and now BAM! Exception.
Not sure why... please note I'm a novice programmer.
Here's a snippet of coding where I'm using the Outlook things :
using Microsoft.Office.Interop.Outlook;
static Microsoft.Office.Interop.Outlook.Application app = null;
static _NameSpace ns = null;
static MailItem item = null;
static MAPIFolder inboxFolder = null;
static MAPIFolder dest = null;
static void SendMail(string mailSubject, string htmlMailBody, string mailTo)
{
Microsoft.Office.Interop.Outlook.Application outlookApp = new Microsoft.Office.Interop.Outlook.Application();
NameSpace outlookNS = outlookApp.GetNamespace("MAPI");
outlookNS.Logon(Missing.Value, Missing.Value, true, true);
MailItem oMsg = (MailItem)outlookApp.CreateItem(OlItemType.olMailItem);
oMsg.To = mailTo;
oMsg.Recipients.ResolveAll();
StreamReader sr = new StreamReader(#"C:\Users\" + WindowsIdentity.GetCurrent().Name.Split('\\')[1] + #"\AppData\Roaming\Microsoft\Signatures\Default.htm");
string signature = sr.ReadToEnd();
oMsg.Subject = mailSubject;
oMsg.HTMLBody = htmlMailBody + "<br><br>" + signature + "</font>";
oMsg.Save();
((Microsoft.Office.Interop.Outlook._MailItem)oMsg).Send();
oMsg = null;
outlookNS = null;
outlookApp = null;
}
app = new Microsoft.Office.Interop.Outlook.Application();
ns = app.GetNamespace("MAPI");
ns.Logon(null, null, false, false);
inboxFolder = ns.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);
#region match - convert - extract
foreach (string tifFile in Directory.GetFiles(workFolder, "*.tif", SearchOption.TopDirectoryOnly))
{
string currentFile = Path.GetFileNameWithoutExtension(tifFile);
for (int i = 1; i <= inboxFolder.Items.Count; i++)
{
//##############CODE CRASHES HERE##############
item = (MailItem)inboxFolder.Items[i];
// item = inboxFolder.Items[i];
if (item.Body != "")
{
if ((item.Body.Contains("Box Number =")) && (item.Body.Contains("Contract ID = ")) && (item.Body.Contains("Branch = ")) && (item.Body.Contains(currentFile.Replace('_', '/'))))
{
// matchFound = true;
MailStack current = new MailStack();
Console.WriteLine("________________________");
Console.WriteLine("File matched \t\t:\t" + currentFile + ".tif");
I've looked around but can't make much sense of the answers available.
any help appreciated.
Try this...
item = inboxFolder.Items[i] as MailItem;
if (item != null)
{
// ...
}

Visual Studio macro: Find files that aren't included in the project?

I'd like to write a macro to crawl through the files in my project directory and find files that aren't included in the project.
In playing around with the DTE object, I see that the Project object has ProjectItems; if a ProjectItem represents a directory, then it has its own ProjectItems collection. This gives me all files that are included in the project.
So I could crawl recursively through each ProjectItems collection, and for each ProjectItem that's a directory, check to see if there are files in the file system that don't have a corresponding ProjectItem. This seems clumsy, though.
Any ideas of a simpler way to approach this?
Here is the C# version of your code:
public static void IncludeNewFiles()
{
int count = 0;
EnvDTE80.DTE2 dte2;
List<string> newfiles;
dte2 = (EnvDTE80.DTE2)System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE.10.0");
foreach (Project project in dte2.Solution.Projects)
{
if (project.UniqueName.EndsWith(".csproj"))
{
newfiles = GetFilesNotInProject(project);
foreach (var file in newfiles)
project.ProjectItems.AddFromFile(file);
count += newfiles.Count;
}
}
dte2.StatusBar.Text = String.Format("{0} new file{1} included in the project.", count, (count == 1 ? "" : "s"));
}
public static List<string> GetAllProjectFiles(ProjectItems projectItems, string extension)
{
List<string> returnValue = new List<string>();
foreach(ProjectItem projectItem in projectItems)
{
for (short i = 1; i <= projectItems.Count; i++)
{
string fileName = projectItem.FileNames[i];
if (Path.GetExtension(fileName).ToLower() == extension)
returnValue.Add(fileName);
}
returnValue.AddRange(GetAllProjectFiles(projectItem.ProjectItems, extension));
}
return returnValue;
}
public static List<string> GetFilesNotInProject(Project project)
{
List<string> returnValue = new List<string>();
string startPath = Path.GetDirectoryName(project.FullName);
List<string> projectFiles = GetAllProjectFiles(project.ProjectItems, ".cs");
foreach (var file in Directory.GetFiles(startPath, "*.cs", SearchOption.AllDirectories))
if (!projectFiles.Contains(file)) returnValue.Add(file);
return returnValue;
}
Thanks to #JaredPar and #lpthnc for pointing me in the right direction. I ended up using an approach very similar to what #JaredPar outlines above. Here's my working macro FWIW.
Imports System.IO
Imports System.Collections.Generic
Imports EnvDTE
Public Module Main
Sub IncludeNewFiles()
Dim Count As Integer = 0
For Each Project As Project In DTE.Solution.Projects
If Project.UniqueName.EndsWith(".vbproj") Then
Dim NewFiles As List(Of String) = GetFilesNotInProject(Project)
For Each File In NewFiles
Project.ProjectItems.AddFromFile(File)
Next
Count += NewFiles.Count
End If
Next
DTE.StatusBar.Text = String.Format("{0} new file{1} included in the project.", Count, If(Count = 1, "", "s"))
End Sub
Private Function GetAllProjectFiles(ByVal ProjectItems As ProjectItems, ByVal Extension As String) As List(Of String)
GetAllProjectFiles = New List(Of String)
For Each ProjectItem As ProjectItem In ProjectItems
For i As Integer = 1 To ProjectItem.FileCount
Dim FileName As String = ProjectItem.FileNames(i)
If Path.GetExtension(fileName).ToLower = Extension Then
GetAllProjectFiles.Add(fileName)
End If
Next
GetAllProjectFiles.AddRange(GetAllProjectFiles(ProjectItem.ProjectItems, Extension))
Next
End Function
Private Function GetFilesNotInProject(ByVal Project As Project) As List(Of String)
Dim StartPath As String = Path.GetDirectoryName(Project.FullName)
Dim ProjectFiles As List(Of String) = GetAllProjectFiles(Project.ProjectItems, ".vb")
GetFilesNotInProject = New List(Of String)
For Each file In Directory.GetFiles(StartPath, "*.vb", SearchOption.AllDirectories)
If Not ProjectFiles.Contains(file) Then GetFilesNotInProject.Add(file)
Next
End Function
End Module
The approach I would take is to
Enumerate the file system looking for all files
Check and see if the given file has an associated project item.
Here is a quick bit of sample code
Function ContainsItem(p as Project, fileName as String) As Boolean
Try
Return p.ProjectItems.Item(fileName)
Catch ex As ArgumentException
Return False
End Try
End Function
Function CotainsItem(dte as DTE, fileName as String) As Boolean
For Each p As Project in dte.Solution.Projects
Return ContainsItem(p, fileName)
Next
End Function
Function GetFilesNotInProject(dte as DTE, startPath as String) as List(Of String)
Dim list As New List(Of String)
Dim files = Directory.GetFiles(startPath, "*.cs", SearchOPtions.AllDirectories)
For Each file in files
If Not ContainsItem(dte, file) Then
list.Add(file)
End If
Next
Return list
End Function
I'd go with PowerShell. The PowerShell script in my other post will do this for you. The script will get the list of included files from the project file and compare that against the files on disk. You will get the set of files that are on disk but not included in the project. You can either delete them or pend them as deletes for TFS.
https://stackoverflow.com/a/23420956/846428

Resources