Can I force applications to run in a different locale to the system setting? - localization

I am developing a C# .NET 6 client-server product using VS2022 with multi-language support. I've set up locale-specific resource strings but at the last minute I realized a problem: while client workstations are set up in local language, the app-server is always in English - so back-end code is using the English localization!
Servers are in English for a good reason (and we can't change this) so is there a way to force a deployed application to use a specified locale? Perhaps in a config file somewhere?
I know I can do this in code by changing Thread.CurrentCulture or similar, but the whole point is I don't want to hard-code it, I want it to be config-driven in a way that overrides the default system setting.

I want it to be config-driven in a way that overrides the default system setting.
You can always add custom setting to your config file and then read it on start up and set needed culture.
For example something like this:
appsettings.json
{
"LocaleOverride" : "en-US",
// rest of settings
}
And somewhere at the start of app (depends on how it is started, if generic/minimal hosting is used, configuration can be read from there, otherwise - manually):
var locale = Configuration["LocaleOverride"];
if(!string.IsNullOrEmpty(locale))
{
var cultureInfo = new CultureInfo(locale);
CultureInfo.DefaultThreadCurrentCulture = cultureInfo;
CultureInfo.DefaultThreadCurrentUICulture = cultureInfo;
}

Related

Client configuration in Electron

I am quite new to Electron and I have two questions regarding configuration of my app.
1) Looking for a way to store client configuration (similar to app.config of .Net Apps).
Why I need this:
I am working on a desktop electron app. This app will be distributed to a number of machines and each of them need to have different configuration values.
2) Need a way to package electron app with predefined configuration for a specific machine.
Example:
Machine 1's config: MachineID='M01', MachineType='A'
Machine 2's config: MachineID='M02', MachineType='B'
Appreciate the support!
For me it was the same but I needed to save settings about the window so I made a settings.js file and stored my settings in there.
For you your settings file would contain something like this:
exports.machineType = 'A';
And you would get it in your app like this:
var settings = require('./settings.js');
var machineType = settings.machineType;
if (machineType == 'A') {
// Do things for machine type A.
} else {
// Do things for machine type B.
}

How can I locate a file to use with the system/child_process API within a Firefox add-on?

I would like to write a Firefox add-on that communicates with a locally installed program to exchange data. It looks like this can be done using either js-ctypes or the low-level system/child_process API, with the latter being the recommended solution.
The child_process API appeals because it sends and receives data abstractly over a pipe rather than directly at the C interface level. However, to use it you need (it seems) to supply the full path to the executable within your code:
var child_process = require("sdk/system/child_process");
var ls = child_process.spawn('/bin/ls', ['-lh', '/usr']);
In my case, the executable is installed by another application and we don't know it's exact location - it will differ according to OS, the user's drives, and possibly the user's preference. I imagine this problem will be common to most executables that are not built in to the OS. So my question is: what means do I have to locate the full path of the executable I want to use? I will need to support multiple OSes but presumably could have different solutions for each if needed.
Thanks!
Here's the code I used on Windows - the key was being able to read an environment variable to find the location of the appropriate application folder. After that I assume that my application is stored under a well-known subpath (we don't allow customization of it).
var system = require("sdk/system");
var iofile = require('sdk/io/file');
var child_process = require('sdk/system/child_process');
var progFilesFolder = system.env["programfiles(x86)"],
targetFile = iofile.join(progFilesFolder, 'FolderName', 'Program.exe');
targetFileExists = iofile.exists(targetFile);
if (targetFileExists) {
var p = child_process.spawn(targetFile);
}
I haven't written the code for Mac yet but I expect it to be similar, with the difference being that there are no drive letters to worry about and the system folders in OS X have standard names (even on localized systems).

Configuring grails datasources with username and password from OS environment

