Sharepoint Deploying resource files to app_globalresources folder using Timer Job.


Hi Everyone ,
in this article i want to explain how to copy your resource files to web application’s app_globalresources folder using by a timer job.

As you know there is four place that the resource files has to be.

\14\Resources\
\14\Template\Features\<Feature Name>\Resources\
\14\Config\Resources\
[Virtual Directory] \App_GlobalResources\

I could not tell about which folder for what,  this is out of concept.But i will explain that

the files which in  \14\Config\Resources can copied to [Virtual Directory] \App_GlobalResources\ folder when a new web.application created. But what about the existing ones.
Friendly stsadm command give us some help.
STSADM -o CopyAppBinContent
But still you can run this command all your sharepoint servers.And this is not an aswer for if you aim to deploy some specific web applications.
You can use
SPWebApplication.ApplyApplicationContentToLocalServer()  fuction for do it with programmatically by creating and using a feature reciever class.

public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
            SPWebApplication webApp = properties.Feature.Parent as SPWebApplication;
            if (webApp != null)
            {
                 ...Somecodes.
                 webApp.Farm.Services.GetValue().ApplyApplicationContentToLocalServer();
            }
        }

I could say that cause a latency when you click to activate button for this feature.and stsadm -o copyappbincontent and ApplyApplicationContentToLocalServer() only copy the resource files on the local server.So
we have  options with Visual Studio 2010 and Sharepoint 2010

First  i will start with the easy way if you are using Sharepoint 2010 and Visual Studio 2010 .
1) Create an Empty Element from vs ide and rename it OurResources.
2) Add a resource file to this element named TestResource.resx
3) Select TestResource.resx and Change property value of  “Build Action”  key to “Resource” from Visual Studio IDE Properties window
4) Change property value of Deployment Type key to “AppGlobalResource”
5) Expand the “Deployment Location” and set the Path is empty .for doing that we can able to copy our resource file root folder of App_GlobalResources.

Second you can use ApplicationResourceFiles element on your Solution xml
<ApplicationResourceFiles> 
    <ApplicationResourceFile Location=”blog.resx”/> 
    <ApplicationResourceFile Location=”blog.en-US.resx”/> 
  </ApplicationResourceFiles>

But what if you are developing a farm scope feature or webapplication scope features that should add extra resource file to selected web applications or you have multiple server farm and you want to deploy resource files accross the farm .This time you may need a TimerJob for deploying your resource files.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using System.IO;

namespace ResourceDeployment
{

    public class DeployResourcesJob : SPJobDefinition {
        public readonly static string DefinitionName = "job-deploy-resources";

        #region Constructors
        public DeployResourcesJob() : base() { }
        public DeployResourcesJob(SPWebApplication webApp) : base(DeployResourcesJob.JobDefinitionName, webApp, null, SPJobLockType.None) {
            this.Title = "Deploy Resource Files";
        }
        #endregion

        public static void ActivateJob(SPWebApplication webApp) {
            // Delete if any existing jobs
            DeployResourcesJob.Delete(webApp.JobDefinitions, JobDefinitionName);

            DeployResourcesJob job = new DeployResourcesJob(webApp);
            job.Schedule = new SPOneTimeSchedule(DateTime.Now.AddHours(-2));
            job.Update();
        }

       public static void RemoveJob(SPJobDefinitionCollection jobDefinitions, string name) {
           DeployResourcesJob existingJob = jobDefinitions.GetValue(DeployResourcesJob.JobDefinitionName);
            while (existingJob != null)
            {
                existingJob.Delete();
                existingJob.Unprovision();
                existingJob = jobDefinitions.GetValue(DeployResourcesJob.JobDefinitionName);
            }
        }

       public override void Execute(Guid targetInstanceId) {

             string source = SPUtility.GetGenericSetupPath("Resources");
            // Copy or remove the resource file for all zones
            if (Directory.Exists(source)) {
                foreach (SPUrlZone zone in this.WebApplication.IisSettings.Keys) {

                    // Get the location of the App_GlobalResources folder under the target Web Application
                    string destination = this.WebApplication.GetIisSettingsWithFallback(zone).Path + "\\App_GlobalResources";

                    if (Directory.Exists(destination)) {
                        string[] resourceFiles = Directory.GetFiles(source, "MyResource*.resx");
                        foreach (string filename in resourceFiles)
                        {
                            string destinationFilename = destination + "\\" + Path.GetFileName(filename);
                            File.Copy(filename, destinationFilename, true);

                        }
                    }

                }
            }
        }

}
}

Here Some Resources:
http://blogs.msdn.com/b/johnwpowell/archive/2009/11/29/sharepoint-2010-localization-with-visual-studio-2010.aspx
http://blogs.msdn.com/b/maximeb/archive/2008/04/26/deploying-resource-files-across-a-farm.aspx
http://cicoria.com/cs1/blogs/cedarlogic/archive/2010/01/31/deployment-of-resource-files-resx-to-app-globalresources-under-sharepoint.aspx

End of Article 🙂

Advertisement

About bpostaci
Escalation Engineer in Microsoft.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: