VSTO Outlook: How to get the StoreID from a Outlook.MailItem - outlook

I have several accounts configured in Outlook. Now I am trying to get the StoreID of an Outlook mailItem. For example if I select a message from the inbox folder of an account, let's say, account1, I want to get its StoreID, and if I select a message from the inbox folder of another Outlook account, let's say, account2, I want to get the its corresponding StoreID.
I have created an extension method to get the StoreID:
public static string GetStoreID(this Outlook.MailItem omi)
{
Outlook.Folder folder = null;
Outlook.Store store = null;
string storeID = null;
try
{
folder = (Outlook.Folder)omi.Parent;
store = folder.Store;
storeID = store.StoreID;
}
catch (Exception ex)
{
Log.Error("GetStoreID: An error occurred while getting mail item storeID. " + ex.ToString());
}
finally
{
folder = null;
store = null;
}
return storeID;
}
Is it correct or is there any other way which is better?

Your method is fine. Or you can make it even faster - simply retrieve the PR_STORE_ENTRYID MAPI property (DASL name "http://schemas.microsoft.com/mapi/proptag/0x0FFB0102") using MailItem.PropertyAccessor.GetProperty and convert it to a string using MailItem.PropertyAccessor.BinaryToString.

Your code works, so it appears you are asking for any other approach you could take to get the StoreID string.
Whether one approach is "better" than any other approach is purely subjective and entirely context specific.
Another way you could do this, would be to instead get the StoreID from the Explorer object (rather than the MailItem). If you have an "Explorer Wrapper" class in your add-in, you could have something like the following for your backing-fields and constructor:
private Outlook.Explorer _myExplorer;
private Outlook.Folder _myFolder;
private Outlook.Store _myStore;
private string _myStoreID;
public OutlookExplorerWrapper(Outlook.Explorer explorer)
{
_myExplorer = explorer;
_myFolder = (Outlook.Folder)_myExplorer.CurrentFolder;
_myStore = _myFolder.Store;
_myStoreID = _myStore.StoreID;
}

Related

How to know the download link of a windows phone 8 application

I'm developing windows phone 8 application. In which I have to share the application's download link on Facebook and Twitter.
Before publishing the application on to the windows phone store, How could I know the download link of the application.
Because we have to implement the share functionality before publishing the application.
I'm looking forward for your responses.
Thanks & Regards,
Suresh
Basically your application download link format is as follow :
http://windowsphone.com/s?appid=<ApplicationId>
with <ApplicationId> is value of ProductID attribute of App element in WMAppManifest.xml file. That ProductID in WMAppManifest.xml will be overridden when you submit the Apps to Marketplace, so avoid hardcoding it. This post demonstrates how to get <ApplicationId> from manifest file as well as how to share it using Microsoft.Phone.Tasks.ShareLinkTask.
UPDATE :
To summarize, create a helper class to read ApplicationID from WMAppManifest.xml file :
public class DeepLinkHelper
{
private const string AppManifestName = "WMAppManifest.xml";
private const string AppNodeName = "App";
private const string AppProductIDAttributeName = "ProductID";
public static string BuildApplicationDeepLink()
{
var applicationId = Guid.Parse(GetManifestAttributeValue(AppProductIDAttributeName));
return BuildApplicationDeepLink(applicationId.ToString());
}
public static string BuildApplicationDeepLink(string applicationId)
{
return #"http://windowsphone.com/s?appid=" + applicationId;
}
public static string GetManifestAttributeValue(string attributeName)
{
var xmlReaderSettings = new XmlReaderSettings
{
XmlResolver = new XmlXapResolver()
};
using (var xmlReader = XmlReader.Create(AppManifestName, xmlReaderSettings))
{
xmlReader.ReadToDescendant(AppNodeName);
if (!xmlReader.IsStartElement())
{
throw new FormatException(AppManifestName + " is missing " + AppNodeName);
}
return xmlReader.GetAttribute(attributeName);
}
}
}
Then you can get/share download link this way :
new Microsoft.Phone.Tasks.ShareLinkTask()
{
Title = "My Application Deep Link",
Message = "My Application Deep Link",
LinkUri = new Uri(DeepLinkHelper.BuildApplicationDeepLink())
}.Show();
Credit to Pedro Lamas for all above codes.

Serialization PhoneApplicationPage Windows Phone

