通過c#建立exchange郵箱不成功的原因有很多,如果你的AD和Exchange在一台機器上,原因有可能是HomeMDB參數不正確,或者是ASPNET帳號沒有許可權開啟exchange帳號。而如果你的AD和Exchange不在一台機器上,使用你的代碼基本上就不可能成功,這是一個bug,而我當時的解決方案就是通過com+來實現的。
下面我把我的實現代碼給你貼出來,通過調用Com+是肯定可以實現的,首先我用vb建立了一個組件,代碼如下:
Dim m_ErrorInfo As String
Function CreateCDOEXMailBox( _
ByVal ADSIUserPath As String, _
ByVal MDBUrl As String) As Boolean
On Error GoTo CatchError
Dim objMailbox As CDOEXM.IMailboxStore
Dim objADSIuser As ActiveDs.IADsUser
Set objADSIuser = GetObject(ADSIUserPath)
Set objMailbox = objADSIuser
objMailbox.CreateMailbox MDBUrl
objADSIuser.SetInfo
CreateCDOEXMailBox = True
m_ErrorInfo = ""
Exit Function
CatchError:
CreateCDOEXMailBox = False
m_ErrorInfo = Err.Description
End Function
Public Property Get errorInfo() As String
errorInfo = m_ErrorInfo
End Property
建立成功後把組件部署到Exchange伺服器上的Com+服務中,然後匯出應用程式代理程式,把該代理安裝在web伺服器上。下面是C#調用Com+建立Exchange郵箱的代碼:
/// <summary>
/// 建立新的使用者
/// </summary>
/// <param name="strLDAPPath">LDAP全路徑</param>
/// <param name="commonName">公用名稱</param>
/// <param name="sAMAccountName">帳號</param>
/// <param name="password">密碼</param>
/// <param name="strDepartment">部門</param>
/// <returns><see cref="System.DirectoryServices.DirectoryEntry"/></returns>
public static DirectoryEntry CreateNewUser(string strLDAPPath, string commonName, string sAMAccountName, string password,string strDepartment)
{
DirectoryEntry deUser;
try
{
DirectoryEntry entry = GetDirectoryObject(strLDAPPath);//擷取你要在其下建立使用者的DirectoryEntry對象
deUser = entry.Children.Add("CN=" + sAMAccountName, "user");
deUser.Properties["sAMAccountName"].Value = sAMAccountName;
deUser.Properties["givenName"].Value = commonName;
deUser.Properties["displayName"].Value = commonName;
deUser.Properties["department"].Value = strDepartment;
deUser.CommitChanges();
ADHelper.EnableUserByAccount(sAMAccountName);//啟用帳號
deUser.Invoke("Put", new object[] {"userPrincipalName",sAMAccountName+"@"+GetShortDomain(ADDomain)});
ADHelper.SetPasswordByAccount(sAMAccountName, password);//設定密碼
deUser.CommitChanges();
bool emailAdded = CreateCDOEXMailBox(deUser.Path,ExchangeSRV,ADDomain);//調用Com+建立郵箱
if (!emailAdded)//如果郵箱建立失敗,則刪除已經建立成功的使用者
{
deUser.Parent.Children.Remove(deUser);
deUser.CommitChanges();
deUser.Close();
deUser = null;
}
entry.Close();
}
catch(Exception ex)
{
if(ex.InnerException != null)
{
ex = ex.InnerException;
}
Trace.WriteLine(ex.ToString());
deUser = null;
}
return deUser;
}
/// <summary>
///
/// </summary>
/// <param name="strADSIUserPath">使用者LDAP路徑</param>
/// <param name="strExchServer">Exchange伺服器名</param>
/// <param name="strDomainName">網域名稱</param>
private static bool CreateCDOEXMailBox(string strADSIUserPath, string strExchServer, string strDomainName)
{
bool rv = false;
try
{
string mdbURL = ADPath + "/" +
"CN=中文01("+ strExchServer + ")," +
"CN=subOu" +
"CN=InformationStore," +
"CN="+ strExchServer + "," +
"CN=Servers," +
"CN=中文02" +
"CN=Administrative Groups," +
"CN=GWBN," +
"CN=Microsoft Exchange," +
"CN=Services," +
"CN=Configuration," +strDomainName;
Type objMailType = Type.GetTypeFromProgID("CreateMail.CreateExMail");
Object objMail = Activator.CreateInstance(objMailType);
Object[] myArg = {strADSIUserPath,mdbURL};
object objAddStatus,objErrorInfo;
objAddStatus = objMailType.InvokeMember("CreateCDOEXMailBox",BindingFlags.InvokeMethod,null,objMail,myArg);
objErrorInfo = objMailType.InvokeMember("errorInfo",BindingFlags.GetProperty, null, objMail, new object[]{});
rv = true;
}
catch(Exception ex)
{
if(ex.InnerException != null)
{
ex = ex.InnerException;
}
Trace.WriteLine(ex.ToString());
}
return rv;
}
/// <summary>
/// 建立郵箱
/// </summary>
/// <param name="strADSIUserPath">使用者LDAP路徑</param>
/// <param name="strExchServer">Exchange伺服器名</param>
/// <param name="strDomainName">網域名稱</param>
private static bool CreateCDOEXMailBox(string strADSIUserPath, string strExchServer, string strDomainName)
{
bool rv = false;
try
{
string mdbURL = ADPath + "/" +
"CN=信箱儲存區("+ strExchServer + ")," +
"CN=第一個儲存群組," +
"CN=InformationStore," +
"CN="+ strExchServer + "," +
"CN=Servers," +
"CN=第一個管理組," +
"CN=Administrative Groups," +
"CN=GWBN," +
"CN=Microsoft Exchange," +
"CN=Services," +
"CN=Configuration," +strDomainName;
Type objMailType = Type.GetTypeFromProgID("CreateMail.CreateExMail");
Object objMail = Activator.CreateInstance(objMailType);
Object[] myArg = {strADSIUserPath,mdbURL};
object objAddStatus,objErrorInfo;
objAddStatus = objMailType.InvokeMember("CreateCDOEXMailBox",BindingFlags.InvokeMethod,null,objMail,myArg);
objErrorInfo = objMailType.InvokeMember("errorInfo",BindingFlags.GetProperty, null, objMail, new object[]{});
rv = true;
}
catch(Exception ex)
{
if(ex.InnerException != null)
{
ex = ex.InnerException;
}
Trace.WriteLine(ex.ToString());
}
return rv;
}
注意如果你使用的exchange2003,則mdbURL不需改變,如果不是,則mdbURL變數你需要改一下。