Running Excel in a different locale/Change system locale settings - c#

I'm trying to find a way to change the locale settings when opening Excel, or changing the entire system locale settings.
I know it's bad practice to do this, so I'll just note that this is purely for automated testing reasons. We want to run our Excel add-in simulating multiple different locale settings to make sure it's handling all the functions properly (if there's a better way of doing this than changing settings please let me know!)
I know how to change the CurrentCulture of the thread, but that only seems to apply to our add-in, so functions of Excel called by our add-in run with the system locale settings.
There are 3 ways I've found that I thought might get this working, but one of them seems like an insanely bad idea, and the other two I can't manage to get working:
The really bad one was to import a .reg file in to the system registry before opening Excel, but I don't like the idea of this.
Another way seems to be to use SetLocaleInfo, imported from kernel32.dll, but for the life of me I can't figure out the parameters to use, or even if this is what I need.
The last way was to use Microsofts AppLocale tool, but opening it through that with different language settings didn't seem to achieve what I expected. Actually, it didn't seem to change anything at all from my current system settings!
If anyone can provide any help it would be greatly appreciated, otherwise I guess these are just being left as manual tests!

I would suggest creating several users on your computer and adjusting user locale settings accordingly to your test purposes for each user in Control Panel -> Region and Language. This basically allows setting a default language, and currency/number/date/time formats. If this is what you want, you can launch excel using a different user execution context by either runas command, which requires a manual password entering, or in batch mode using psexec tool from SysInternals: http://technet.microsoft.com/en-us/sysinternals/bb897553
Make sure to specifycommand line options that load account's profile. Unfortumnately you can only adjust user locale settings per each user. System locale settings are defined per computer.

Here you have a full example of how to call SetLocaleInfo from .Net. I won't copy here for brevity, it's a
http://took1.googlecode.com/svn-history/r87/trunk/Code/App.Dev/SetLocale.cs

Related

Is it bad practice to programmatically update the web.config?

I've built an installer that creates a website, application pool, and then assigns the website to the app pool. As part of this I allow the user to input different settings for various connection strings (allows the developer to set them to DEV / UAT etc.). I then modify the web.config with the settings input by the user.
As this is something that will only be installed by a small bunch of developers I'm not concerned with the security of the input (I'm aware they could put in anything), but more with whether it's considered bad practice to modify the web.config in this way?
I've read a few questions on here regarding how people do this and generally in each one there is someone saying that it's not a good idea to do this. The second answer on this question states that doing so will restart your application. I can see how this could cause problems if your user is in the middle of using the app, but for my scenario this isn't relevant. Is this the only reason to consider when doing this?
The warnings are usually applied when someone is talking about having an asp.net website update its own web.config file. But as I understand it, you're talking about updating it from your installer, and this happens before the site is used, so it should be fine.
And, of course, think about it the other way - what's your alternative to manipulating these files programmatically? Do you have any means at your disposal for manipulating these files that doesn't, at some point, have some program open the file and write to it?
Notepad? It's a program.
IIS Manager? It's a program.
Your installer? It's a program.
web.config is like the .htaccess file, in wordpress some plugins automatically updates these files accordingly.
This links might help you, I did have this same question the other day
Change a web.config programmatically with C# (.NET)
Just a (perhaps obvious) thought: Be careful not to overwrite any manual changes added after the installation.
If I had made some custom changes to a config file, I would not want them to be overwritten by a program. It does not sound as if this would happen in your scenario though, so if the solution works for you, I can't see any real problem.

Store the state of a variable in C#

