I can't figure out how to get the CultureInfo of the Installed System on the Client Machine.
There is the CultureInfo.InstalledUICulture Property, but it seems to be unavailable in Silverlight.
Regards
Jonny
I believe that Culture.CurrentCulture will in fact provide you with the user's culture. It can however change or be programmatically set via current thread's Thread.CurrentCulture property. I'm not sure if Silverlight can access the user's machine/operating system culture/language settings beyond this mechanism.
As you mention in a comment, you cannot trust it as it will definitely change through the lifetime of the application. Perhaps then you should record the current culture when the application first starts up before it's programmatically changed, and store it indefinitely (statically or otherwise) to be referenced by your code.
EDIT: Another possibility is to leverage the hosting browser and its JavaScript. Googling around I see that you can access window.navigator.language which will report the language of the browser. Internet Explorer likes to do its own thing and reports the browserLanguage, userLanguage, and systemLanguage.
You can write up a small JavaScript method on the page (you will want to do more cross-browser tests, version tests, and operating system tests):
function GetUserLanguage()
{
if (window.navigator.language)
return window.navigator.language;
else //yay IE
return clientInformation.browserLanguage;
}
Then in Silverlight you might have something like:
string userLanguage = (string)HtmlPage.Window.Invoke("GetUserLanguage");
CultureInfo userCulture = new CultureInfo(userLanguage);
I'm not sure if all cultures reported by the browser (across all browsers/versions/operating systems) will match the culture listing in Silverlight.
Related
I recently started having a problem with CultureInfo in my web application.
The code in question:
public static CultureInfo ConvertToCultureInfo(this string input)
{
try
{
return new CultureInfo(input);
}
catch (Exception)
{
return new CultureInfo("en-US");
}
}
When a user whose locale is 'en-AT' is accessing my website the request for this cultureinfo works on my local but is failing on my Windows Server 2012 box (and falling back to en-US, which is incorrect).
We tracked it down to an issue with the MS-LCID version 10.1 but this is allegedly only available for Windows Server 2016.
However, this occurs to me as kind of silly - why can't we just download a package that updates the existing LCID to support the newer locales? It's still the same list of dateformats and Windows Server 2012 is still supported. I can't find any resources on updating this and was hoping someone here knew a bit about this and could point me in the right direction.
Right now my best lead is to additionally test for custom CultureInfos and supply my own formats, but this seems like overkill when there exists the LCID, it's just somewhat out of date.
I have a web application in which I set the CultureInfo on Thread.CurrentThread to ar-IL (Arabic-Israel):
Thread.CurrentThread.CurrentCulture = new CultureInfo("ar-IL")
The problem is that on my local machine (Windows 10 with IIS 10) it works just fine and no exception is being thrown. However, on Azure (Windows Server 2012 R2 with IIS 8.5) it throws CultureNotFoundException:
Culture is not supported. Parameter name: name 'ar-IL' is an invalid
culture identifier
I checked the source of CultureInfo and realized that the native call to nativeInitCultureData() is the culprit. On my Windows 10 machine it returns true but on Windows Server 2012 it returns false.
Also, checking the SSCLI for nlsinfo.cpp file reveals this comment:
// Call GetLocaleInfoEx and see if the OS knows about it.
// Note that GetLocaleInfoEx has variations:
// * Pre-Vista it fails and has to go downlevel
// * Vista succeeds, but not for neutrals
// * Win7 succeeds for all locales.
// * Mac does ???
So, how can I handle custom combinations of languages and regions (ar-IL, he-US etc) that are not recognized by Windows?
P.S I'm aware of the possibility to create and register a custom locale (using CultureAndRegionInfoBuilder) but it will take too much effort to cater for all the combinations I'm planning to support.
Yes, Windows 10 is able to provide somewhat sensible information for any culture name.
Constructing culture info yourself is an option - as long as calendar information is compatible you can merge strings from neutral ("HE") culture with data for any specific one (like "en-US"). CultureAndRegionInfoBuilder can be used to safely combine information as shown in the MSDN sample:
// Create a custom culture for ru-US.
CultureAndRegionInfoBuilder car1 = new CultureAndRegionInfoBuilder("ru-US",
CultureAndRegionModifiers.None);
car1.LoadDataFromCultureInfo(CultureInfo.CreateSpecificCulture("ru-RU"));
car1.LoadDataFromRegionInfo(new RegionInfo("en-US"));
Aleternatively you can build XML files defining cultures you need to support and either load them at run-time or even install on the servers using CultureAndRegionInfoBuilder.Register - Create custom culture in ASP.NET.
I developed a XAML browser application (XBAP) that is embedded within an ASP.NET web page. I am having a problem getting the latest version of the XBAP to update on the client computer. During development, I have had to use the Mage.exe tool to clear out the application cache so that my changes will be seen when running on my local computer. Besides executing Mage.exe -cc in the command line, I have also found rundll32 dfshim CleanOnlineAppCache to work just as well.
However, I do not want to ask customers to run any commands in the command line. What will I have to do to make the XBAP automatically update on the client computer? Instead of the updated XBAP refreshing on the client computer, the previous version of the XBAP continues to run.
Update
I created a bounty on this question because I have the same issue. From what I read online, XBAPs are supposed to compare the cached version # with the version # of the one on the webserver, and download the new version if it's different. I've verified that my version numbers are different, but the cached copy is still the one that is running when I launch the XBAP.
The cached copy also comes if I launch the XBAP outside of the asp.net page, although I do get the new version if I change the url parameters.
Update #2
I've discovered that the XBAP does automatically update on XP 32-bit machines, but not on my Windows 7 64-bit machine.
You could try something like this, although I use it in XAPs not XBAPs it might work for you too:
(snippet follows)
public partial class App : Application
{
/// <summary>
/// Creates a new <see cref="App"/> instance.
/// </summary>
public App()
{
Application.Current.CheckAndDownloadUpdateAsync();
// rest of code
EDIT
Was gonna suggest incrementing version number between publishes but it seems that's already been taken care of. Does this behavior happen on all browsers ? Might be some IE-specific bug/oddity (i've seen plenty of IE-only misbehaviors... wouldn't surprise me)
Years ago, we had this problem with an ordinary website. It kept haunting us, and in the end, we ended up changing the url prefix for each new version. The very first page was never cached, and forwarded to the updated url.
Its a workaround, I know, but a very reliable one.
You can use ClickOnce to deploy your application. If you want to force user to update just set minimum required version for the application (it's in Application Updates dialog box).
without the correct cache headers your browser may be preventing downloading the xbap.
clear cache to see if this fixes it.
alternatively use:
<%string versionInfo = typeof (AVSTX.POS.WebMvc.Controllers.HomeController).Assembly.GetName().Version.ToString(); %>
<param name="source" value="<%=ResolveUrl("~/ClientBin/AVSTX.POS.WebRia.xap?version=" + versionInfo) %>"/>
to create a new url which the browser cannot cache at this point.
It is based on inspecting the host assembly version so make sure to increment
[assembly: AssemblyVersion("3.4.9.0")]
[assembly: AssemblyFileVersion("3.4.9.0")]
this solution won't solve the dynamic modules you may download in the future. you will need to fix the actual cache headers if this is your problem.
edit 1: code to disable browser caching
//http://stackoverflow.com/questions/1160105/asp-net-mvc-disable-browser-cache
//http://developer.yahoo.com/performance/rules.html#expires
//http://ray.jez.net/prevent-client-side-caching-with-httpmodules/
//http://stackoverflow.com/questions/2281919/expiry-silverlight-xap-file-from-browser-cache-programmatically
public class XapFileHttpModule : IHttpModule
{
#region IHttpModule Members
public void Init(HttpApplication context)
{
context.BeginRequest += context_BeginRequest;
}
public void Dispose()
{
}
private void context_BeginRequest(Object source, EventArgs e)
{
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
if(context.Request.FilePath.Contains(".xap"))
{
context.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
context.Response.Cache.SetValidUntilExpires(false);
context.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
context.Response.Cache.SetNoStore();
}
}
#endregion
}
Application caching is done via manifest files caching, when manifests signatures changes, runtime will upgrade the local files (moreover it just upgrade the changed files). Just sure that you has the right headers sent on HTTP responses. Sometimes dynamic pages cache settings or hosting providers global settings interfere. For me, it always works out of the box.
ClickOnce worked for me like a charm. Also make sure that you're versioning your XBAP properly.
I deploy my Xbap by simply copying filest to ClientBin directory in my web project.
I display it in iframe.
To make application "refresh" version I have to change "Publish Version" in Xbap project before build.
Project Properties -> Publish -> Publish Version.
This changes version in xbap and manifest file forcing clients to download newest version.
I have a web application that will use a few different cultures, one of which is es-US (Spanish United States). However, Windows XP do not have any support for the culture es-US. To work around the problem, I've found out that one is supposed to be able to use the CultureAndRegionInfoBuilder. So I looked into CultureAndRegionInfoBuilder and did the following:
On a Windows 7 machine I saved the culture es-US to an XML-file, as follows:
private static void SaveCultureToFile() {
try {
CultureAndRegionInfoBuilder cultureAndRegionInfoBuilder = null;
Console.WriteLine("Saving es-US to xml disc...\n");
cultureAndRegionInfoBuilder = new CultureAndRegionInfoBuilder("es-US", CultureAndRegionModifiers.Replacement);
// Populate the new CultureAndRegionInfoBuilder object with culture information.
CultureInfo ci = new CultureInfo("es-US");
cultureAndRegionInfoBuilder.LoadDataFromCultureInfo(ci);
cultureAndRegionInfoBuilder.Save("es-US.xml");
}
Then I have a function that reads the xml, and registeres the culture into the system, as follows:
private static void RegisterCultureFromDisk() {
try {
CultureAndRegionInfoBuilder cultureAndRegionInfoBuilder = null;
Console.WriteLine("Loading es-US from xml...\n");
cultureAndRegionInfoBuilder = CultureAndRegionInfoBuilder.CreateFromLdml("es-US.xml");
Console.WriteLine("Culture is registred to the system...\n");
cultureAndRegionInfoBuilder.Register();
Console.WriteLine("The following culture has been registred to the system: \n");
}
So I run the program using the SaveCultureToFile method on a Windows 7 machine, thus saving the culture to an xml file. Then I copy the files to the Windows XP machine, and runs the same program but the RegisterCultureFromDisk() method. But the program fails in the CultureAndRegionInfoBuilder.CreateFromLdml("es-US.xml") method saying that:
"Culture name 'es-us' is not
supported"
Well, thats exactly why I'm trying to load the culture from the xml and registering it into the system.
Do any one know what I'm doing wrong, or how I can create the es-us culture at the Windows XP machine?
Thanx!
I know this is an ancient question, but I've recently run into this issue and managed to actually solve it.
Turns out the CreateFromLdml method can be tricked into loading a non-existing culture if you just create a temporary culture using the name of the one you want to import. Then you can unregister the temporary culture and register the one you just loaded instead.
I've made a simple command-line tool for exporting/importing cultures, which we've successfully used to add in some obscure missing cultures we needed when deploying new servers on Azure.
If you need it - the source code and a more in depth description of the solution is available here.
From MSDN:
Note that a custom culture can be registered on a computer only by a user who has administrative rights on that computer. Consequently, typical applications cannot create a custom culture.
I suspect it might be the cause of your problem... do you have admin rights on this machine ?
The code I am currently working on runs on Windows Server 2003, but needs to be able to write to EventLogs on multiple machines. I am coding in C#, using VS2008 Pro, and .NET Framework 3.5.
The code itself is relatively simple (thanks to the framework):
using (EventLog remoteEvtLog = new EventLog(LogName, HostName, EventSource))
{
remoteEvtLog.WriteEntry(Body);
}
"LogName" is a string containing the name of the log to write to - in most cases "Application".
"HostName" is a string containing the NetBIOS Name of the machine where the log entry should be written.
"EventSource" is a string containing the name of the event sender (this is a utility used by multiple apps, so usually it will have the name of the consuming application).
"Body" is a string containing the text to be written to the event log.
In most cases this works fine, but when the machine being written to uses UAC, any write which creates a new EventSource fails. This occurs even though the Security credentials used are members of the Administrators group - and I have not been able to find a way to specify the elevated priviledge level. Apparently, members of the Administrators goroup get two tokens - one limited, and one elevated, but as far as I can tell, the only way to specifiy the elevated token is through the UI - which is obviously a problem when remotely accessing the Logs.
Any ideas out there?
Your code is not supposed to create new event sources (the legacy auto-create behavior is unfortunate, but still wrong). If you need a separate event source for your application, then the installer for that application - which runs with elevated administrative privileges - should create it.