I need to run a new Process from .NET application with a culture of my choice.
This process will run an external unmanaged 3rd party exe.
How can I make it run with a specific culture?
Note that I don't want to change culture for thread which can be done like this:
System.Treading.Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-FR")
I dont want to setup a default culture for new threads which can be done by reflection or:
CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("fr-FR")
If executable is .Net application you can create your own proxy executable, set culture the way you want and "start" the other application by loading its executable via reflection and launching corresponding Main method. You'll likely need to understand configuration and assembly loading APIs to get all working correctly if it does not magically start on a first try.
For native apps I'm afraid you'd need to change regional settings or for some applications their own configuration.
Related
i'm currently developing a cross-platform App using Xamarin.Forms 3.4 and Visual Studio 2017 (latest version by now).
Since that App should support multiple languages which can be changed on runtime, i'm currently looking into ways to get this done. I already added several resources and translated all interface elements which works just fine. I read through this article to get started:
https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/localization/
For now, when using the UWP app, the language is automatically set to my current system settings, which is the german language, even if the default app language is english. Thats fine.
Now, I got a method which configures my current language by setting several information, like the default CultureInfo object. That method looks like follows:
public void UpdateAppLanguage()
{
CultureInfo ci;
Language l;
// storage is a class containing several persistent information, like
// the language selected by the user to be used
// the Local attribute states if the language is actually present on
// the current user's system
if(Storage.GetCurrentLanguage().Local == true)
{
// language is present locally, so the user wants to use that one for
// the interface
ci = new CultureInfo(Storage.GetCurrentLanguage().Code);
AppResources.Culture = ci;
CultureInfo.CurrentCulture = ci;
CultureInfo.CurrentUICulture = ci;
CultureInfo.DefaultThreadCurrentCulture = ci;
CultureInfo.DefaultThreadCurrentUICulture = ci;
DependencyService.Get<ILocalize>().SetLocale(ci); // set the Thread for locale-aware methods
}
else
{
// no preferences available yet, use the system's current ci
if (Device.RuntimePlatform != Device.UWP)
ci = DependencyService.Get<ILocalize>().GetCurrentCultureInfo();
else
ci = CultureInfo.CurrentCulture;
l = new Language{
Name = ci.EnglishName,
Code = ci.TwoLetterISOLanguageName
};
Storage.SetCurrentLanguage(l);
CultureInfo.CurrentCulture = ci;
CultureInfo.CurrentUICulture = ci;
AppResources.Culture = ci; // set the RESX for resource localization
DependencyService.Get<ILocalize>().SetLocale(ci); // set the Thread for locale-aware methods
}
}
I'm currently testing with a language set, and that language is English.
And here is the dependency service implementation for the UWP sub-project:
public class Localize : stereopoly.ILocalize
{
public void SetLocale (CultureInfo ci)
{
//Windows.Globalization.ApplicationSettings.PrimaryLanguageOverride = ci.Name;
Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = "EN-US";
Windows.ApplicationModel.Resources.Core.ResourceContext.GetForCurrentView().Reset();
Windows.ApplicationModel.Resources.Core.ResourceContext.GetForViewIndependentUse().Reset();
}
public CultureInfo GetCurrentCultureInfo ()
{
return null;
}
}
As you can see, I also tried to set the language to EN-US by force, which doesn't work either. I'm calling the UpdateAppLanguage() method even before the initial Application.InitializeComponent() method runs, I also tried calling it within the OnStart() event method, neither works.
I'd expect the language change getting applied since its executed even before the actual Application starts, but I can switch the several pages of my app as often as I want, the language will always be german, no matter what I do.
I found several answers to this question for plain UWP apps, but not for Xamarin.Forms implementations of UWP projects and that seems to be the problem here, because no other hint regarding pure UWP apps seem to work.
Do you have any idea what might help me?
Thanks.
Make sure you are targeting at least UWP 16299 (FCU), because before that version UWP had issues properly switching languages in debug mode. If you run in Release mode however, it should work normally.
In addition the UWP app needs to know it supports a given language, because this is generated at compile time (using <Resource Language="x-generate"/> in Package.appxmanifest)
You can do this by adding a Strings folder in your UWP project and then adding multiple subfolders - one for each supported language. Finally in each of them add a Resources.resw file (right-click folder, Add > New item..., Resources file (RESW)). The result will look like this.
Then inside each RESW file add some resource. I usually put in AppName, as I often localize it as well:
After this, the app should pick up on the fact that you support the given language and display localized.
I finally found the answer to my problem, it was just as simple as it usually is when it comes to such errors.
It turns out that all bootstrap projects like the UWP, iOS and Android sub-projects also inherit the Assembly Neutral Language from the parent project, no matter what configuration is defined in the specific sub-project (at least thats how it works for UWP). I just noticed that I can set an Assembly Neutral Language within the settings of my .Net main project, and as soon as I did that, all the warnings disappeared and my UWP app ended up showing english text instead of the system default german one. I can also switch back to german now, even though I still have to restart the app to get all frames translated, but thats not that big of a problem, I can work on fixing that up later on. Here's the link that finally got me covered:
Xamarin.Forms: Localization of the UWP app
Thanks for your amazing help anyway :).
This is not a question about standard localization - I know how to localize the app, use resources, Uid's and so on - this works perfectly.
The problem is that the app comes within a bundle, therefore when the user installs the app it covers only languages that are selected in device/phone settings. But I would like to provide an option in settings that would allow choosing a language regarding the settings. For this purpose, I can use ApplicationLanguages.PrimaryLanguageOverride, which works very nice when deployed via VS, but as I've mentioned - version from the store lacks resources, as not all are installed.
Does anybody know how to bypass this bundle behavior?
The problem is also that I'm using MAT (multilingual app toolkit) and my translation comes with xliff files. I've spent quite a lot of time to find a way to convert them to resw files, without success. Is there any way to do it (or I've to write my own converter)?
You need to use ResourceContext:
var context = new ResourceContext(); // deliberately not using getForCurrentView()
context.Languages = new string() {"fr-fr"};
ResourceMap resourceMap = ResourceManager.Current.MainResourceMap.GetSubtree("Resources");
String str = resourceMap.GetValue("string1", context).ValueAsString;
More info at:
'How to load string resources' and
'ResourceContext class'ResourceContext class'.
PS. I have app in store and there is no problem with changing language without reinstall so all resources must be there
Check out this: UWP: Resource file for languages is not deployed correctly you need to get rid of bundle in order for my code from above to work. Or you could check if chosen language is installed in OS and if not you could not allow user to choose it using:
Windows.System.UserProfile.GlobalizationPreferences.Languages
One of our clients requested that some terminology we're using should be changed according to their needs. That means changing a bunch of labels in forms and user messages. Our application is developed as multi-language application so everything is in resource files.
To solve this need I've decided to create a custom culture. I have created hr-HR-HP from standard hr-HR language. I did some tests and everything worked fine.
However, in our project, our third party components break down with the following exception
CultureNotFoundException: Culture is not supported.
Parameter name: culture
4096 (0x1000) is an invalid culture identifier.
Google says that this happens when CultureInfo is created via LCID and that is not supported for custom cultures. So, to avoid this i set Culture parameters as follows:
Thread.CurrentThread.CurrentCulture = new CultureInfo("hr-HR");
Thread.CurrentThread.CurrentUICulture = new CultureInfo("hr-HR-HP");
Great, the error is gone and forms read their resources as expected. However, now ResourceManager is the problem. It's using hr satellite assembly instead of hr-HR-HP one. I use ResourceManager to read the user messages from satellite assemblies.
Any suggestions? Is it possible to specify which language I want for ResourceManager? Should I try some other approach?
Silly me, I was so close to the answer. Just a little more googling reveals that I can specify what culture I want in ResourceManager.GetString() method.
All, I have a localised WinForms application. I have created a facility where users are able to change the required culture/language of the application at runtime. To avoid doing anything fancy, when the use does want to change the culture they are prompted that the application must be restarted for the change in culture to take effect (reasonable as this is not going to happen often if at all). I then store the new language required as a string in one of my settings XML files ("de-DE", "en-US", "en-GB" et al.). Then when the application restarts, if required I switch to the required culture:
// Main constructor.
public SqlEditorForm(string[] args)
{
// Load settings.
username = Environment.UserName;
userSettings = UserSettings.Instance();
advUserSettings = AdvanceUserSettings.Instance();
CheckChangeCurrentCulture();
isInitialising = true;
InitializeComponent();
...
}
private void CheckChangeCurrentCulture()
{
//if (!Debugger.IsAttached)
// Debugger.Launch();
if (advUserSettings.DefaultCulture)
return;
else
{
CultureInfo culture = new CultureInfo(advUserSettings.CustomCultureString);
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
}
}
Now when running in debug/release mode from VS2012, this mechanism works fine. However, when I install the application on (running Windows 7 (x86/x64)) various machines this mechanism no longer works, that is to say that the culture does not switch from the machines default EVER.
I have attached the debugger to the installed application and the code to change the culture is being invoked and the logic seems to be working and no exceptions are thrown, but the culture/language does not change. I have been though many questions on SO but cannot find an applicable one that covers this particular issue.
Why is this mechanism working from VS2012, but not for the installed application? What do I need to do in order to achieve my desired behaviour?
Thanks for your time.
Note, I have also tried replacing the call to CheckChangeCurrentCulture(); with:
Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("de-DE");
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("de-DE");
which also works within VS2012 (Debug and Release modes) but not with the installed application. I have also changed the machines culture Start -> Control Panel -> Region and Language to German ("de-DE") expecting the application and the .NET framework to detect I have that culture available and use it. This also failed for the installed application.
Maybe on your production machines the sattelite assembly of the new culture cannot be loaded for some reason and hence your application falls back to the neutral culture.
Check with Microsoft sysinternals Process Monitor tool for unsuccessfull satellite assembly file accesses.
You an also check with .NET fuslog tool http://msdn.microsoft.com/en-us/library/e74a18c4.aspx
I have an application which has several resource files for different languages depending on the machines culture/language. This works fine if i set the Culture using code, but I am wanting to specify the culture on the command line somehow.
I know in java you simply need to set the VM Args lang attributes and the application starts up in that language, but I am unsure if this is possible using Visual Studio as it doesnt have this type of option.
Can anyone provide a non code solution, I know i could set some cmd line args to read in the lang and then set it using a bit of code but I am wanting to know if there is another way.
I also dont want to keep switching my language using my machine setting.
Cultures are a .NET specific thing, picked up at run-time from the current users 'Locale'. This can be changed by a user at runtime, on a per-application basis.
The default 'Execute Process' functionality does not really support this, a Microsoft utility exists "AppLoc" which adds this functionality. There is an article available on CodeProject Running AppLoc from Batch Files explains how to better control this.
Why do you need to set this using cmd line args?
You could just use current thread CurrentUICulture property to get it.