How to disable "Exchange ActiveSync" while creating a new mailbox using C# - exchange-server

How should I disable "Exchange ActiveSync" using C# code while creating a new mailbox in Microsoft Exchange 2010?

You can execute powershell command to disable exchange active sync from c# code.
C# code looks like this:
var command = "Get-Mailbox \"name\" | Set-CASMailbox -ActiveSyncEnabled $false";
var runspaceConfig = RunspaceConfiguration.Create();
PSSnapInException snapInException = null;
runspaceConfig.AddPSSnapIn("Microsoft.Exchange.Management.PowerShell.E2010", out snapInException);
using (var runspace = RunspaceFactory.CreateRunspace(runspaceConfig))
{
runspace.Open();
using (var pipeline = runspace.CreatePipeline())
{
pipeline.Commands.AddScript(command);
var results = pipeline.Invoke();
// You can handle results here
}
runspace.Close();
}

Related

Microsoft.Office.Interop.Outlook does not work on web server but works on local machine

I am using below code in the button event, so that user can send mail through self machine outlook directly (nuget Microsoft. Office. Interop.Outlook). Code is working when I am debugging below code in my localhost and send mail from outlook. But problem is when I deployed the code into web server and browse through IE from my work station, mail not send through outlook.
This error message show in log:
Retrieving the COM class factory for component with CLSID {0006F03A-0000-0000-C000-000000000046} failed due to the following error: 80070005 Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)).
How can I resolve this issue?
Web application reside into web server and users will access the application from IE and then they will send mail through self machine outlook.
public void SendEmailOutlook(string mailToRecipients, string mailCCRecipients, string subjectLine, [Optional] string attachments, string HTMLBody)
{
try
{
Microsoft.Office.Interop.Outlook.Application oApp = new Microsoft.Office.Interop.Outlook.Application();
Microsoft.Office.Interop.Outlook.MailItem oMsg = oApp.CreateItem(Microsoft.Office.Interop.Outlook.OlItemType.olMailItem);
Outlook.Recipients oRecips = oMsg.Recipients;
List<string> oTORecip = new List<string>();
List<string> oCCRecip = new List<string>();
var ToRecip = mailToRecipients.Split(',');
var CCRecip = mailCCRecipients.Split(',');
foreach (string ToRecipient in ToRecip)
{
oTORecip.Add(ToRecipient);
}
foreach (string CCRecipient in CCRecip)
{
oCCRecip.Add(CCRecipient);
}
foreach (string to in oTORecip)
{
Outlook.Recipient oTORecipt = oRecips.Add(to);
oTORecipt.Type = (int)Outlook.OlMailRecipientType.olTo;
oTORecipt.Resolve();
}
foreach (string cc in oCCRecip)
{
Outlook.Recipient oCCRecipt = oRecips.Add(cc);
oCCRecipt.Type = (int)Outlook.OlMailRecipientType.olCC;
oCCRecipt.Resolve();
}
oMsg.Subject = subjectLine;
if (attachments.Length > 0)
{
string sDisplayName = "MyAttachment";
int iPosition = 1;
int iAttachType = (int)Outlook.OlAttachmentType.olByValue;
var Sendattachments = attachments.Split(',');
foreach (var attachment in Sendattachments)
{
Outlook.Attachment oAttach = oMsg.Attachments.Add(attachment, iAttachType, iPosition, sDisplayName);
}
}
if (HTMLBody.Length > 0)
{
oMsg.HTMLBody = HTMLBody;
}
oMsg.Save();
oMsg.Send();
oTORecip = null;
oCCRecip = null;
oMsg = null;
oApp = null;
}
catch (Exception e)
{
//print(e.Message);
}
}
Outlook, just like every other Office app, cannot be used from a service (such as IIS).
The Considerations for server-side Automation of Office article states the following:
Microsoft does not currently recommend, and does not support, Automation of Microsoft Office applications from any unattended, non-interactive client application or component (including ASP, ASP.NET, DCOM, and NT Services), because Office may exhibit unstable behavior and/or deadlock when Office is run in this environment.
If you are building a solution that runs in a server-side context, you should try to use components that have been made safe for unattended execution. Or, you should try to find alternatives that allow at least part of the code to run client-side. If you use an Office application from a server-side solution, the application will lack many of the necessary capabilities to run successfully. Additionally, you will be taking risks with the stability of your overall solution.
As a possible workaround you may consider using EWS or any other REST API (for example, Graph API) if you deal with Exchange server profiles only. See Explore the EWS Managed API, EWS, and web services in Exchange for more information.
I've had this issue too."Retrieving the COM class factory for component with CLSID {0006F03A-0000-0000-C000-000000000046} failed due to the following error: 80070005 Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))."
Server environment:Windows server 2019&iis
Local machine:Windows 10&iis
Tip:The Microsoft office doesn't support that use OutWork IIS or Asp.net
So,I give you right answer(It's worked):
1、Run "win+R" ,then inuput 'Dcomcnfg'
2、As this pic:
enter image description here

Sending emails from Visual Studio using Exchange Web Service

I am trying to send email using Exchange Web Service (Microsoft.Exchange.WebServices.NETStandard) and it is working when I am using Linqpad.
But the same code does not send email when running in Visual Studio. There is no error either.
I am running either app as myself.
Appreciate any idea to troubleshoot this issue.
var service = new ExchangeService(ExchangeVersion.Exchange2016)
{
Url = new Uri("..."),
Credentials = CredentialCache.DefaultNetworkCredentials
};
var address = "...";
var message = new EmailMessage(service)
{
From = address,
Subject = "test",
Body = new MessageBody(BodyType.Text, "test")
};
message.ToRecipients.Add(address);
message.Send();
I changed the Nuget reference in Visual Studio to Microsoft.Exchange.WebService and that solved the issue.

How to unit test Azure Functions in Visual Studio

I am using Visual Studio to create Azure Functions. I can create, publish and run functions manually. If I set my Function project to Start Up and run, I host starts. How do I get the Host to start when using MSTest ?
I want to write a test using RestSharp and invoke the functions during the tests - the way the actual applicaion will work. It seems I need a way to get MSTest to start the Azure Function Host.
I was hoping to find an approach similar to debugging Asp.Net/SOAP in older versions of VS where the MSTest engine would start the IISExpress and attach VS to the Asp.Net projects. Edit and continue was supported.
I have worked out the following approaches, so far:
RestSharp Code:
var url = $"http://localhost:7071/api";
var functionKey = "this value is ignored by 'Azure Functions Core Tools' ";
var client = new RestSharp.RestClient(url);
var request = new RestSharp.RestRequest("GetConnectionString", RestSharp.Method.POST);
request.AddHeader("x-functions-key", functionKey);
var response = client.Execute<string>(request);
Option 1:
Run 2nd instance of VS and run the Functions.
Update code to reflect url paths displayed by Azure Functions Core Tools.
Edit and continue works.
Option 2:
Add this class to UnitTest project:
Attach to func.exe process to debug functions
Edit and continue do not work.
[TestClass]
public class Initializer
{
static System.Diagnostics.Process process { get; set; }
[AssemblyInitialize]
public static void Initialize(TestContext context)
{
//process does not use the WorkingDirectory properly with %userprofile%
var userprofile = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
var path = $#"{userprofile}\source\repos\mypro\...\myproj.Functions\bin\Debug\netcoreapp3.1";
var startInfo = new ProcessStartInfo
{
FileName = #"cmd.exe",
Arguments = #"/C ""%localappdata%\AzureFunctionsTools\Releases\3.2.0\cli_x64\func.exe host start --port 7071 --pause-on-error""",
//RedirectStandardInput = true,
//RedirectStandardOutput = true,
//RedirectStandardError = true,
//UseShellExecute = false,
UseShellExecute = true,
WorkingDirectory = path
};
process = new System.Diagnostics.Process()
{
StartInfo = startInfo
};
process.Start();
// Thread.Sleep(3000);
}
[AssemblyCleanup]
public static void Cleanup()
{
process.CloseMainWindow();
}
}
Option 3:
Start func.exe process
Working Folder: ...\source\repos\xxx\xxx\xxx.Functions\bin\Debug\netcoreapp3.1\
Command Line:
"C:\Users\username\AppData\Local\AzureFunctionsTools\Releases\3.2.0\cli_x64\func.exe" host start --port 7071 --pause-on-error
Attach to func.exe process.
Edit and continue does not work.

How to automate Package Manager Console in Visual Studio 2013

My specific problem is how can I automate "add-migration" in a build process for the Entity Framework. In researching this, it seems the mostly likely approach is something along the lines of automating these steps
Open a solution in Visual Studio 2013
Execute "Add-Migration blahblah" in the Package Manager Console (most likely via an add-in vsextention)
Close the solution
This initial approach is based on my own research and this question, the powershell script ultimately behind Add-Migration requires quite a bit of set-up to run. Visual Studio performs that setup automatically when creating the Package Manager Console and making the DTE object available. I would prefer not to attempt to duplicate that setup outside of Visual Studio.
One possible path to a solution is this unanswered stack overflow question
In researching the NuGet API, it does not appear to have a "send this text and it will be run like it was typed in the console". I am not clear on the lines between Visual Studio vs NuGet so I am not sure this is something that would be there.
I am able to find the "Pacakage Manager Console" ironically enough via "$dte.Windows" command in the Package Manager Console but in a VS 2013 window, that collection gives me objects which are "Microsoft.VisualStudio.Platform.WindowManagement.DTE.WindowBase". If there is a way stuff text into it, I think I need to get it to be a NuGetConsole.Implementation.PowerConsoleToolWindow" through reviewing the source code I am not clear how the text would stuffed but I am not at all familiar with what I am seeing.
Worst case, I will fall back to trying to stuff keys to it along the lines of this question but would prefer not to since that will substantially complicate the automation surrounding the build process.
All of that being said,
Is it possible to stream commands via code to the Package Manager Console in Visual Studio which is fully initialized and able to support an Entity Framework "add-migration" command?
Thanks for any suggestions, advice, help, non-abuse in advance,
John
The approach that worked for me was to trace into the entity framework code starting in with the AddMigrationCommand.cs in the EntityFramework.Powershell project and find the hooks into the EntityFramework project and then make those hooks work so there is no Powershell dependency.
You can get something like...
public static void RunIt(EnvDTE.Project project, Type dbContext, Assembly migrationAssembly, string migrationDirectory,
string migrationsNamespace, string contextKey, string migrationName)
{
DbMigrationsConfiguration migrationsConfiguration = new DbMigrationsConfiguration();
migrationsConfiguration.AutomaticMigrationDataLossAllowed = false;
migrationsConfiguration.AutomaticMigrationsEnabled = false;
migrationsConfiguration.CodeGenerator = new CSharpMigrationCodeGenerator(); //same as default
migrationsConfiguration.ContextType = dbContext; //data
migrationsConfiguration.ContextKey = contextKey;
migrationsConfiguration.MigrationsAssembly = migrationAssembly;
migrationsConfiguration.MigrationsDirectory = migrationDirectory;
migrationsConfiguration.MigrationsNamespace = migrationsNamespace;
System.Data.Entity.Infrastructure.DbConnectionInfo dbi = new System.Data.Entity.Infrastructure.DbConnectionInfo("DataContext");
migrationsConfiguration.TargetDatabase = dbi;
MigrationScaffolder ms = new MigrationScaffolder(migrationsConfiguration);
ScaffoldedMigration sf = ms.Scaffold(migrationName, false);
}
You can use this question to get to the dte object and from there to find the project object to pass into the call.
This is an update to John's answer whom I have to thank for the "hard part", but here is a complete example which creates a migration and adds that migration to the supplied project (project must be built before) the same way as Add-Migration InitialBase -IgnoreChanges would:
public void ScaffoldedMigration(EnvDTE.Project project)
{
var migrationsNamespace = project.Properties.Cast<Property>()
.First(p => p.Name == "RootNamespace").Value.ToString() + ".Migrations";
var assemblyName = project.Properties.Cast<Property>()
.First(p => p.Name == "AssemblyName").Value.ToString();
var rootPath = Path.GetDirectoryName(project.FullName);
var assemblyPath = Path.Combine(rootPath, "bin", assemblyName + ".dll");
var migrationAssembly = Assembly.Load(File.ReadAllBytes(assemblyPath));
Type dbContext = null;
foreach(var type in migrationAssembly.GetTypes())
{
if(type.IsSubclassOf(typeof(DbContext)))
{
dbContext = type;
break;
}
}
var migrationsConfiguration = new DbMigrationsConfiguration()
{
AutomaticMigrationDataLossAllowed = false,
AutomaticMigrationsEnabled = false,
CodeGenerator = new CSharpMigrationCodeGenerator(),
ContextType = dbContext,
ContextKey = migrationsNamespace + ".Configuration",
MigrationsAssembly = migrationAssembly,
MigrationsDirectory = "Migrations",
MigrationsNamespace = migrationsNamespace
};
var dbi = new System.Data.Entity.Infrastructure
.DbConnectionInfo("ConnectionString", "System.Data.SqlClient");
migrationsConfiguration.TargetDatabase = dbi;
var scaffolder = new MigrationScaffolder(migrationsConfiguration);
ScaffoldedMigration migration = scaffolder.Scaffold("InitialBase", true);
var migrationFile = Path.Combine(rootPath, migration.Directory,
migration.MigrationId + ".cs");
File.WriteAllText(migrationFile, migration.UserCode);
var migrationItem = project.ProjectItems.AddFromFile(migrationFile);
var designerFile = Path.Combine(rootPath, migration.Directory,
migration.MigrationId + ".Designer.cs");
File.WriteAllText(designerFile, migration.DesignerCode);
var designerItem = project.ProjectItems.AddFromFile(migrationFile);
foreach(Property prop in designerItem.Properties)
{
if (prop.Name == "DependentUpon")
prop.Value = Path.GetFileName(migrationFile);
}
var resxFile = Path.Combine(rootPath, migration.Directory,
migration.MigrationId + ".resx");
using (ResXResourceWriter resx = new ResXResourceWriter(resxFile))
{
foreach (var kvp in migration.Resources)
resx.AddResource(kvp.Key, kvp.Value);
}
var resxItem = project.ProjectItems.AddFromFile(resxFile);
foreach (Property prop in resxItem.Properties)
{
if (prop.Name == "DependentUpon")
prop.Value = Path.GetFileName(migrationFile);
}
}
I execute this in my project template's IWizard implementation where I run a migration with IgnoreChanges, because of shared entites with the base project. Change scaffolder.Scaffold("InitialBase", true) to scaffolder.Scaffold("InitialBase", false) if you want to include the changes.

Testing SharePoint List Workflow from Visual Studio 2010

I am trying to create a custom workflow in Visual Studio 2010 for SharePoint 2010 and have run into a problem. I have figured out how to deploy the workflow to the SharePoint site, but executing it results in an error. However, the error message is completely non-descriptive, so I want to find out if there is a way to execute it from Visual Studio so I can see where it fails, and possibly why.
I'm trying to simply create a new subsite based on a given ListItem.Title information.
How is it you go about debugging?
For reference, here is my code
class CreateSubsite : System.Workflow.ComponentModel.Activity
{
protected override System.Workflow.ComponentModel.ActivityExecutionStatus
Execute(System.Workflow.ComponentModel.ActivityExecutionContext executionContext)
{
createSite();
return System.Workflow.ComponentModel.ActivityExecutionStatus.Closed;
}
public void createSite()
{
using (SPSite currentSite = SPContext.Current.Site)
{
using (SPWeb currentWeb = SPContext.Current.Web)
{
SPList currentList = SPContext.Current.List;
SPListItem currentListItem = SPContext.Current.ListItem;
WorkflowContext workflow = new WorkflowContext();
SPSite parentSite = new SPSite(workflow.CurrentWebUrl);
SPWeb newSite = currentSite.AllWebs.Add(
currentListItem.Title.Replace(" ", "_"),
currentListItem.Title,
String.Empty, currentWeb.Language, "CI Template", false, false
);
}
}
}
}
Try to remove Using keyword from your code .You should not dispose your SPSite and SPWeb when you use SPContext because disposing of that object might actually break the workflow as it may still need a reference to that object for later use.
just rewrite your code without use using
public void createSite() {
SPSite currentSite = SPContext.Current.Site
SPWeb currentWeb = SPContext.Current.Web
//.... Rest of your code
Hope that help
Regards.

Resources