I am currently working on a grails application. Previously I have been using Django alot to create webapps. In django you can easily create settings that are collected from the OS environment. I find that to be an easy solution for making sure that you don't check in usernames and passwords into the source code repository.
So what I would like to do is in the DataSource.groovy be able to lift in the username and password from the OS environment. Has anyone done anything like this, or is this not the way to go forward?
If this is not the "grails way", how is it supposed to be done, because having the username and password in the repository just feels wrong?
You can write code in DataSource.groovy and Config.groovy to get env variable and then set username password and other things. I always to it for my production app, sample code is as follows
//Eample is based on url structure like "mysql://username:password#host/database?autoReconnect=true&useUnicode=yes&characterEncoding=UTF-8"
dataSource {
String mysqlUrl = System.getenv("DATABASE_URL")
println ">>>>>> Got DATABASE_URL: ${mysqlUrl} <<<<<<<"
URI dbUri = new URI(mysqlUrl);
username = dbUri.userInfo.split(":")[0]
password = dbUri.userInfo.split(":")[1]
String databaseUrl = "jdbc:${dbUri.scheme}://${dbUri.host}${dbUri.path}"
if (dbUri.port > 0) {
databaseUrl += ":${dbUri.port}"
}
String query = dbUri.query ?: "reconnect=true"
query += "&autoReconnect=true&useUnicode=yes&characterEncoding=UTF-8"
databaseUrl += "?${query}"
url = databaseUrl
dialect = 'org.hibernate.dialect.MySQL5InnoDBDialect'
}
This is one of the way I am sure there must be some simpler way to do this.
PS: I find it simple though :)
You can create a environment variable in Windows. Example DBCONNGRAILS. In config.groovy (...\grails-app\conf\config.groovy) you can use something like
def myConnectionString = System.getenv(DBCONNGRAILS)
WARNING: If you get variables from the environment(Windows) there will no problem when loading the value when in development. But when you are working with a production server, there will be cases when you will need to resart the OS for tomcat to be able to pick up the changes. I would recommend externalizing the config files.
You can externalized the configuration in any other place and load/merge it simply in your application configuration.
We use JNDI at work for exactly this scenario. We have context.xml files located within the individual server's Tomcat directories. The context.xml contains the datasource properties and then within the datasource closure (defined in Datasource.groovy), the jndiName property is set accordingly.
More Links about JNDI:
http://grails.github.io/grails-doc/2.3.7/guide/conf.html#JNDIDataSources
http://grails.asia/how-to-make-grails-use-jndi-datasource-with-tomcat

Grails - computer/browser locale doesn't affects i18n mechanism

I'm having a weird problem or maybe i failed to understand how Grails i18n mechanism works.
I inserted the following to my index.gsp file:
LocaleContextHolder.locale: '${org.springframework.context.i18n.LocaleContextHolder.locale}'
java.util.Locale.getDefault(): '${java.util.Locale.getDefault()}'
RequestContextUtils.getLocale(request): '${org.springframework.web.servlet.support.RequestContextUtils.getLocale(request)}'
session['SessionLocaleResolver.LOCALE']: '${session['org.springframework.web.servlet.i18n.SessionLocaleResolver.LOCALE']}'
This code snippet should print the Locale, and it does like so:
LocaleContextHolder.locale: 'iw'
java.util.Locale.getDefault(): 'en_US'
RequestContextUtils.getLocale(request): 'iw'
session['SessionLocaleResolver.LOCALE']: ''
The above is my default output when i run the given code snippet.
I tried to understand what exactly affects this variables so i did the next steps:
I changed Chrome's Locale
Settings --> Show advanced settings --> Language and input settings)
I changed my operating system's locale (Windows 7)
Control panel --> Region and language --> Format + Location + System locale
After those changes i rebooted my computer and expected the values of the locale variables to change, but they still remain the same.
I'm aware i can change the Locale with the ?lang parameter & with some code, but i'm interested in letting Grails to decide which Locale to pick.
What exactly affects those variables? how does Grails decide the machine's locale?
15.2 Changing Locales
By default the user locale is detected from the incoming Accept-Language header. However, you can provide users the capability to switch locales by simply passing a parameter called lang to Grails as a request parameter:
/book/list?lang=es
Grails will automatically switch the user's locale and store it in a cookie so subsequent requests will have the new header.
from here :
https://grails.github.io/grails-doc/2.4.3/guide/i18n.html
If you are deploying in tomcat you can set the locale in the catalina.sh script:
if [ -z "$LOGGING_MANAGER" ]; then
JAVA_OPTS="$JAVA_OPTS -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Duser.language=en -Duser.region=US"
else
JAVA_OPTS="$JAVA_OPTS $LOGGING_MANAGER -Duser.language=en -Duser.region=US"
fi
I think the internationalization works when you pass lang parameter in the URL. It's mentioned in the documentation
By default the user locale is detected from the incoming Accept-Language header.
However, you can provide users the capability to switch locales by simply passing
a parameter called lang to Grails as a request parameter:
/book/list?lang=es
http://grails.github.io/grails-doc/latest/guide/i18n.html
By default the user Locale is detected from the incoming Accept-Language HTTP header, this header is generated by the browser that is used by the user.
Each browser determines the system Locale differently:
Internet Explorer uses the O/S Locale settings.
Firefox / Chrome let the user to decide what Locale to use (In the language settings).
See: http://www.w3.org/International/questions/qa-lang-priorities.en.php

