Can't access public folders root - c#

I've recently coded a .NET Console app using C#. It's purpose was to read the emails within a specific folder, parse them for specific values and save them to a database.
Our email system, at the time I originally coded this, was Exchange 2003. However, I was made aware we would soon be upgrading to Exchange 2010: ergo, I built the code to work in both environments.
Following the migration to Exchange 2010, however, the app has broken.
The app uses the EWS API for 2010 functionality. When it attempts to use the ExchangeService's FindFolders method to find the publicfoldersroot, it throws an exception. Here's the code:
ExchangeService service = new ExchangeService();
FindFoldersResults findRootFldrs;
service.UseDefaultCredentials = true;
service.AutodiscoverUrl("xxxxx#xxxx.xxx", delegate(string x) {
return true; });
FolderView fview = new FolderView(100);
fview.Traversal = FolderTraversal.Deep;
findRootFldrs = service.FindFolders(WellKnownFolderName.PublicFoldersRoot,
fview);
The exception: ErrorInvalidSchemaVersionForMailboxVersion, aka:
The mailbox that was requested doesn't support the specified RequestServerVersion
I've attempted:
Setting the exchangeservice to 2007 (throws an exception: "An internal server error occurred. The operation failed.")
Giving myself the highest level of permission to the Public Folder (no effect)
Manually setting my credentials (no effect)
I can view the public folders in Outlook 2007; the publicfoldersroot property is available in the intellisense; the code works on local folders (I can parse my inbox).
My current thinking is that it's a setting on the recent setup of Exchange 2010: unfortunately that isn't really my field. The exception tells me it's trying to use a previous version of Exchange. Setting it to 2007 simply causes the code to fail with an internal server error.

Old post, but this turned out to be the answer for me: http://technet.microsoft.com/en-us/library/bb629522.aspx
Essentially the account used to connect with EWS had a mailbox in a mailbox database whose default public folder server was still Exchange 2003. Any and all attempts to enumerate public folders over EWS failed. Swapping it out for a 2010 backend server cured it instantly.

Have you tried esb.RequestServerVersion.Version = ExchangeVersionType. Exchange2010 (or SP1)

Change this line:
ExchangeService service = new ExchangeService();
to something like this:
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010);
or
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP1);
Depending on your version.

Related

Can't access user Exchange mailbox on certain machines

I'm trying to run the following code as my own user.
var email = UserPrincipal.Current.EmailAddress;
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2007_SP1);
service.AutodiscoverUrl(email);
FolderId inbox = new FolderId(WellKnownFolderName.Inbox, new Mailbox(email));
service.FindItems(inbox, new ItemView(1000));
This code works on one machine, but not on a new machine. Instead I get this exception
Microsoft.Exchange.WebServices.Data.ServiceResponseException was unhandled
HResult=-2146233088
Message=The specified object was not found in the store., The process failed to get the correct properties.
Source=Microsoft.Exchange.WebServices
StackTrace:
at Microsoft.Exchange.WebServices.Data.ServiceResponse.InternalThrowIfNecessary() in \\REDMOND\EXCHANGE\BUILD\E15\15.00.0913.015\SOURCES\sources\dev\EwsManagedApi\src\EwsManagedApi\Core\Responses\ServiceResponse.cs:line 277
at Microsoft.Exchange.WebServices.Data.MultiResponseServiceRequest`1.Execute() in \\REDMOND\EXCHANGE\BUILD\E15\15.00.0913.015\SOURCES\sources\dev\EwsManagedApi\src\EwsManagedApi\Core\Requests\MultiResponseServiceRequest.cs:line 166
at Microsoft.Exchange.WebServices.Data.ExchangeService.FindItems[TItem](IEnumerable`1 parentFolderIds, SearchFilter searchFilter, String queryString, ViewBase view, Grouping groupBy, ServiceErrorHandling errorHandlingMode) in \\REDMOND\EXCHANGE\BUILD\E15\15.00.0913.015\SOURCES\sources\dev\EwsManagedApi\src\EwsManagedApi\Core\ExchangeService.cs:line 832
at Microsoft.Exchange.WebServices.Data.ExchangeService.FindItems(FolderId parentFolderId, ViewBase view) in \\REDMOND\EXCHANGE\BUILD\E15\15.00.0913.015\SOURCES\sources\dev\EwsManagedApi\src\EwsManagedApi\Core\ExchangeService.cs:line 956
I can't really see any differences between the machines other than
The failing machine is a new install, so it might be missing some framework components or something?
I don't have admin rights on the failing machine, but I'm not running as admin on either machine.
The failing machine has Outlook 365 installed while the working machine has Outlook 2013 installed. I'm not sure why this would be an issue though, since they are both talking to the same Exchange server.
The really confusing thing is that I have two accounts configured in Outlook under Account Settings (the second one is a service account mailbox). If I change the email variable to the second account's email address, everything works fine. This is leading me to believe it's not strictly an issue with admin rights, but I can't quite figure out what the issue is.

