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, 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)    

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, 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)    

 

Note: GetNTFullNameandEmailfromLogin est la méthode indisponible dans le bac à sable appelée dans l’exemple.

Vincent Runge, Escalation Engineer