i hace a class named "Conexion" an i keep all the info of my app there, what i want its to save the object of the class to a file when the user presses the windows key, but the app crashes because it says the obect "delegado" has a problem reflecting his type. The type of this object is "PhoneApplicationPage" , it seems it cannot be serialized. The object keeps track of what page did the request.
so im requesting your help to see if theres a solution, that doesn make me redo the app, because i dont have time.
heres the code of the methods i use to save and load the data.
public void save() {
IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication();
IsolatedStorageFileStream stream = storage.CreateFile(fileName);
DateTime currTime = DateTime.Now;
this.timeOff = currTime.ToString();
XmlSerializer xml = new XmlSerializer(this.GetType());
xml.Serialize(stream, this);
stream.Close();
stream.Dispose();
}
public Conexion load() {
IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication();
Conexion conn;
if (storage.FileExists(fileName))
{
IsolatedStorageFileStream stream = storage.OpenFile(fileName, System.IO.FileMode.Open);
XmlSerializer xml = new XmlSerializer(typeof(Conexion));
conn = xml.Deserialize(stream) as Conexion;
stream.Close();
DateTime currTime = DateTime.Now;
DateTime checkTime = DateTime.Parse(timeOff).AddMinutes(lapso);
if (DateTime.Compare(checkTime, currTime) >= 0)
{
Console.WriteLine("sesion valida");
}
else {
conn.reseteaSingletonConexion();
}
stream.Dispose();
}
else
{
conn= new Conexion();
}
return conn;
}
thanks in advance
Edit:
Well ignoring the object "delegado" stopped the app from crashing, but now , when i load the info , the object cannot be deserialized , it seems it marks 2 details in the same error:
There is an error in XML document (2, 2).
Conexion cannot be serialized because it does not have a parameterless constructor.
but the class does have a parameterless constructor.
any idea?
You could use the [XmlIgnore] attribute against the objects that won't serialize (chances are you don't want to serialize the entire XAML page.
Place this attribute above a property in your Conexion class. Eg,
public class Conexion
{
public string MyPropertyToSerialize { get;set; }
[XmlIgnore]
public string MyPropertyToIgnore { get;set; }
}
Hope that helps.

Sending the unique phone id as an email

I try to create an app that allows the user to register himself for my service.
The problem is that it is very important that i can limit each user to a very single account
i figured out I could probably do this with the Phone unique id and the windows live id
i also figured out how to get These within the app , but now my problem is how to get them to me!
Can anyone help me on how to send the phone id with the desired username to my email address ?
Thank you
EDIT
I use this code to get the needed values
public static class ExtendedPropertyHelper
{
private static readonly int ANIDLength = 32;
private static readonly int ANIDOffset = 2;
public static string GetManufacturer()
{
string result = string.Empty;
object manufacturer;
if (DeviceExtendedProperties.TryGetValue("DeviceManufacturer", out manufacturer))
result = manufacturer.ToString();
return result;
}
//Note: to get a result requires ID_CAP_IDENTITY_DEVICE
// to be added to the capabilities of the WMAppManifest
// this will then warn users in marketplace
public static byte[] GetDeviceUniqueID()
{
byte[] result = null;
object uniqueId;
if (DeviceExtendedProperties.TryGetValue("DeviceUniqueId", out uniqueId))
result = (byte[])uniqueId;
return result;
}
// NOTE: to get a result requires ID_CAP_IDENTITY_USER
// to be added to the capabilities of the WMAppManifest
// this will then warn users in marketplace
public static string GetWindowsLiveAnonymousID()
{
string result = string.Empty;
object anid;
if (UserExtendedProperties.TryGetValue("ANID", out anid))
{
if (anid != null && anid.ToString().Length >= (ANIDLength + ANIDOffset))
{
result = anid.ToString().Substring(ANIDOffset, ANIDLength);
}
}
return result;
}
}
Now i need to store thes in variables ( what i cant really get to work ) and then send them to my php script which extracts them
in addition to this i need to ask the user to enter his email address and include this in the POST too ,
can you help?
You can get DeviceExtendedProperties.DeviceUniqueId from Microsoft.Phone.Info namespace.
Don't forget to declare in WMAppManifest.xml
like this:
<Capabilities>
<Capability Name="ID_CAP_IDENTITY_DEVICE"/>
<Capability Name="ID_CAP_IDENTITY_USER"/>
</Capabilities>
Link to msdn here
Then, you can send this id to your e-mail:
var emailComposeTask = new EmailComposeTask
{
To = "your-email#domiain.com",
Subject = "Test Message using EmailComposeTask",
Body = deviceId
};
emailComposeTask.Show();
But this will open an-email client, and I don't thik that user will be so kind to send you an email. So, you'd better send a POST request to your server
private void Button_Click(object sender, RoutedEventArgs e)
{
//collect all data you need:
var deviceId = Convert.ToBase64String(ExtendedPropertyHelper.GetDeviceUniqueID());
var userName = ExtendedPropertyHelper.GetWindowsLiveAnonymousID();
var manufatcurer = ExtendedPropertyHelper.GetManufacturer();
//create request string
//[see the explanation on MSDN][2]
var requestUrl = string
.Format("http://myPageUrlAddress.com/script.aspx?deviceid={0}&user={1}&manufacturer={2}",
deviceId, userName, manufatcurer);
System.Uri myUri = new System.Uri(requestUrl);
//create a request instance
HttpWebRequest myRequest = (HttpWebRequest)HttpWebRequest.Create(myUri);
myRequest.Method = "POST";
myRequest.ContentType = "application/x-www-form-urlencoded";
//and it will be sent.
//Also you need to create GetRequestStreamCallback method to
//handle server responce.
myRequest.BeginGetRequestStream(new
AsyncCallback(GetRequestStreamCallback), myRequest);
}
//this method is empty. You can show tha dialog box about successful sending.
public void GetRequestStreamCallback(IAsyncResult result) { ; }
What about e-mail - just create a TextBox on the same Page, and save user input to a variable.
If "my service" is a web service, then you could use the web service instead of the mail system.
In either case you can use Convert.ToBase64String(phoneId) to convert the phone id to a string.
To send strings via mail from WP7 you need to use EmailComposeTask.

