How can I simply determine if simple or extended MAPI is loaded.
Because I want to diable my add in wenn simple MAPI is loaded.
I'm working with Add-In Express and Redemption.dll.
Using the Windows "Send To" command actually integrates with SendMail.dll. AFAIK you can't intercept these calls to do something custom, but you can add your own shortcuts in the context menu:
http://www.slipstick.com/outlook/create-a-custom-send-to-shortcut/
What about this solution? Could this leading to problems?
Outlook.Application outlookApp = null;
Outlook.Explorer outExp = null;
try
{
outlookApp = (Outlook.Application)AddinModule.CurrentInstance.OutlookApp;
outExp = outlookApp.ActiveExplorer() as Outlook.Explorer;
if (outExp != null)
{
// extended stuff
} else {
// simple stuff
}
}
Related
I have just started learning how to program add-ins for Outlook using Visual Studio. I am having a hard time finding resources to read up on VSTO. How can I cannot modify the default fonts for "New mail messages" and "Replying or forwarding messages" under Personal Stationery in Outlook?
Revised my post to include the solution:
I am using code from this link (https://pcloadletter.co.uk/2010/05/19/outlook-default-font-and-signature/) and converted to c#. For those that are trying to do the same, here is how I did it.
private void SetFont()
{
RegistryKey key = Registry.CurrentUser.OpenSubKey(#"SOFTWARE\Microsoft\Office\16.0\Common\MailSettings", true);
// set the font in Outlook and then export it from the registry. Use that value for our code.
string ComposeFontSimple = #"3c,00,00,00,1f,00,00,f8,00,00,00,00,c8,00,00,00,00,00,
00,00,ff,ff,00,dd,00,22,41,72,69,61,6c,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00";
byte[] arrComposeFontSimpleBin = ArrayHexToDec(ComposeFontSimple.Split(','));
key.SetValue("ComposeFontSimple", arrComposeFontSimpleBin, RegistryValueKind.Binary);
}
public static byte[] ArrayHexToDec(string[] arrHex)
{
byte[] arrDec = new byte[arrHex.GetUpperBound(0)];
for (int i = 0; i < arrHex.GetUpperBound(0); i++)
{
if (arrHex[i] == "00")
{
arrDec[i] = 0;
}
else
{
arrDec[i] = byte.Parse(arrHex[i], System.Globalization.NumberStyles.HexNumber);
}
}
return arrDec;
}
The settings are stored at HKCU\Software\Microsoft\Office\%s.0\Common\MailSettings.
The value you want is ReplyFontSimple - font size starts at offset 12, and name start at offset 0x1A (0x0 terminated string).
Outlook keeps its setting in the windows registry. Try using the Process Monitor for tracking where exactly Outlook saves its settings.
If we speak about making changes to Outlook mail items at runtime, the message body can be modified using three different ways:
Body.
HTMLBody.
The Word editor. The WordEditor property of the Inspector class returns an instance of the Word Document which represents the message body.
See Chapter 17: Working with Item Bodies for more information.
I'm writing an Outlook 2010 add-in with VSTO, one part of which will automatically add the correct email signature to a new AppointmentItem. The issue I've come across is how to determine which signature is the correct one. For example, I have 2 email signatures set up in Outlook, which have rules on use based on which address my email is coming from. How can I access these rules?
My issue is not with finding the signature files, but in applying the correct rules based on the user's settings. Any ideas?
You can access the rules by using the code below. You can loop through them and get the rule type and actions
app is the current instance of the Outlook.Application
Outlook.Rules rules= app.Session.DefaultStore.GetRules();
foreach (Outlook.Rule r in rules)
{
}
I ended up solving this by creating a dictionary object with the key being the email address and the value as the filepath:
private Dictionary<string, string> signatureDictionary()
{
string sigDataDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + #"\Microsoft\Signatures";
Dictionary<string, string> returnValue = new Dictionary<string,string>();
Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(#"Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging Subsystem\Profiles\Outlook\9375CFF0413111d3B88A00104B2A6676", false);
string[] str = key.GetSubKeyNames();
foreach (string s in str)
{
Microsoft.Win32.RegistryKey subKey = key.OpenSubKey(s, false);
if (subKey.GetValue("New Signature") != null)
{
returnValue.Add(System.Text.Encoding.Unicode.GetString(subKey.GetValue("Account Name") as
Byte[],0,(subKey.GetValue("Account Name") as Byte[]).Length - 2)
, Path.Combine(sigDataDir,System.Text.Encoding.Unicode.GetString(
subKey.GetValue("New Signature") as Byte[], 0, (subKey.GetValue("New Signature") as
Byte[]).Length - 2) + #".rtf"));
}
}
key.Close();
return returnValue;
}
This answer to a similar question initially pointed me in the right direction, and figuring out that the "New Signature" key is only populated when a signature has been set for that account. Undoubtedly there will be situations where this doesn't work, but it sorts it out for my current issue. Since I use the WordEditor when I'm editing emails in VSTO I use the RTF files in this function, but there are also .HTM and .TXT files in the same directory so you can use those if you prefer.
For connecting to webservices i wrote the following code.
WebClient wc = new WebClient();
wc.DownloadStringAsync(new Uri("http://www.Webservices.asmx"));
wc.DownloadStringCompleted += new DownloadStringCompletedEventHandler(wc_DownloadStringCompleted);
void wc_DownloadStringCompleted(object sender,DownloadStringCompletedEventArgs e)
{
Debug.WriteLine("Web service says: " + e.Result);
using (var reader = new StringReader(e.Result))
{
String str = reader.ReadToEnd();
}
}
by using above code Get the string result.But i want get the result in HTMLVisulaizer then i know the what are the methods having that webservice.then i can easily access the particular method.
Please tell me how to call a web service method in Windows phone 7?in webservice i am having 5 webmethods.how to get that and how to call the Particular webmenthod.
Please tell me thanks in advance.
#venkateswara Are you talking about obtaining a list of known WebReference methods so you know which one to call in you code? Do you not see the this of known method calls when you add the WebReference to your WP7 project? Since you will be developing the WP7 app in VS I can't see the reason you would want to do this. Even if you don't own the webservice yourself, you will need to connect to it from VS in order to add the reference to your project.
Below is the screen in VS2010 where a WebReference is added. The Operations are listed on the right.
Once added you can use the ObjectBrowser to understand how the methods should be called.
Please let me know if I have missed something from your question.
#Jason James
The first step:
You must add referent Services ,like Jason James has very detailed instructions .
step 2 :
You can open App.xaml.cs , in Functions Apps
public Apps()
{
// Global handler for uncaught exceptions.
UnhandledException += Application_UnhandledException;
// Show graphics profiling information while debugging.
if (System.Diagnostics.Debugger.IsAttached)
{
// Display the current frame rate counters.
Application.Current.Host.Settings.EnableFrameRateCounter = true;
// Show the areas of the app that are being redrawn in each frame.
//Application.Current.Host.Settings.EnableRedrawRegions = true;
// Enable non-production analysis visualization mode,
// which shows areas of a page that are being GPU accelerated with a colored overlay.
//Application.Current.Host.Settings.EnableCacheVisualization = true;
}
// You can declare objects here that you will use
//Examlpe: NameservicesReferent.(Function that returns services) = new NameservicesReferent.(Function that returns services)();
Ws_Function = new Nameservices.ServiceSoapClient();
}
step 3:
in Mainpage.xaml.cs
GlobalVariables.Ws_advertise.getLinkAdvertiseIndexCompleted += new EventHandler<advertise.getLinkAdvertiseIndexCompletedEventArgs>(Ws_advertise_getLinkAdvertiseIndexCompleted);
GlobalVariables.***NameWedservise***.getLinkAdvertiseIndexAsync("**parameters to be passed**");
step 4:
void Ws_advertise_getLinkAdvertiseIndexCompleted(object sender, advertise.getLinkAdvertiseIndexCompletedEventArgs e)
{
//function returns the results to you, the example here is an array
string[] array = null;
try
{
array = e.result;
if(array != null)
}
cath(exception ex)
{
}
finally
{
array = null;
GlobalVariables.Ws_advertise.getLinkAdvertiseIndexCompleted -= new EventHandler<advertise.getLinkAdvertiseIndexCompletedEventArgs>(Ws_advertise_getLinkAdvertiseIndexCompleted);
}
}
What is the alternative for DomainProjectPicker if I want to select a server plus its projects? I am aware of a new class called TeamProjectPicker, but that doesn't help me. Anyone know how to select the server from this type of dialog?
Thanks,TS.
As far as I can figure it out it's more or less the same as the DomainProjectPicker.
Here's a code sample of how I was working with it:
if (tpp.ShowDialog() == DialogResult.OK)
{
try
{
//here you get the TfsTeamProjectCollection (the TeamFoundationServer class is also obsolete)
TfsTeamProjectCollection tfsProj = tpp.SelectedTeamProjectCollection;
//here you authenticate
tfsProj.Authenticate();
}
etc...
You can use the TeamProjectPicker class from Microsoft.TeamFoundation.Client.dll. There is a great blog post that describes how to wrangle the dialog: Using the TeamProjectPicker API in TFS 2010
Here's the code sample for selecting multiple team projects:
Application.EnableVisualStyles(); // Makes it look nicer from a console app.
//"using" pattern is recommended as the picker needs to be disposed of
using (TeamProjectPicker tpp = new TeamProjectPicker(TeamProjectPickerMode.MultiProject, false))
{
DialogResult result = tpp.ShowDialog();
if (result == DialogResult.OK)
{
System.Console.WriteLine("Selected Team Project Collection Uri: " + tpp.SelectedTeamProjectCollection.Uri);
System.Console.WriteLine("Selected Projects:");
foreach(ProjectInfo projectInfo in tpp.SelectedProjects)
{
System.Console.WriteLine(projectInfo.Name);
}
}
}
If you don't care about the project and only want the user to be able to select a server and collection, use TeamProjectPickerMode.NoProject in the constructor.
How do I open a custom control panel programmatically, like custom.cpl? Specifically, how do I open a 64-bit cpl when running as 32-bit application?
Vista added support for canonical names so you don't have to hard code dll filenames and tab indexs
Example:
WinExec("%systemroot%\system32\control.exe /name Microsoft.WindowsUpdate", SW_NORMAL);
(Names are always in english)
See MSDN for a list
XP/2000 supports "control.exe mouse" and a few other keywords, see the same MSDN page for a list (You can probably find some undocumented ones by running strings on control.exe)
Since I didn't find a good answer here on SO, here's the solution of my research:
Start a new application "control" that gets the name of the control panel as its first parameter:
::ShellExecute(m_hWnd, NULL, _T("control.exe"), _T("access.cpl"), NULL, SW_SHOW);
just use this....
ProcessStartInfo startInfo = new ProcessStartInfo("appwiz.cpl");
startInfo.UseShellExecute = true;
Process.Start(startInfo);
Step1 :
Read System Directory from the machine.
Step2 :
Use Process to start ControlPanel
**Process.Start(System.Environment.SystemDirectory + #"\appwiz.cpl");**
As i previously mentioned in another Question:
If you type "Start Control" or "Control" into Command Prompt it will open Control Panel.
Therefore just run a Process.
This Code (Bellow) worked perfectly for me:
public Form1()
{
InitializeComponent();
}
#region Variables
Process p;
#endregion Variables
[...]
void myMethod()
{
try
{
p = new Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.UseShellExecute = false;
p.Start();
p.StandardInput.WriteLine("start control");
p.StandardInput.Flush();
p.StandardInput.Close();
Console.WriteLine(p.StandardOutput.ReadToEnd());
}
catch (Exception ex) { MessageBox.Show(ex.Message); }
}