3

I'm developing an application for mobile devices (Windows CE 5.0, .NET compact framwork 2.0 pre-installed) using .NET compact framework 3.5 and MS Visual Studio 2008.

I'm using the built-in option for creating localized forms. This works perfectly as long as I use the debugging function of Visual Studio with the mobile device connected to my desktop computer. In this case, Visual Studio deploys my application along with .NET compact framework 3.5. After disconnecting the mobile device and having installed my application it is still working as expected.

My problem is: If I install the .NET compact framework using the CAB file provided by Microsoft and then install my application (also by using the CAB file created by Visual Studio) without having used the debugger the application works as well but without localization. So I think there must be some parts of the .NET framework which are only installed using the deployment function of Visual Studio - and which are making .net recognizing the locale. - Does anybody know which parts (libraries...?) are these? Since the application will be provided to users which will not use Visual Studio I've to find a solution for this.

  • 1
    Have you verified that the CAB file actually installs your localized resource assemblies? – Daniel Hilgarth Aug 21 '13 at 14:04
  • There isn't a "localization" part of the CF. You're likely not deploying the localized resources with your CAB, or you're deploying them to the wrong place. – ctacke Oct 20 '13 at 20:33

2 Answers2

0

I used the tutorial - guide to do resource localization using Compact Framework: http://www.codeproject.com/Articles/28234/Survival-guide-to-do-resource-localization-using-C

Cornel Marian
  • 2,443
  • 23
  • 28
0

The answer is simple. It should work. But it does not.

There is clearly a bug in Microsoft's tool CABWiz used by Visual Studio to generate CAB files. It has a problem when using files with the same name in different subfolders, like when using localizations.

After hours of trying to fix it, I ended up whith a solution inspired by the CodeProject guide as given by Cornel in the previous answer : You have to "hack" the Visual Studio process of generating CAB, by using resource files with unique name, and then modifying the INF file to specify the original name for deployment on the device.

To automatize a little more, I made a little EXE that is launched as project post-build :

        FileInfo CurrentExeInfo = new FileInfo(System.Reflection.Assembly.GetExecutingAssembly().Location);

        // Current Folder + bin\Debug
        DirectoryInfo BinDebug = new DirectoryInfo( Path.Combine( CurrentExeInfo.Directory.FullName,  @"bin\Debug") );

        // Subfolders in \bin\Debug
        Console.WriteLine(BinDebug.FullName);
        string[] Dirs = Directory.GetDirectories(BinDebug.FullName, "*", SearchOption.TopDirectoryOnly);

        // In each localization folder ...
        foreach (string Dir in Dirs)
        {
            DirectoryInfo DirInfo = new DirectoryInfo(Dir);

            // ... Resource files
            string[] RFiles = Directory.GetFiles(Dir, "*.resources.dll");

            foreach (string RFile in RFiles)
            {
                FileInfo RFileInfo = new FileInfo(RFile);
                bool DoCopy = false;

                // No underscore in resource name
                if (!RFileInfo.Name.Contains("_") || RFileInfo.Name.IndexOf("_") == 0)
                {
                    DoCopy = true;
                }
                // underscore in resource name
                // --> Have to check if already a copy 
                else
                { 
                    // prefix removal
                    int PrefixIndex = RFileInfo.Name.IndexOf("_");
                    string TestFilename = RFileInfo.Name.Substring(PrefixIndex + 1);

                    if (!File.Exists(Path.Combine(Dir, TestFilename)))
                    {
                        // File without underscore does not exist, so must copy
                        DoCopy = true;
                    }
                }

                if (DoCopy)
                {
                    // Copy file
                    string NewFileName = Path.Combine(Dir, DirInfo.Name.ToUpper() + "_" + RFileInfo.Name);
                    Console.WriteLine("Copying " + RFile + " -> " + NewFileName);
                    File.Copy(RFile, NewFileName, true);
                }
            }
        }

And then this CAB patcher after normal CAB generation :

    const string cabwizpath = @"C:\Program Files (x86)\Microsoft Visual Studio 9.0\SmartDevices\SDK\SDKTools\cabwiz.exe";

    static void Main(string[] args)
    {
        if (args.Length == 0)
        {
            Console.WriteLine("Aborted: You must enter the inf file information");
            Console.ReadLine();
            return;
        }
        if (!File.Exists(args[0]))
        {
            Console.WriteLine("Aborted: I can not found the INF file!");
            Console.ReadLine();
            return;
        }

        // string to search
        Regex R = new Regex("\"[A-Z]{2,3}_(.+)\\.resources\\.dll\",\"([A-Z]{2,3})_(.+)\\.resources\\.dll\"");

        // File reading
        string inffile = File.ReadAllText(args[0]);

        // Format replace from
        // "FR_ProjectName.resources.dll","FR_ProjectName.resources.dll"
        // To
        // "ProjectName.resources.dll","FR_ProjectName.resources.dll"
        inffile = R.Replace(inffile, "\"$1.resources.dll\",\"$2_$3.resources.dll\"");

        // Rewriting file
        File.WriteAllText(args[0], inffile);
        Console.WriteLine("INF file patched ...");

        // Génération du CAB ...
        Console.WriteLine("Generating correct CAB ... ");
        System.Diagnostics.ProcessStartInfo proc = new System.Diagnostics.ProcessStartInfo("\"" + cabwizpath + "\"", "\"" + args[0] + "\"");
        proc.ErrorDialog = true;
        proc.UseShellExecute = false;
        proc.RedirectStandardOutput = true;
        Process CabWiz =  Process.Start(proc);
        Console.WriteLine("\""+cabwizpath + "\" \""+ args[0]+"\"");
        CabWiz.WaitForExit();
        Console.WriteLine("CAB file generated (" + CabWiz.ExitCode + ") !");
    }

I hope it helps.

More links about this :

Jalil
  • 3,150
  • 3
  • 30
  • 39