How to initialize information on authorization [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
Ok, so this seems like a common need. A little googling finds a lot of ways to do this. I'm interested in the most "mvc correct" way to do it.
I have, in the upper right hand corner of my app, a greeting that says Hello FirstName LastName. Now, it's quite easy to get at the username of the logged in user, through the IPrincipal (aka User.Identity.Name). However, this won't give me the First and Last name of the user. I have to hit the Membership API to get that.
Hitting the Membership API has its drawbacks. It hits the database every time, which adds an additional db access to every served page. It's easy enough to set some session variables on login, but this only works for that session. If the user clicks the "Remember me", then no login occurs next time and i have to still load these values.
I could create my own membership provider to do some cacheing, but that's a lot of work for a more or less single purpose.
I could use Application_AuthenticateRequest and hit the membership api and store the values in session variables, or something similar. This is ok, but seems a little brute force.
I could register a global filter and handle OnAuthenticate, essentially doing the same thing. This seems a little better, but i'm unusre of the ramifications here.
I could derive a base controller, and simly add properties to provide this information. This seems a bit "old school", and I hate having to make a base class for a single purpose.
I could create a cacheing static method that would get the information on first access. This is basically not much better than a singleton.
I could also create my own IPrincipal, but that means casting it every time to get at the data, and that seems clunky. I could wrap that in another class to simplify it, but still...
I could store the data in the forms authentication cookie, and get it from there. There's some tools available to make that easier.
Are there any methods I haven't thought of? And what is the most "mvc correct" way of doing it?
I think the best way is using Cookies. Here is the solution I used in my project:
Create a class to save data in it
[DataContract]
[Serializable()]
public class AuthData {
[DataMember]
public String UserName { get; set; }
[DataMember]
public String FirstName { get; set; }
[DataMember]
public String LastName { get; set; }
[DataMember]
public String Email { get; set; }
// any other property you need to a light-store for each user
public override string ToString() {
string result = "";
try {
using (MemoryStream stream = new MemoryStream()) {
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, this);
result = Convert.ToBase64String(stream.ToArray());
}
} catch (Exception ex) {
throw new HttpException(ex.Message);
}
return result;
}
static public AuthData FromString(String data) {
AuthData result = null;
try {
byte[] array = Convert.FromBase64String(data);
using (MemoryStream stream = new MemoryStream(array)) {
stream.Seek(0, 0);
BinaryFormatter formatter = new BinaryFormatter();
result = (AuthData)formatter.Deserialize(stream, null);
}
} catch (Exception ex) {
throw new HttpException(ex.Message);
}
return result;
}
}
Signin method:
public static bool SignIn(string userName, string password, bool persistent){
if (Membership.ValidateUser(userName, password)) {
SetAuthCookie(userName, persistent);
return true;
}
return false;
}
Setting AuthCookie:
public static void SetAuthCookie(string userName, bool persistent) {
AuthData data = GetAuthDataFromDB(); // implement this method to retrieve data from database as an AuthData object
var ticket = new FormsAuthenticationTicket(
1,
userName,
DateTime.Now,
DateTime.Now.Add(FormsAuthentication.Timeout),
persistent,
data.ToString(),
FormsAuthentication.FormsCookiePath
);
string hash = FormsAuthentication.Encrypt(ticket);
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, hash);
cookie.Expires = DateTime.Now.Add(FormsAuthentication.Timeout);
cookie.HttpOnly = false;
cookie.Path = FormsAuthentication.FormsCookiePath;
HttpContext.Current.Response.Cookies.Add(cookie);
}
Getting AuthCookie:
public static AuthData GetAuthCookie() {
if (HttpContext.Current.User != null && HttpContext.Current.User.Identity.IsAuthenticated && HttpContext.Current.User.Identity is FormsIdentity) {
FormsIdentity id = (FormsIdentity)HttpContext.Current.User.Identity;
FormsAuthenticationTicket ticket = id.Ticket;
var data = AuthData.FromString(ticket.UserData);
HttpContext.Current.Items["AuthDataContext"] = data;
return data;
}
return null;
}
In ControllerBase:
private AuthData _authData;
private bool _authDataIsChecked;
public AuthData AuthData {
get {
_authData = System.Web.HttpContext.Current.Items["AuthDataContext"] as AuthData;
if (!_authDataIsChecked && _authData == null) {
SignService.GetAuthCookie();
_authData = System.Web.HttpContext.Current.Items["AuthDataContext"] as AuthData;
_authDataIsChecked = true;
}
return _authData;
}
}
The FormsAuthenticationExtensions project solves this problem storing the additional information in the auth cookie itself. http://formsauthext.codeplex.com/
This spares the database hit, and lives as long as the auth cookie, hence it works if the users asks for "remember me". It can be used the same way (in MVC too) as the standard forms authentication.
To your question, what is the most MVCisch way: I would first decide where I want to keep the information. This part of the question is rather independent of the MVC framework as the concepts (session, post data, cookies, etc.) are given with or without it.
I will implement and extend the IPrincipal and IIdentity, so when you access User.Identity you will find LastName and FirstName.
This way is better imo.
For my projects I have extended IIdentity and IPrincipal with my classes adding the properties I always need "to be there". To me is not this big work, I mean, there are only a bunch of methods that need to be implemented.
For IIdentity the interface requirement are only AuthenticationType (string), IsAuthenticated (bool) and Name (string).
While in IPrincipal Identity (IIDentity) and IsInRole (boolean)

