Does any one know the best way to deploy a resource file to the App_GlobalResource folder of the web application when a feature is activated?
Application resource files cannot be deployed via a feature unless you execute some code and start a SharePoint timer job that copies the files to the App_GlobalResources folder on each Web front-end server.
You should instead let the SharePoint solutions framework deploy the .RESX files to the App_GlobalResources folder on each server. You can specify application resource files as follows in the manifest.xml file of your WSP solution package:
<?xml version="1.0" encoding="utf-8"?>
<Solution SolutionId="{185E973C-3A10-4e2a-9E0F-DC14414551F9}"
xmlns="http://schemas.microsoft.com/sharepoint/"
DeploymentServerType="WebFrontEnd">
<ApplicationResourceFiles>
<ApplicationResourceFile Location="yourappname.resx"/>
<ApplicationResourceFile Location="yourappname.en-US.resx"/>
</ApplicationResourceFiles>
...
</Solution>
When you deploy the WSP solution package using STSADM or Central Administration, the SharePoint solutions framework will start a timer job that deploys these files to the App_GlobalResources folder of all the Web applications you decided to deploy the solution to.
We recently ran into the same issue on our farm installation. Unfortunately, adding ApplicationResourceFile entries in the manifest only gets your resources to the Resources-folder.
While you can manually deploy the resource files from Resources to App_GlobalResources with stsadm -o copyappbincontent (must be issued on every front end server), we ended up creating a timer job to manually copy the files, as outlined here:
So, as a final followup to this question here is what we finally did to completely automate this process.
We did, as was suggested, use the ApplicationResourceFile element in the manifest file.
<?xml version="1.0" encoding="utf-8"?>
<Solution SolutionId="{185E973C-3A10-4e2a-9E0F-DC14414551F9}"
xmlns="http://schemas.microsoft.com/sharepoint/"
DeploymentServerType="WebFrontEnd">
<ApplicationResourceFiles>
<ApplicationResourceFile Location="yourappname.resx"/>
<ApplicationResourceFile Location="yourappname.en-US.resx"/>
</ApplicationResourceFiles> ...
</Solution>
This did in fact put the files into the "resources" folder. So, we simply accessed the resources from there in code like so:
string appPath = HttpContext.Current.Request.MapPath(HttpContext.Current.Request.ApplicationPath);
ResourceManager resX = ResourceManager.CreateFileBasedResourceManager("ResourceFileName", appPath + "resources", null);
SPSecurity.RunWithElevatedPrivileges(delegate()
{
AddResource(resX, "DefaultTextBoxLabelText");
We run this code in the constructor and add the entries from the resource file into a local dictionary. You must use RunWithElevatedPrivileges because the new "resources" folder that is created is only accessable by the AppPool account.