Solutions “bac à sable” en Sharepoint 2010
Ce post détaille certains aspects du support de l’utilisation des solutions ”bac à sable” avec Sharepoint 2010 RTM sous forme de questions-réponses.
Les terme français “bac à sable” est équivalent au terme anglais “sandbox”.
Les étapes de mise en place des solutions bac à sables sont détaillées à vue d'ensemble des solutions bac à sable (documentation préliminaire).
Le bac à sable et les processus
Q: Dans quel process une solution bac-à-sable s’exécute-t-elle ?
R: l’exécutable du process est C:\program files\Common Files\Microsoft Shared\Web Server Extensions\14\UserCode\SPUCWorkerProcess.exe
Q: Dans VisualStudio, j’ai l’erreur “Error occurred in deployment step 'Activate Features': Cannot start service SPUserCodeV4 on computer '<monserveur>'.
R: Il faut vérifier que le service “Microsoft SharePoint Foundation Sandboxed Code Service” soit démarré. Le status peut être vérifié dans l’Administration Centrale : System Settings \ Manage Services on this server.
Q: Comment déterminer si une solution était dans un bac à sable lorsqu’une exception s’est produite ?
R: si la pile d’appel contient une ligne
SPUCWorkerProcess.exe!Microsoft.SharePoint.UserCode.SPUserCodeApplicationHostAppDomainRef.ExecuteWrapper
la solution s’exécutait dans un bac à sable.
Q: comment recycler le process du bac à sable ?
R: le process SPUCWorkerProcess.exe est recyclé en stoppant puis en redémarrant le service “Microsoft SharePoint Foundation Sandboxed Code Service”
Les DLL du bac à sable…
Q: Comment visualiser le modèle objet accessible depuis une solution bac-à-sable ?
R: le modèle objet est visualisable en utilisant l’explorateur d’objets sur c:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\UserCode\assemblies\Microsoft.SharePoint.dll. Seules les méthodes accessibles sont affichées. Par exemple, la méthode non authorisée Microsoft.SharePoint.Utilities.SPUtility.SendEmail() n’est pas affichée. En revanche, la méthode authorisée Microsoft.SharePoint.Utilities.SPUtility.StringToUInt64() est affichée.
Q: Est-il possible de déterminer à la compilation si une solution “bac à sable” appelle un méthode non authorisée ?
R: la compilation s’effectue en utilisant la DLL Microsoft.SharePoint.dll du répertoire C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\ISAPI\ . Comme toutes les méthodes sont présentes, il n’y aura pas d’erreur à la compilation si une méthode non authorisée est compilée.
Une astuce – que nous ne recommandons pas – serait de modifier la référence afin d’utiliser Microsoft.SharePoint.dll du répertoire c:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\UserCode\assemblies afin de détecter à la compilation les appels non-authorisés. Parce que la solution ne doit pas être déployée avec cette référence, nous ne recommandons pas cette astuce.
Q: Dans quel répertoire se trouve la DLL de la solution lors de son appel dans le bas à sable ?
R: la DLL de la solution est chargée depuis
C:\ProgramData\Microsoft\SharePoint\UCCache\<suite de caractères>\<masolution>.dll
Q: que se passe-t-il lorsqu’une méthode non authorisée est appellée ?
R: une exception est générée. Pour une webpart, la page contient par exemple:
Erreur du composant WebPart : Une exception non gérée a été générée par la méthode Execute du wrapper de code en mode bac à sable dans le domaine d’application de confiance partielle : Une erreur inattendue s'est produite.
ou
Web Part Error: Unhandled exception was thrown by the sandboxed code wrapper's Execute method in the partial trust app domain: An unexpected error has occurred.
l’erreur détaillée est ci-dessous ( l’exception se trouve en couleur marron):
[SPUserCodeSolutionExecutionFailedException: Une exception non gérée a été générée par la méthode Execute du wrapper de code en mode bac à sable dans le domaine d’application de confiance partielle : Une erreur inattendue s'est produite.]
Server stack trace:
at Microsoft.SharePoint.UserCode.SPUserCodeApplicationHostAppDomainRef.Execute(Type userCodeWrapperType, SPUserCodeCachedAssemblyGroup userAssemblyGroup, Guid siteCollectionId, Byte[] binaryUserCodeToken, Byte[] proxyOperationToken, SPUserCodeExecutionContext executionContext)
at Microsoft.SharePoint.UserCode.SPUserCodeApplicationHostAppDomainRef.Execute(Type userCodeWrapperType, SPUserCodeCachedAssemblyGroup userAssemblyGroup, Guid siteCollectionId, Byte[] binaryUserCodeToken, Byte[] proxyOperationToken, SPUserCodeExecutionContext executionContext)
at Microsoft.SharePoint.UserCode.SPUserCodeAppDomain.Execute(Type userCodeWrapperType, SPUserCodeCachedAssemblyGroup userAssemblyGroup, Guid siteCollectionId, Byte[] binaryUserCodeToken, Byte[] proxyOperationToken, SPUserCodeExecutionContext executionContext)
at Microsoft.SharePoint.UserCode.SPUserCodeWorkerProcessProxyForShim.ExecuteInternal(Type userCodeWrapperType, SPUserCodeCachedAssemblyGroup userAssemblyGroup, Guid siteCollectionId, Byte[] binaryUserCodeToken, Byte[] proxyOperationToken, SPUserCodeExecutionContext executionContext)
at Microsoft.SharePoint.UserCode.SPUserCodeWorkerProcessProxy.Execute(Type userCodeWrapperType, SPUserCodeCachedAssemblyGroup userAssemblyGroup, Guid siteCollectionId, Byte[] binaryUserCodeToken, Byte[] proxyOperationToken, SPUserCodeExecutionContext executionContext)
at System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Int32 methodPtr, Boolean fExecuteInContext, Object[]& outArgs)
at System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(IMessage msg, Int32 methodPtr, Boolean fExecuteInContext)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at Microsoft.SharePoint.UserCode.SPUserCodeWorkerProcess.ExecuteDelegate.EndInvoke(IAsyncResult result)
at Microsoft.SharePoint.UserCode.SPUserCodeWorkerProcess.Execute(Type userCodeWrapperType, SPUserCodeCachedAssemblyGroup userAssemblyGroup, Guid siteCollectionId, SPUserToken userToken, String currentAffinity, SPUserCodeExecutionContext executionContext)
at Microsoft.SharePoint.UserCode.SPUserCodePoolableProcessConnection.Execute(Type userCodeWrapperType, SPUserCodeCachedAssemblyGroup userAssemblyGroup, Guid siteCollectionId, SPUserToken userToken, String affinity, SPUserCodeExecutionContext executionContext)
at Microsoft.SharePoint.UserCode.SPUserCodeExecutionHost.Execute(Type userCodeWrapperType, Guid siteCollectionId, SPUserToken userToken, String affinity, SPUserCodeExecutionContext executionContext)
at System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Int32 methodPtr, Boolean fExecuteInContext, Object[]& outArgs)
at System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(IMessage msg, Int32 methodPtr, Boolean fExecuteInContext)
Exception rethrown at [1]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at Microsoft.SharePoint.Administration.ISPUserCodeExecutionHostProxy.Execute(Type userCodeWrapperType, Guid siteCollectionId, SPUserToken userToken, String affinityBucketName, SPUserCodeExecutionContext executionContext)
at Microsoft.SharePoint.UserCode.SPUserCodeExecutionManager.Execute(Type userCodeWrapperType, SPSite site, SPUserCodeExecutionContext executionContext)
at Microsoft.SharePoint.UserCode.SPUserCodeWebPartRemoteExecutionHelper.<>c__DisplayClassa.b__9()
at Microsoft.SharePoint.Utilities.SecurityContext.RunAsProcess(CodeToRunElevated secureCode)
at Microsoft.SharePoint.UserCode.SPUserCodeWebPartRemoteExecutionHelper.ExecuteRequestInSandBox(HttpContext context, SPWeb web, SPWebPartManager manager, SPUserCodeWebPart userCodeWebPart)
[HttpUnhandledException: Exception of type 'System.Web.HttpUnhandledException' was thrown.]
Server stack trace:
at System.Web.UI.Page.HandleError(Exception e)
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
at System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
at System.Web.UI.Page.ProcessRequest()
at System.Web.UI.Page.ProcessRequest(HttpContext context)
at Microsoft.SharePoint.UserCode.SPUserCodeWebPartWrapper.ExecuteHttpRequest(SPUserCodeWebPartHttpRequestContext webPartExecutionContext, SPUserCodeWebPartHttpResponse httpRequestResponse)
at Microsoft.SharePoint.UserCode.SPUserCodeWebPartWrapper.Execute(SPUserCodeExecutionContext executionContext)
at Microsoft.SharePoint.UserCode.SPUserCodeApplicationHostAppDomainRef.ExecuteWrapper(SPUserCodeWrapper wrapper, SPUserCodeExecutionContext executionContext)
at System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Int32 methodPtr, Boolean fExecuteInContext, Object[]& outArgs)
at System.Runtime.Remoting.Messaging.StackBuilderSink.AsyncProcessMessage(IMessage msg, IMessageSink replySink)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.EndInvokeHelper(Message reqMsg, Boolean bProxyCase)
at System.Runtime.Remoting.Proxies.RemotingProxy.Invoke(Object NotUsed, MessageData& msgData)
at Microsoft.SharePoint.UserCode.SPUserCodeApplicationHostAppDomainRef.CodeToExecuteWrapper.EndInvoke(IAsyncResult result)
at Microsoft.SharePoint.UserCode.SPUserCodeApplicationHostAppDomainRef.Execute(Type userCodeWrapperType, SPUserCodeCachedAssemblyGroup userAssemblyGroup, Guid siteCollectionId, Byte[] binaryUserCodeToken, Byte[] proxyOperationToken, SPUserCodeExecutionContext executionContext)
[MissingMethodException: Method not found: 'Void Microsoft.SharePoint.Utilities.SPUtility.GetNTFullNameandEmailfromLogin(Microsoft.SharePoint.SPWeb, System.String, System.String ByRef, System.String ByRef)'.]
at SBWebPArt5_Login_Sable.Login_WebPArt5_Sable.Login_WebPArt5_Sable.<>c__DisplayClass1.b__0(Object , EventArgs )
at System.Web.UI.WebControls.Button.OnClick(EventArgs e)
at System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument)
at System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument)
at System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument)
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
Le journal ULS contient une entrée pour SPUCWorkerProcess.exe et également une entrée pour SPUCHostService.exe:
04/29/2010 16:47:46.22 SPUCWorkerProcess.exe (0x1530) 0x1780 SharePoint Foundation Sandboxed Code Service
fe8s Medium - - Unhandled exception was thrown by the sandboxed code wrapper's Execute method in the partial trust
app domain: An unexpected error has occurred. - userCodeWrapperType = "Microsoft.SharePoint.UserCode.SPUserCodeWebPartWrapper",
userAssemblyGroupId = "3F74E8EE99624C358005954B7BD10334-idjGV+/yzfqv3u+SsMvNh/QyrYW23cR2ErgVPMa+clc=", siteCollectionId = "22b46f56-a5c1-
47cc-b55f-fdb9b369ca19" - Inner Exception: Microsoft.SharePoint.UserCode.SPUserCodeSolutionProxiedException: Exception of type
'System.Web.HttpUnhandledException' was thrown. ---> Microsoft.SharePoint.UserCode.SPUserCodeSolutionProxiedException: Method not found:
'Void Microsoft.SharePoint.Utilities.SPUtility.GetNTFullNameandEmailfromLogin(Microsoft.SharePoint.SPWeb, System.String, System.String
ByRef, System.String ByRef)'.
at SBWebPArt5_Login_Sable.Login_WebPArt5_Sable.Login_WebPArt5_Sable.<>c__DisplayClass1.<CreateChildControls>b__0(Object , EventArgs )at System.Web.UI.WebControls.Button.OnClick(EventArgs e) at System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument)
at System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument)
at System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument)
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)--- End of inner exception stack trace ---
Server stack trace: at System.Web.UI.Page.HandleError(Exception e)
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
at System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
at System.Web.UI.Page.ProcessRequest()
at System.Web.UI.Page.ProcessRequest(HttpContext context)
at Microsoft.SharePoint.UserCode.SPUserCodeWebPartWrapper.ExecuteHttpRequest(SPUserCodeWebPartHttpRequestContext webPartExecutionContext,SPUserCodeWebPartHttpResponse httpRequestResponse)
at Microsoft.SharePoint.UserCode.SPUserCodeWebPartWrapper.Execute(SPUserCodeExecutionContext executionContext)
at Microsoft.SharePoint.UserCode.SPUserCodeApplicationHostAppDomainRef.ExecuteWrapper(SPUserCodeWrapper wrapper, SPUserCodeExecutionContextexecutionContext)
at System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Int32 methodPtr,Boolean fExecuteInContext, Object[]& outArgs)
at System.Runtime.Remoting.Messaging.StackBuilderSink.AsyncProcessMessage(IMessage msg, IMessageSink replySink)Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.EndInvokeHelper(Message reqMsg, Boolean bProxyCase)
at System.Runtime.Remoting.Proxies.RemotingProxy.Invoke(Object NotUsed, MessageData& msgData)
at Microsoft.SharePoint.UserCode.SPUserCodeApplicationHostAppDomainRef.CodeToExecuteWrapper.EndInvoke(IAsyncResult result)
at Microsoft.SharePoint.UserCode.SPUserCodeApplicationHostAppDomainRef.Execute(Type userCodeWrapperType, SPUserCodeCachedAssemblyGroupuserAssemblyGroup, Guid siteCollectionId, Byte[] binaryUserCodeToken, Byte[] proxyOperationToken, SPUserCodeExecutionContext
executionContext)
04/29/2010 16:47:46.29 SPUCHostService.exe (0x0548) 0x13B8 SharePoint Foundation Sandboxed Code Service
fe3r Medium - - Unhandled exception was thrown by the sandboxed code wrapper's Execute method in the partial trust
app domain: An unexpected error has occurred. - Monitored process "ipc://ef45c9b0-c020-4920-a200-434242116856:7000" has encountered an
unhandled exception while executing user code. - Inner Exception: Microsoft.SharePoint.UserCode.SPUserCodeSolutionProxiedException:
Exception of type 'System.Web.HttpUnhandledException' was thrown. ---> Microsoft.SharePoint.UserCode.SPUserCodeSolutionProxiedException:
Method not found: 'Void Microsoft.SharePoint.Utilities.SPUtility.GetNTFullNameandEmailfromLogin(Microsoft.SharePoint.SPWeb, System.String,
System.String ByRef, System.String ByRef)'.
at SBWebPArt5_Login_Sable.Login_WebPArt5_Sable.Login_WebPArt5_Sable.<>c__DisplayClass1.<CreateChildControls>b__0(Object , EventArgs )at System.Web.UI.WebControls.Button.OnClick(EventArgs e)
at System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument)
at System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument)
at System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument)
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
--- End of inner exception stack trace ---Server stack trace:
at System.Web.UI.Page.HandleError(Exception e)
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
at System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
at System.Web.UI.Page.ProcessRequest()
at System.Web.UI.Page.ProcessRequest(HttpContext context)
at Microsoft.SharePoint.UserCode.SPUserCodeWebPartWrapper.ExecuteHttpRequest(SPUserCodeWebPartHttpRequestContext webPartExecutionContext,SPUserCodeWebPartHttpResponse httpRequestResponse)
at Microsoft.SharePoint.UserCode.SPUserCodeWebPartWrapper.Execute(SPUserCodeExecutionContext executionContext)
at Microsoft.SharePoint.UserCode.SPUserCodeApplicationHostAppDomainRef.ExecuteWrapper(SPUserCodeWrapper wrapper, SPUserCodeExecutionContextexecutionContext) at System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md, Object[] args, Object server,
Int32 methodPtr, Boolean fExecuteInContext, Object[]& outArgs)
at System.Runtime.Remoting.Messaging.StackBuilderSink.AsyncProcessMessage(IMessage msg, IMessageSink replySink) Exception rethrown at[0]: at System.Runtime.Remoting.Proxies.RealProxy.EndInvokeHelper(Message reqMsg, Boolean bProxyCase)
at System.Runtime.Remoting.Proxies.RemotingProxy.Invoke(Object NotUsed, MessageData& msgData)
at Microsoft.SharePoint.UserCode.SPUserCodeApplicationHostAppDomainRef.CodeToExecuteWrapper.EndInvoke(IAsyncResult result)
at Microsoft.SharePoint.UserCode.SPUserCodeApplicationHostAppDomainRef.Execute(Type userCodeWrapperType, SPUserCodeCachedAssemblyGroupuserAssemblyGroup, Guid siteCollectionId, Byte[] binaryUserCodeToken, Byte[] proxyOperationToken, SPUserCodeExecutionContext
executionContext)
Note: GetNTFullNameandEmailfromLogin est la méthode indisponible dans le bac à sable appelée dans l’exemple.
Vincent Runge, Escalation Engineer