VS 2010 addin: getting selected text in the editor

Coders, I am developing an add in for VS2010 and I am trying to get the selected text in the code editor. so far, i have been searching many webpages and thy all seems to use DTE.ActiveDocument which causes an error in my code. I have written two versions of a method that suppose to return a selected text in the editor but I still get the same error over and over:
the error is: An object reference is required for the non-static field, method, or property 'EnvDTE._DTE.ActiveDocument.get'
and here are my two versions of the method (only relevant code is showen):
using EnvDTE;
private string getSelectedText_V1()
{
string selectedText = string.Empty;
/*PROBLEM HERE: An object reference is required for the non-static field, method, or property 'EnvDTE._DTE.ActiveDocument.get'*/
Document doc = DTE.ActiveDocument;
return selectedText;
}
private string getSelectedText_V2()
{
string selectedText = string.Empty;
/*PROBLEM HERE: An object reference is required for the non-static field, method, or property 'EnvDTE._DTE.ActiveDocument.get'*/
EnvDTE.TextSelection TxtSelection = DTE.ActiveDocument.Selection;
return selectedText;
}
Please help me figure out what i did wrong in my code?
If you have access to GetService() method in your addin, you could add:
DTE dte = this.GetService(typeof(DTE)) as DTE;
Then your code would become:
private string getSelectedText_V1()
{
string selectedText = string.Empty;
DTE dte = this.GetService(typeof(DTE)) as DTE;
Document doc = dte.ActiveDocument;
return doc.Selection.Text;
}

Resources