I am working on a c# application that is serially encrypted when user install the application and runs application first time I ask user for key and if he enters right key. I run the application. But my requirement that this process should be one time after installation only,
I think there are two possibilities.
Store software validation state in a variable and use it to allow the running of application (I do not want to use XML,Object serialize as I have to save the state of one variable also user can remove files created by serialize).
Ask user about key while he is installing application,If he enter wrong key then he should not be able to install the software.
Can some body answer
Is there a simple way to store the state of a single variable.
Or
2. How to trigger installer manually (after validation).
Software Protection is an old and expansive topic. The current state of the art, is that it's not really possible to protect you software 100% reliable. Sooner or later, someone will crack it anyway, given enough exposure and/or interest.
Nonetheless, a lot of people and companies protect their software products and there are a number of way to this (not 100% reliably however).
It is not clear what your requirements are, from your question. Given what you've described, the simplest option would be to zip up the installer with a password. If a user don't know the correct password they won't be able to unpack the zip file and install your program.
This is usually not very practical, as the same password is provided for everyone. You want to do your own serial key validation, and you considering doing this at installation time. If this is the route you want to go for you will need to provide some script that will do validation to your installation system. You indicated, that you are using windows installer. You can user Windows Installer XML (WiX) toolset to author an installation. Given enough patience, you can built the key validation into your windows installer package. Most practical way possible is to call your validation routine that you've writen in c# from the wix package. You can use Conditional Syntax to check conditions in your installation. This should cover your option 2.
As for option 1, then whenever in the system you store your piece of information, user always will be able to get there and change it (it's their computer after all). Some people store this in registry, some in key files. Deleting these files is usually not a problem, because if user deletes them, your program will know that it should not run. However a user would be able to copy them on other machine, etc.
Isolated Storage is yet another place to store you information with .NET. Ultimately it is some deeply buried files in the file system anyway.
Once again, Software Protection is a complex topic, it's up to you to decide, what you requirements are, what compromises you can afford and what you choose to implement.
Good luck!
for something like this, i would encrypt it and store it in the registry. this is not they type of thing that you want to store in a settings file. you can check out this codeproject article on how to access the registry using C#.

single exe with changeable settings

I am trying to make a simple application which will be used to point a web browser control to some of our web applications at my work. I would like to have only one exe file but also have an admin window to change some of the settings and have them persist when the application is closed. Is that possible? I have looked at the application settings resources part but as I understand that makes a file that loads the settings.
I don't want to have to parse a file or have anything but ONE file so please don't suggest doing that if it is possible.
Just use application settings - that will create a single file, you won't have to do any parsing, it'll all be fine.
It'll be separate to the exe file, but unless you meant that "ONE file" to include the executable and rewrite that on the fly, it should fit your description easily.
For example, let's build a console app that just remembers how many times it's been launched:
Create a new console application project
Go to the properties page, and click into the Settings tab.
Click on the link to create a settings file
Type in the table to create a setting called "LaunchCount" of type int. Make it either user scope or application scope, depending on whether you want it to be persisted per user or system-wide.
Hit Ctrl-S to save.
In the Main method in Program.cs, write this code:
Settings settings = Settings.Default;
settings.LaunchCount++;
Console.WriteLine("Launch count: {0}", settings.LaunchCount);
settings.Save();
Add the appropriate using directive for Settings (put the cursor in Settings and hit Ctrl-.)
Run the app several times, and observe the number increasing.
You can't have persisted settings without having a separate file...safely. You must either have a separate file, which is the standard and suggested approach approach, like the one created with Application settings, or you must use something like the registry to save settings.
Keep in mind, though, that using the registry is highly discouraged due to security reasons. Plus most companies don't allow access to registries anyway which means that anyone without this access could not use the settings feature.
There are several ways to do this. You can use a command-line argument to do that. Launch the app from the shell and put in your command line argument and change how it launches.
A UNIX-y approach is to look at the name of the exe and change behavior based on that. If I recall correctly, rsh and rlogin are the same executable - they just look at argv[0] to decide how to run. In windows, this is straight forward - look at System.Environment.GetCommandLineArgs - if there is a non-empty string in the 0th element of that, it will be your executable name.
For persisting settings, see Jon Skeet's answer.
I have to say that this is generally a bad idea, but I've done this before a long time ago in VB6. I created a Resource within the exe and then (somehow) directly manipulated it.
The problem is, is that this is usually not possible within the .NET framework due to it being memory resident. These guys tryed it out in .net and they ended up creating an program in IL to do the heavy lifting... Modify Emdeded String in C# compiled exe
Go with a settings file as Jon suggested!

Patch an application

I need to create a patching routine for my application,
it's really small but I need to update it daily or weekly
how does the xdelta and the others work?
i've read around about those but I didn't understand much of it
the user shouldn't be prompted at all
Ok this post got flagged on meta for the answers given, so I'm going to weigh in on this.
xdelta is a binary difference program that, rather than providing you with a full image, only gives you what has changed and where. An example of a text diff will have + and - signs before lines of text showing you that these have been added or removed in the new version.
There are two ways to update a binary image: replace it using your own program or replace it using some form of package management. For example, Linux Systems use rpm etc to push out updates to packages. In a windows environment your options are limited by what is installed if you're not on a corporate network. If you are, try WSUS and MSI packaging. That'll give you an easier life, or ClickOnce as someone has mentioned.
If you're not however, you will need to bear in mind the following:
You need to be an administrator to update anything in certain folders as others have said. I would strongly encourage you to accept this behaviour.
If the user is an administrator, you can offer to check for updates. Then, you can do one of two things. You can download a whole new version of your application and write it over the image on the hard disk (i.e. the file - remember images are loaded into memory so you can re-write your own program file). You then need to tell the user the update has succeeded and reload the program as the new image will be different.
Or, you can apply a diff if bandwidth is a concern. Probably not in your case but you will need to know from the client program the two versions to diff between so that the update server gives you the correct patch. Otherwise, the diff might not succeed.
I don't think for your purposes xdelta is going to give you much gain anyway. Just replace the entire image.
Edit if the user must not be prompted at all, just reload the app. However, I would strongly encourage informing the user you are talking on their network and ask permission to do so / enable a manual update mode, otherwise people like me will block it.
What kind of application is this ? Perhaps you could use clickonce to deploy your application. Clickonce very easily allows you to push updates to your users.
The short story is, Clickonce creates an installation that allows your users to install the application from a web server or a file share, you enable automatic updates, and whenever you place a new version of the app on the server the app will automatically(or ask the user wether to) update the app. The clickonce framework takes care of the rest - fetching the update , figure out which files have changed and need to be downloaded again and performs the update. You can also check/perform the update programatically.
That said, clickonce leaves you with little control over the actual installation procedure, and you have nowhere close to the freedom of building your own .msi.
I wouldn't go with a patching solution, since it really complicates things when you have a lot of revisions. How will the patching solution handle different versions asking to be updated? What if user A is 10 revisions behind the current revision? Or 100 revisions, etc? It would probably be best to just download the latest exe(s) and dll(s) and replace them.
That said, I think this SO question on silent updates might help you.
There is a solution for efficient patching - it works on all platforms and can run in completely silent mode, without the user noticing anything. On .NET, it provides seamless integration of the update process using a custom UserControl declaratively bound to events from your own UI.
It's called wyUpdate.
While the updating client (wyUpdate) is open source, a paid for wybuild tool is used to build and publish the patches.
Depending on the size of your application, you'd probably have it split up into several dll's, an exe, and other files.
What you could do is have the main program check for updates. If updates are available, the main program would close and the update program would take over - updating old files, creating new ones, and deleting current files as specified by the instructions sent along with a patch file (probably a compressed format such as .zip) downloaded by the updater.
If your application is small (say, a single exe) it would suffice to simply have the updater replace that one exe.
Edit:
Another way to do this would be to (upon compilation of the new exe), compare the new one to the old one, and just send the differences over to the updater. It would then make the appropriate adjustments.
You can make your function reside in a separate DLL. So you can just replace the DLL instead of patching the whole program. (Assuming Windows as the target platform for a C# program.)

How can I change a Windows user's regional settings/date format?

I use a VB6/COM+ application which outputs date/time values based on the short date settings in the Control Panel, Regional Settings, for the user that runs it. The program that then parses that output has a configurable setting for the date format it expects, and presents in the UI.
e.g. If the regional setting for the user is set to mm/dd/yyyy, and it outputs 06/18/2009, the application expecting "18/06/2009" fails with "String was not recognized as a valid DateTime".
As we usually run this application as a service account, which we have not logged in as interactively to create a profile, we generally set the correct date format and then tick the "Apply all settings to the current user account and the default user profile" option.
I would like to be make the C# configuration utility I have written for this mess to be able to set the date format programmatically for a given user.
Edit
I would like nothing more than to change the code, but do not have the ability to do so at this time.
I also know that what I am asking is a bad thing to do. With regards to "it should be the user's choice" - I am that user, as I create it explicitly for the task; I just want to set the date format by a scripted method, rather than having to do the clicking myself.
This is specifically discouraged by Microsoft. Any solution you may come up with will be a filthy hack that will probably stop working soon.
Think of it this way: who are you to decide those settings? Don't you think that's the user's decision?
Back on topic: find an unambiguous format for the applications to communicate in, such as YYYYMMDD. The application that displays can then simply respect the actual user settings, as it should.
But, since you can't change it, just poke into the registry:
Current user:
HKEY_CURRENT_USER\Control Panel\International
Specific user:
HKEY_USERS\(user SID)\Control Panel\International
Default user:
HKEY_USERS\.DEFAULT\Control Panel\International
sShortDate is probably the value you want to change.
If you are going to modify the profile to suit your needs, why not just ignore the profile settings and hardcode the format you want in your app?
code:
Imports System.Threading
Thread.CurrentThread.CurrentCulture = New CultureInfo("en-US", False)
Microsoft.Win32.Registry.SetValue("HKEY_CURRENT_USER\Control Panel\International", "sShortDate", "M/d/yyyy")
While persistently changing a user's culture (regional settings) is to be done cautiously, there are legitimate use cases.
On Windows 8 and Windows Server 2012 and above, Windows PowerShell comes with the
Set-Culture cmdlet, which is the programmatic equivalent of choosing a different region via Control Panel (intl.cpl).
For instance, Set-Culture fr-CA is the equivalent of interactively choosing region French (Canada) for the current user.
Caveat: Mixed cultures such as en-DE (sic) appear not to work as of Windows PowerShell v5.1 - see this answer of mine.
While it won't be fast, it is possible to call PowerShell commands from C#.

Categories

Resources