C# DCOM event binding Unathorized Execption

For a project I am working on I have to interface with a third-party DCOM library. I started with COM interop and this worked just fine locally, then I switched to DCOM and now I keep getting an unauthorized access exception (0x80070005) when trying to bind an event handler to the exposed event. Below is a summary of what I do in code:
public void connect(string server)
{
object dcomObj = null;
var guidB = Guid.Parse("c8c1f57f-0d7c-40b3-b17c-2eac12512006");
var typ = Type.GetTypeFromCLSID(guidB, server, true);
object[] url = { new UrlAttribute(server) };
dcomObj = Activator.CreateInstance(typ, null, url);
user = (RemoteObjectInterface)dcomObj ;
user.getState(); //works fine locally and remotely
user.stateChange += this.User_StateChange; //only works locally
}
I tried setting every permission I could find on the web but I without success. Does anyone have an Idea as to why only the binding of events fails?
RemoteObjectInterface inherits from both the IRemoteObjectEvents and the IRemoteObject. These interface come from the interop ms generated for me when I imported the original dll.
The server is a windows server 2003 VM in virtual box with a bridged network adapter. On the server Everyone is admin (including guest) and limits are set to full access and defaults are set to full access. I am building and running my code on c# .net 4.5.2 from a Windows 10 machine using visual studio 2015.
The sample application that comes with the SDK also fails when I try to use it remotely, the server registers the user but the sample application never realizes that it logged in successfully, I suspect that this behaviour is related to the failing of event binding.
TL;DR I can get and use a remote object but when I try to add an event handler I get an unauthorized exception (0x80070005), why does this happen on event binding? And how do I fix it?
I had the same problem.
For me the issue was I had a AD running on the same device and had to disable the loopback check in the registry. Other solution could be better I assume, but for me the registry hack will do.

Read email content and move items between folders with Exchange 2010 and c#

I’m working on an application that must read the email content and move emails from one folder to another, these are the only two features that it must support. The mail server is Exchange 2010 and I have enough privileges to access the mailbox.
I’ve been seeing some posts about EWS Managed Code but I’m certainly lost in all this information. Can you shed some light on this and advise about the best approach to accomplish it?
Ps. Using VS 2015 and .net framework 4.5
Update: find below a quick test using the EWS Manage API
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2013);
//This will accept all certificates, regardless of why they are invalid
ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
service.Credentials = new WebCredentials("Administrator", "mypassword", "myexchangeserver.com");
service.Url = new Uri("https://myexchangeserver.com/EWS/Exchange.asmx");
EmailMessage email = new EmailMessage(service);
email.ToRecipients.Add("userid#myexchangeserver.com");
email.Subject = String.Format("HelloWorld at {0}", DateTime.Now);
email.Body = new MessageBody("This is the first email I've sent by using the EWS Managed API.");
email.Send();
I’m working on an application that must read the email content and move emails from one folder
Okay so you will need to use a Exchange Mailbox API to access Mailbox content, on Exchange 2010 the available API's that you could use to move a Message between folders would be MAPI (via the Outlook Object Model or Thirdparty library like Redemption) or Exchange Web Services (EWS). (other API's like POP,IMAP and Activesync would also work but are much harder to use).
To work out which is the best API to use you need to consider where your application is going to run eg if you building an code that run within outlook then using the OOM. If you building an application that is going to run on the server then use EWS.
I’ve been seeing some posts about EWS Managed Code but I’m certainly lost in all this information.
If your going to write and EWS app then using the Managed API is the best way to go, the best place is to jump into write some actual code eg start with
https://msdn.microsoft.com/en-us/library/office/dn567668(v=exchg.150).aspx
then try
https://msdn.microsoft.com/en-us/library/office/dn600291(v=exchg.150).aspx
Cheers
Glen

C# EWS API - Accessing items on different Exchange server than the server where account accessing is configured