Administrator rights request

I've got error if I don't run my program "As Administrator"
Access violation ... in module ... etc...
Got error when trying to work with my ini file.
How to avoid error or make a request Administrator rights.
(using C++Builder6 , but Delphi code is readable for me too)
working with ini by default
TIniFile *FormCllient;
FormCllient = new TIniFile(ExtractFilePath(Application->ExeName)+"Inf\\MyIniFile.ini");
...
Added :
I think I need add rules for folder after install application
I make install pack with Inno Setup ... Hope that's real.
*****Added : *****
How to put my file into app data ?
Don't put the ini file along the application /unless you really have to/. The common user, even the administrator /when app not explicitly elevated/ has no right to write into the Program Files folder.
Use environment var %ProgramData% if you want to write the ini accessible for all users, and use env var %USERPROFILE%\AppData\Roaming if you want to write user specific data accessible only by the current user.
You can use also "SHGetFolderPath" in order to obtain these folder via API.
Here's a function I wrote to get the Application Data folder in C++Builder.
If you're using older versions of C++Builder, you might find you have to change this to use AnsiStrings instead of Unicode (replace the "UnicodeString"s with "AnsiString"s, and change the call to "SHGetSpecialFolderPathW" to read "SHGetSpecialFolderPath").
GetAppDataFolder.h:
#ifndef GetAppDataFolderH
#define GetAppDataFolderH
UnicodeString GetAppDataFolder(bool roaming = true);
#endif
GetAppDataFolder.cpp:
// Helper function to get the location of the current user's Application Data folder (used for
// storing per-user application settings).
#include <vcl.h>
#pragma hdrstop
/* roaming: True for application data that can be accessed by the same user on different
machines. If you have per-user settings that are only relevant to a particular
computer, e.g., screen resolution, set 'roaming' to false.
*/
UnicodeString GetAppDataFolder(bool roaming /* = true */)
{
UnicodeString retVal;
int csidl = roaming ? CSIDL_APPDATA : CSIDL_LOCAL_APPDATA;
wchar_t thePath[MAX_PATH];
if (SHGetSpecialFolderPathW(NULL, thePath, csidl, 0) == TRUE) {
retVal = thePath;
}
return retVal;
}
Try hard coding it, the access violation is probably coming from asking the system for information about a file that the user may or may not have permissions to know about. if you need a more dynamic solution try using an environment variable that refers to the location of the file or the users "home" folder
Any reasons for/against storing your app configuration in the registry? I'm not suggesting you redo the code that brought up the question, just curious for my own future projects.

Resources