没办法,客户要求这样。本来希望使用注册表改一改就好,结果发现注册表根本不可读。很难找到我们需要的所有东西。
然后想做一个Oulook addin判断一下,然后直接SetDefaultStore。结果发现SetDefaultStore不支持VB。
既然要用VC++了,就不费劲写什么Addin了。直接上Win32 Console App.
方法很简单,
使用MAPILogonEx登陆当前Profile。
GetMsgStoresTable读取所有的存贮。
判断PR_DEFAULT_STORE是否是在服务器上。如果不是,再使用GetMsgStoresTable找到服务器存储,并且使用SetDefaultStore跑一下就好。
写起来可不是很容易,一直写到3点半。该睡觉了。
先把source code摆这里好了。
// SetMyDefaultStore.cpp
// Need MAPI32.Lib
#include "stdafx.h"
#include <stdio.h>
#include <conio.h>
#include <mapix.h>
#include <mapiutil.h>
#define DEBUG(Status) (Status<0)
__int8 debug;
STDMETHODIMP SetDefStore(
LPMAPISESSION lpMAPISession);
STDMETHODIMP GetDefStore(
LPMAPISESSION lpMAPISession);
void DisplayUsage();
int main(int argc, char *argv[ ])
{
HRESULT hRes;
LPMAPISESSION lpMAPISession = NULL;
LPMDB lpMDB = NULL;
LPMAPIFOLDER lpInboxFolder = NULL;
LPSPropValue tmp = NULL;
FLAGS flLogon = MAPI_NO_MAIL |MAPI_USE_DEFAULT;
debug = 0;
if (argc > 2)
{
DisplayUsage();
goto quit1;
}
if (argc == 2)
{
if ((_stricmp(argv[1], "/d") == 0)||(_stricmp(argv[1], "/D") == 0))
debug = -1;
else
{
DisplayUsage();
goto quit1;
}
}
hRes = MAPIInitialize(NULL);
if (FAILED(hRes)) goto quit;
if DEBUG(debug) flLogon = MAPI_LOGON_UI;
hRes = MAPILogonEx(0,
NULL,//profile name
NULL,//password - This parameter should ALWAYS be NULL
flLogon,//MAPI_LOGON_UI, //Allow a profile picker box to show if not logged in
&lpMAPISession);//handle of session
if (FAILED(hRes)) goto quit;
hRes = GetDefStore(lpMAPISession);
if (FAILED(hRes)) goto quit;
quit:
if (tmp) MAPIFreeBuffer(tmp);
UlRelease(lpInboxFolder);
UlRelease(lpMDB);
UlRelease(lpMAPISession);
MAPIUninitialize();
if (FAILED(hRes))
{
printf("Failed with hRes of %x/n",hRes);
}
quit1:
//printf("Hit any key to continue/n");
//while(!_kbhit()){ Sleep(50);};
return 0;
}
STDMETHODIMP GetDefStore(
LPMAPISESSION lpMAPISession)
{
LPMAPITABLE pStoresTbl = NULL;
LPSRowSet pRow = NULL;
static SRestriction sres;
SPropValue spv;
HRESULT hRes;
LPMDB lpTempMDB = NULL;
//Will Retrieve Provider Name only
//two types of provider we will accept
//Microsoft Exchange Server
//Personal Folders
enum {PROVIDER,NUM_COLS};
static SizedSPropTagArray(NUM_COLS,sptCols) = {NUM_COLS, PR_PROVIDER_DISPLAY};
//Get the table of all the message stores available
hRes = lpMAPISession -> GetMsgStoresTable(0, &pStoresTbl);
if (FAILED(hRes)) goto quit;
//Set up restriction for the default store
sres.rt = RES_PROPERTY; //Comparing a property
sres.res.resProperty.relop = RELOP_EQ; // Test ing equality
sres.res.resProperty.ulPropTag = PR_DEFAULT_STORE; //Tag to compare
sres.res.resProperty.lpProp = &spv; //Prop tag and value to compare against
spv.ulPropTag = PR_DEFAULT_STORE; //Tag type
spv.Value.b = TRUE; //Tag value
//Convert the table to an array which can be stepped through
//Query all rows without any restrictions. Thus all rows get returned.
hRes = HrQueryAllRows(
pStoresTbl, //Table to query
(LPSPropTagArray) &sptCols, //Which columns to get // If the ptaga parameter is NULL, HrQueryAllRows retrieves the entire column set of the current table view passed in the ptable parameter
&sres, //If the pres parameter is NULL, HrQueryAllRows makes no restrictions.
NULL, //No sort order
0, //Max number of rows (0 means no limit)
&pRow); //Array to return
if (FAILED(hRes)) goto quit;
//There should be only one row which is default message store.
LPSTR strProvName = pRow->aRow[0].lpProps[PROVIDER].Value.lpszA;
//default store's provider can be only Microsoft Exchange Server and Personal Folders.
//If the store's provide starts with 'M', the user's server mailbox is used. We then need to do nothing.
//If the store's provider does not start with 'M', a personal folder is used. We then need to set it to a server store.
if ('M' == strProvName[0])
{
if DEBUG(debug) printf("The current store is on the Exchange server./n");
if DEBUG(debug) printf("We need to do nothing and will quit the program./n");
goto quit;
}
if DEBUG(debug) printf("The current store is on a personal folder./n");
if DEBUG(debug) printf("We need to locate the store of the Exchange server and change the default store in this profile!/n");
SetDefStore(lpMAPISession);
//Always clean up your memory here!
quit:
FreeProws(pRow);
UlRelease(pStoresTbl);
if (FAILED(hRes))
{
HRESULT hr;
LPMAPIERROR lpError;
hr = lpMAPISession->GetLastError(hRes,0,&lpError);
if (!hr)
{
printf("%s/n%s/n",lpError->lpszError,lpError->lpszComponent);
MAPIFreeBuffer(lpError);
}
}
return hRes;
}
STDMETHODIMP SetDefStore(LPMAPISESSION lpMAPISession)
{
LPMAPITABLE pStoresTbl = NULL;
LPSRowSet pRow = NULL;
static SRestriction sres;
HRESULT hRes;
LPMDB lpTempMDB = NULL;
enum {EID, NAME, PROVIDER, NUM_COLS};
static SizedSPropTagArray(NUM_COLS,sptCols) = {NUM_COLS, PR_ENTRYID, PR_DISPLAY_NAME, PR_PROVIDER_DISPLAY};
//Get the table of all the message stores available
hRes = lpMAPISession -> GetMsgStoresTable(0, &pStoresTbl);
if (FAILED(hRes)) goto quit;
//Convert the table to an array which can be stepped through
//Only one message store should have PR_DEFAULT_STORE set to true, so only one will be returned
hRes = HrQueryAllRows(
pStoresTbl, //Table to query
(LPSPropTagArray) &sptCols, //Which columns to get
NULL, //No Restriction
NULL, //No sort order
0, //Max number of rows (0 means no limit)
&pRow); //Array to return
if (FAILED(hRes)) goto quit;
//browse to all rows in the rowset.
//ULONG i = 0;
//ULONG loopCount = pRow->cRows;
//do
for(ULONG i = 0; i<pRow->cRows; i++)
{
LPSTR strProvName = pRow->aRow[i].lpProps[PROVIDER].Value.lpszA;
LPSTR strName = pRow->aRow[i].lpProps[NAME].Value.lpszA;
if (('M'==strProvName[0])&&('P'!=strName[0]))
{
if DEBUG(debug) printf("Change default store for.../n");
if DEBUG(debug) printf(strProvName);
if DEBUG(debug) printf("/t");
if DEBUG(debug) printf(strName);
if DEBUG(debug) printf("/n");
hRes = lpMAPISession->SetDefaultStore(
MAPI_DEFAULT_STORE, //Establishes the message store as the session default. Updates the message store's status table row by setting the STATUS_DEFAULT_STORE flag in the PR_RESOURCE_FLAGS column.
pRow->aRow[i].lpProps[EID].Value.bin.cb,//[in] Count of bytes in the entry identifier pointed to by the lpEntryID parameter.
(LPENTRYID)pRow->aRow[i].lpProps[EID].Value.bin.lpb); // Pointer to the entry identifier of the message store intended as the default.
if (!FAILED(hRes)) break;
}
}
//Always clean up your memory here!
quit:
FreeProws(pRow);
UlRelease(pStoresTbl);
if (FAILED(hRes))
{
HRESULT hr;
LPMAPIERROR lpError;
hr = lpMAPISession->GetLastError(hRes,0,&lpError);
if (!hr)
{
printf("%s/n%s/n",lpError->lpszError,lpError->lpszComponent);
MAPIFreeBuffer(lpError);
}
}
return hRes;
}
void DisplayUsage()
{
printf("The syntax of the command is incorrect./n");
printf("Usage:/n");
printf("SetMyDefaultStore [/D]/n");
printf("[/D]/t Shows debug information./n");
}