I have an account created on Exchange Server A and I'm trying to access items on shared mailbox X configured on Exchange server B. I have required permissions to access mailbox X and I'm able to do it using MS Outlook, but not able to do it using EWS Managed API. I have used following code:
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2007_SP1);
service.Credentials = new WebCredentials("user.name#organization.com", "password");
service.Url = new Uri("https://organization.com/EWS/Exchange.asmx");
Mailbox somemailbox = new Mailbox("some.mailbox#organization.com");
FolderId folderInbox = new FolderId(WellKnownFolderName.Inbox, somemailbox);
FindFoldersResults findResults = service.FindFolders(folderInbox, new FolderView(int.MaxValue));
This returns an error: "The account accessing the resource must be on the same Mailbox Server version as the delegate account being accessed." pointing last line of the code (service.FindFolders).
At the beginning I thought that version of the servers are not compatible, but when I changed ExchangeVersion in line 1 of the code to any other than "Exchange2007_SP1" I got error message Exchange Server doesn't support the requested version., So I guess that this is not version related problem. I guess that in such case I would not be able to connect using MS Outlook which works fine.
I think that I'm missing something very easy, but I don't know what...
the problem is that you connect to the primary server. If you want to access the delegate-account you will have to change the ews-url to the ews-address of the server where the mailbox is stored. I have nearly the same scenario in my company and with diffrent urls it works fine for me. If your exchange-server is co configured properly you can use the autodiscover function 'service.Autodiscover()' of the managed api to get the right ews-address.

Control IIS 7 server from Windows 2003 server programmatically

We run various jobs using a Windows 2003 server. Some of these jobs send app pool commands to web servers running IIS 6 (recycle, start, stop). Now we have a Windows 2008 web server running IIS 7, and we want to send the same commands. This is all done using C#.
This is the code we use to send commands for IIS 6:
var methodToInvoke = "Stop"; // could be "Stop", "Start", or "Recycle"
var co = new ConnectionOptions
{
Impersonation = ImpersonationLevel.Impersonate,
Authentication = AuthenticationLevel.PacketPrivacy
};
var objPath = string.Format("IISApplicationPool.Name='W3SVC/AppPools/{0}'", appPoolName);
var scope = new ManagementScope(string.Format(#"\\{0}\root\MicrosoftIISV2", machineName), co);
using (var mc = new ManagementObject(objPath))
{
mc.Scope = scope;
mc.InvokeMethod(methodToInvoke, null, null);
}
This code doesn't work for IIS 7 due to underlying changes, so we're currently trying this:
using (ServerManager serverManager = ServerManager.OpenRemote(machineName))
{
var appPool = serverManager.ApplicationPools[appPoolName];
if (appPool != null)
{
appPool.Stop(); // or app.Start() or app.Recycle()
serverManager.CommitChanges();
}
}
The above code works fine on my workstation, which runs Windows 7 (and, thus, IIS 7.5). However, it does not work when I deploy this code to our application server. It get this error:
System.InvalidCastException:
Unable to cast COM object of type 'System.__ComObject' to interface type
'Microsoft.Web.Administration.Interop.IAppHostWritableAdminManager'.
This operation failed because the QueryInterface call on the COM component for the
interface with IID '{FA7660F6-7B3F-4237-A8BF-ED0AD0DCBBD9}' failed due to the following error:
Interface not registered (Exception from HRESULT: 0x80040155).
From my research, this is due to the fact that IIS 7 is not available on the Windows Server 2003 server. (I did include the Microsoft.Web.Administration.dll file.)
So my questions are:
Is it possible for the above code for IIS 7 to work at all from a Windows 2003 server?
If no to #1, is there a better way of doing this?
From reading around it doesn't appear to be possible to do what you're looking for. It's not enough to include the dll files.
According to http://forums.iis.net/t/1149274.aspx..
In order to use Microsoft.Web.Administration you need to have IIS installed, at the bare minimum you need to install the Configuration API's which are brought through installing the Management Tools.
Unfortunately there is no SDK that enables this and it has several dependencies on other components that wouldn't let you just take it to another machine and make it work (such as COM objects, DLL's, etc).
I'd be interested in knowing if you've found a way round this.
Thanks
Try controlling the IIS pool with DirectoryEntry instead.
See this topic:
Check the status of an application pool (IIS 6) with C#
Microsoft.Web.Administration, it relies on System.Web.dll which was provided by framework 4, not client profile.

Categories