public bool ProcessTimesheet(Guid siteGuid, Guid tsGuid, string lcid, string userName, bool submitStatus, string sspName) { #region Local Variables string exceptionMsg = null; string tsInfo = string.Empty; Stopwatch timeToProcessAll = new Stopwatch(); Stopwatch timeToProcessStatus = new Stopwatch(); timeToProcessAll.Start(); //SPSite spSite = new SPSite("http://win-9dubqmslff7/pwa/"); bool result = false; #endregion try { if (appLog == null) appLog = new AppLog(LoggingPrefix, LoggingFolder, LogFileEveryHour); #region STEP 1 - Initialize Web Service urls statusing.Url = "http://win-9dubqmslff7/PWA/_vti_bin/psi/statusing.asmx";//WSUrl( HostName, sspName, "statusing", true); resource.Url = WSUrl(HostName, sspName, "resource", false); timesheet.Url = WSUrl(HostName, sspName, "timesheet", false); if (logEvents) appLog.WriteLine(string.Format("STEP 1 - Initialize Web Service urls")); #endregion #region STEP 2 - Retrieve Timesheet DataSet TimesheetWS.TimesheetDataSet timesheetDS = timesheet.ReadTimesheet(tsGuid); TimesheetPSI tsHeader = new TimesheetPSI(timesheetDS); Guid tspUID = tsHeader.PeriodUID; Guid tresUID = tsHeader.ResUID; if (logEvents) { appLog.WriteLine(string.Format("STEP 2 - Start event override for timesheet UID: {0}", tsGuid.ToString())); tsInfo = string.Format("Timesheet: {0}; Resource: {1}; Creator: {2}, Period: {3}", tsHeader.Name, tsHeader.ResName, tsHeader.CreatorResName, tspUID.ToString()); } #endregion ResourceWS.ResourceDataSet resourceDS = resource.ReadResource(tresUID); ResourcePSI resourcePSI = new ResourcePSI(resourceDS); bool isWindowsUser = userName.StartsWith("AspNetSqlMembershipProvider") ? false : true; statusing.SetImpersonationContext(isWindowsUser, userName, tresUID, Guid.Empty, siteGuid, lcid); timesheet.SetImpersonationContext(isWindowsUser, userName, tresUID, Guid.Empty, siteGuid, lcid); if (logEvents) appLog.WriteLine(string.Format("STEP 3 - Statusing Impersonation for RES_UID: {0}", tresUID.ToString())); #endregion TimesheetWS.TimesheetDataSet timeSheetDs = new TimesheetWS.TimesheetDataSet(); TimesheetWS.TimesheetDataSet.HeadersRow headersRow = timeSheetDs.Headers.NewHeadersRow(); headersRow.RES_UID = new Guid("97B3EBBF-871B-4ED6-B366-5EFE59B68F4A"); headersRow.TS_UID = Guid.NewGuid(); headersRow.WPRD_UID = new Guid("EE8C2B3E-556B-4FAC-9CE1-537A51B4CCF6"); headersRow.TS_CREATOR_RES_UID = new Guid("97B3EBBF-871B-4ED6-B366-5EFE59B68F4A"); headersRow.TS_NAME = "我的时间表"; headersRow.TS_COMMENTS = "Create By PSI"; headersRow.TS_ENTRY_MODE_ENUM = (byte)PSLibrary.TimesheetEnum.EntryMode.Weekly; timeSheetDs.Headers.AddHeadersRow(headersRow); timesheet.CreateTimesheet(timeSheetDs, TimesheetWS.PreloadType.Default); }using System;using System.Collections.Generic;using System.Net;using System.Text;// Project Server 2007 Referencesusing Microsoft.Office.Project.Server.Library;namespace Microsoft.EPM.TSAutoStatus{ ////// Timesheet Helper Methods /// class TimesheetPSI { #region Properties private string name; private string resName; private string creatorResName; private Guid creatorResUID; private Guid resUID; private Guid periodUID; private decimal totalActValue; ////// Timesheet Name /// public string Name { get { return name; } } ////// Resource Name /// public string ResName { get { return resName; } } ////// Timesheet creator resource name /// public string CreatorResName { get { return creatorResName; } } ////// Timesheet creator resource UID /// public Guid CreatorResUID { get { return creatorResUID; } } ////// Resource UID /// public Guid ResUID { get { return resUID; } } ////// Period UID /// public Guid PeriodUID { get { return periodUID; } } ////// Total actual value in hours /// public decimal TotalActValue { get { return totalActValue; } } #endregion #region Constructor ////// Timesheet header information /// /// Timesheet DataSet public TimesheetPSI(TimesheetWS.TimesheetDataSet timesheetDS) { name = timesheetDS.Headers[0].TS_NAME; resName = timesheetDS.Headers[0].TS_CACHED_RES_NAME; creatorResName = timesheetDS.Headers[0].TS_CACHED_CREATOR_RES_NAME; creatorResUID = timesheetDS.Headers[0].TS_CREATOR_RES_UID != Guid.Empty ? timesheetDS.Headers[0].TS_CREATOR_RES_UID : Guid.NewGuid(); resUID = timesheetDS.Headers[0].RES_UID != Guid.Empty ? timesheetDS.Headers[0].RES_UID : Guid.NewGuid(); periodUID = timesheetDS.Headers[0].WPRD_UID != Guid.Empty ? timesheetDS.Headers[0].WPRD_UID : Guid.NewGuid(); totalActValue = timesheetDS.Headers[0].TS_TOTAL_ACT_VALUE/60000; } #endregion } ////// Perform WS impersonation /// class TimesheetDerived : TimesheetWS.TimeSheet { private String contextString = String.Empty; protected override WebRequest GetWebRequest(Uri uri) { WebRequest webRequest = base.GetWebRequest(uri); if (contextString != String.Empty) { webRequest.UseDefaultCredentials = true; webRequest.Credentials = CredentialCache.DefaultCredentials; webRequest.Headers.Add("PjAuth", contextString); webRequest.Headers.Add("ForwardFrom", "/_vti_bin/psi/timesheet.asmx"); webRequest.PreAuthenticate = true; } return webRequest; } public void SetImpersonationContext(bool isWindowsUser, String userNTAccount, Guid userGuid, Guid trackingGuid, Guid siteId, String lcid) { contextString = GetImpersonationContext(isWindowsUser, userNTAccount, userGuid, trackingGuid, siteId, lcid); } private String GetImpersonationContext(bool isWindowsUser, String userNTAccount, Guid userGuid, Guid trackingGuid, Guid siteId, String lcid) { PSContextInfo contextInfo = new PSContextInfo(isWindowsUser, userNTAccount, userGuid, trackingGuid, siteId, lcid); return PSContextInfo.SerializeToString(contextInfo); } }}
调用的时候:
UpdateStatus update = new UpdateStatus("http://win-9dubqmslff7/pwa"); Guid siteGuid = new Guid("4E925E19-93AC-4275-9FD6-336D7E874377"); Guid tsGuid = new Guid("C06F9A45-F19F-404A-A1D6-DF3ACDBA05BE"); string lcid = "1033"; string userName = @"HN\xxxx"; bool submitStatus = true; string sspName = "pwa"; update.ProcessTimesheet( siteGuid, tsGuid, lcid, userName, submitStatus, sspName);
这里详细介绍下参数:
siteGuid就是我们网站集的GUID,一般指PWA的网站集
tsGuid就是我们的时间表的GUID,这里我们创建时间表的时候无需用到,如果是读取时间表的数据,在[ProjectServer_Published].[dbo].[MSP_TIMESHEETS]下的TS_UID字段
lcid指中英文版本,中文1033
userName指被模拟的账户,如果我想模拟X账户,只需填写X的用户名即可
headersRow.RES_UID = new Guid("97B3EBBF-871B-4ED6-B366-5EFE59B68F4A");指的是被模拟账户的RESOURCE GUID
headersRow.TS_CREATOR_RES_UID = new Guid("97B3EBBF-871B-4ED6-B366-5EFE59B68F4A");指的是创建时间表用户的RESOURCE GUID,一般指本人
headersRow.WPRD_UID = new Guid("EE8C2B3E-556B-4FAC-9CE1-537A51B4CCF6");指的是时间表的日期GUID,从[ProjectServer_Reporting].[dbo].[MSP_TimesheetPeriod]表里面查找,找到指定日期的GUID即可。
同理,根据模拟账户还可以做很多事情,比如有些用户保存了时间表的工时,但是忘记提交,系统可以自动模拟用户将未提交的工时提交上去。