前言
Sharepoint2010的用户同步无法从AD中完全同步所有用户的照片信息到sharepoint2010的中来,经过查询微软资料需要打累计补丁http://support.microsoft.com/kb/2394320/zh-cn,累计补丁描述如下:
您尝试导入从 Active Directory thumbnailPhoto属性到 Microsoft SharePoint 服务器 2010 年的PictureURL属性在用户配置文件中的图片。设置导入PictureURL映射。然后,在 SharePoint 服务器执行完全同步。在这种情况下,图片不会添加到 SharePoint 服务器中的用户配置文件。
我在测试服务器上打了累计补丁,然后完全同步还是无法做到,再说累计补丁是微软没有经过测试的补丁,不敢在正式生产环境中打此类补丁。因此,需要考虑其他办法从AD或其他文件中同步用户的照片信息到sharepoint2010中来。
实现方法
实现思路
以管理员账号打开个人站点http://win-moss/my/,点【网站操作】-【查看所有网站内容】,如下图:
进入后找到【图片库】-【用户照片】如下图:
点击进入后可以看到MOSS个人站点下每个人的照片信息如下图:
可以看到每个用户都有3张照片,每张照片大小规格以及命名规则如下表格:
分为大中小三种图片,格式为JPG格式
明白这个后,其实我们就可以写代码操作图片库了,并把图片保存成3种大小规格,命名规则合符规定,最后更新UserProfile中的PictureUrl属性即可完成照片的上传。
实现方法
首先需要引用如下主要DLL,如下图:
Microsoft.Office.Server.dll
Microsoft.Office.Server.UserProfiles.dll
Microsoft.SharePoint.dll
microsoft.sharepoint.portal.dll
System.Drawing.dll
引用的命名空间如下:
using Microsoft.SharePoint; using Microsoft.SharePoint.WebControls; using System.IO; using System.Drawing; using Microsoft.Office.Server.UserProfiles; using Microsoft.SharePoint.Portal.WebControls;
代码段:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Reflection;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.IO;
using Microsoft.Office.Server.UserProfiles;
using Microsoft.SharePoint.Portal.WebControls;
using System.Web;
using System.Threading;
using System.Globalization;
using System.Data;
using System.Collections;
namespace UploadProfileImage
{
class Program
{
private static DataTable userTable = null;
enum ProfileType { None, NoPhoto, Inactive };
private static ProfileType usersLoaded = ProfileType.None;
private static ProfileImagePicker profileImagePicker = new ProfileImagePicker();
private static string MySiteHostUrl = "http://win-moss/my/";
private static string MAccountName = "contoso\\test02";
static void Main(string[] args)
{
UploadPhotos();
Console.WriteLine("ok");
Console.Read();
}
private static DataTable GetNoPhotoProfiles()
{
DataTable dt = CreateUserTable();
SPSite site = new SPSite(MySiteHostUrl);
SPWeb web = site.OpenWeb();
SPServiceContext sc = SPServiceContext.GetContext(site);
UserProfileManager upm = new UserProfileManager(sc);
IEnumerator profileEnumerator = upm.GetEnumerator();
InitializeProfileImagePicker(web);
while(profileEnumerator.MoveNext())
{
try
{
UserProfile up = (UserProfile)profileEnumerator.Current;
if (up["PictureUrl"].Value == null || up["PictureUrl"].Value.ToString() == "")
{
DataRow dr = dt.NewRow();
dr["username"] = up["AccountName"];
dr["last"] = up["LastName"];
dr["first"] = up["FirstName"];
dr["UserProfileID"] = up.ID;
dt.Rows.Add(dr);
dt.AcceptChanges();
}
}
catch (Exception)
{
}
}
web.Dispose();
site.Dispose();
return dt;
}
private static DataTable CreateUserTable()
{
DataTable dt = new DataTable();
DataColumn dcUsr = new DataColumn("username");
DataColumn dcLast = new DataColumn("last");
DataColumn dcFirst = new DataColumn("first");
DataColumn dcProfileId = new DataColumn("UserProfileID");
DataColumn dcPair = new DataColumn("FoundPhoto");
DataColumn dcPairPath = new DataColumn("FoundPhotoURL");
dt.Columns.Add(dcUsr);
dt.Columns.Add(dcLast);
dt.Columns.Add(dcFirst);
dt.Columns.Add(dcProfileId);
dt.Columns.Add(dcPair);
dt.Columns.Add(dcPairPath);
return dt;
}
/// <summary>
///
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
private static byte[] ReadFile(string fileName)
{
FileStream pFileStream = null;
byte[] pReadByte = new byte[0];
try
{
pFileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read);
BinaryReader r = new BinaryReader(pFileStream);
r.BaseStream.Seek(0, SeekOrigin.Begin); //将文件指针设置到文件开
pReadByte = r.ReadBytes((int)r.BaseStream.Length);
return pReadByte;
}
catch
{
return pReadByte;
}
finally
{
if (pFileStream != null)
pFileStream.Close();
}
}
/// <summary>
/// 上传图片
/// </summary>
private static void UploadPhotos()
{
SPSite mySites = new SPSite(MySiteHostUrl);
SPWeb myWeb = mySites.OpenWeb();
SPFolder subfolderForPictures = myWeb.GetFolder("User Photos\\Profile Pictures");
if (subfolderForPictures == null)
{
return;
}
UserProfileManager userProfileManager = new UserProfileManager(SPServiceContext.GetContext(mySites));
//读取文档
string[] strCollection = Directory.GetFiles(@"c:\photoFolder");
foreach (string item in strCollection)
{
//FileInfo
FileInfo fileinfo = new FileInfo(item);
//
byte[] buffer = null;
string fileNameWithoutExtension = GetFileNameFromAccountName(MAccountName);
string photoURL = fileinfo.FullName;
if(photoURL.ToLower().EndsWith("jpg"))
{
System.Threading.Thread.Sleep(2500);
buffer = ReadFile(fileinfo.FullName);
int largeThumbnailSize = 0X90;
int mediumThumbnailSize = 0X60;
int smallThumbnailSize = 0X20;
using (MemoryStream stream = new MemoryStream(buffer))
{
using (Bitmap bitmap = new Bitmap(stream, true))
{
CreateThumbnail(bitmap, largeThumbnailSize, largeThumbnailSize, subfolderForPictures, fileNameWithoutExtension + "_LThumb.jpg");
CreateThumbnail(bitmap, mediumThumbnailSize, mediumThumbnailSize, subfolderForPictures, fileNameWithoutExtension + "_MThumb.jpg");
CreateThumbnail(bitmap, smallThumbnailSize, smallThumbnailSize, subfolderForPictures, fileNameWithoutExtension + "_SThumb.jpg");
}
}
SetPictureUrl(MAccountName, subfolderForPictures, userProfileManager, mySites.Url);
}
}
myWeb.Dispose();
mySites.Dispose();
}
/// <summary>
/// 根据账号得到文件名称
/// </summary>
/// <param name="accountName"></param>
/// <returns></returns>
private static string GetFileNameFromAccountName(string accountName)
{
string result = accountName;
string charsToReplace = @"\/:*?""<>|";
Array.ForEach(charsToReplace.ToCharArray(), charToReplace => result = result.Replace(charToReplace, '_'));
return result;
}
private static void InitializeProfileImagePicker(SPWeb web)
{
Type profileImagePickerType = typeof(ProfileImagePicker);
FieldInfo fi_m_objWeb = profileImagePickerType.GetField("m_objWeb", BindingFlags.NonPublic | BindingFlags.Instance);
fi_m_objWeb.SetValue(profileImagePicker, web);
MethodInfo mi_LoadPictureLibraryInternal = profileImagePickerType.GetMethod("LoadPictureLibraryInternal", BindingFlags.NonPublic | BindingFlags.Instance);
if (mi_LoadPictureLibraryInternal != null)
{
mi_LoadPictureLibraryInternal.Invoke(profileImagePicker, new object[] { });
}
}
/// <summary>
///
/// </summary>
/// <param name="original"></param>
/// <param name="idealWidth"></param>
/// <param name="idealHeight"></param>
/// <param name="folder"></param>
/// <param name="fileName"></param>
/// <returns></returns>
private static SPFile CreateThumbnail(Bitmap original, int idealWidth, int idealHeight, SPFolder folder, string fileName)
{
SPFile file = null;
// Workaround to get the Microsoft.Office.Server.UserProfiles assembly
Assembly userProfilesAssembly = typeof(UserProfile).Assembly;
// UserProfilePhotos is internal
// so there is no visibility from Visual Studio
Type userProfilePhotosType = userProfilesAssembly.GetType("Microsoft.Office.Server.UserProfiles.UserProfilePhotos");
MethodInfo mi_CreateThumbnail = userProfilePhotosType.GetMethod("CreateThumbnail", BindingFlags.NonPublic | BindingFlags.Static);
if (mi_CreateThumbnail != null)
{
file = (SPFile)mi_CreateThumbnail.Invoke(null, new object[] { original, idealWidth, idealHeight, folder, fileName });
}
return file;
}
private static void SetPictureUrl(string accountName, SPFolder subfolderForPictures, UserProfileManager userProfileManager, string siteUrl)
{
UserProfile userProfile = userProfileManager.GetUserProfile(accountName);
string fileNameWithoutExtension = GetFileNameFromAccountName(accountName);
string pictureUrl = String.Format("{0}/{1}/{2}_MThumb.jpg", siteUrl, subfolderForPictures.Url, fileNameWithoutExtension);
userProfile["PictureUrl"].Value = pictureUrl;
userProfile.Commit();
}
}
}
测试结果:
在AD新建一个用户contoso\\test02,默认没有照片如下图:
在我的虚拟机C盘下建立一个文件夹(C:\photoFolder)并放上照片文件(Hydrangeas.jpg)如下图:
去【图片库】-【用户照片】也看不到test02的照片信息,如下图:
运行代码后:
去个人站点下的用户配置信息看照片如下图:
去【图片库】-【用户照片】可以看到如下图信息: