In my application I want to support 2 languages (English and Arabic). For now I throw the English version of the help file in a certain path. What if I want the user choose the language he wants to install his application with and according to choose I'll throw the related chm file in that path.
Also another part of the Q, can I do something like when you install an application it asks you the language then it throws only the related exe file?
You didn't tell how you achieve localization in your application. Since you are developing in .NET I assume that you have a .resx file for every language containing all localized data. So why not install both help files and make the path to the help file a localized string in the resource file?
By the way, using localized resource files you will only have one executable to install. You can choose during the loading of your forms which language will be using by specifying the CultureInfo.CurrentUICulture accordingly, e.g. based on a config setting or registry key.
Concerning the second part of your question: You can have your user select the target language. This would set the config setting or registry key described above. However, changing the language during installation would not change the UI language of the MSI installer (I don't think this is supported *).
I would therefore recommend you to have a separate installer for each language or use a different install system (NSIS seems to be a good choice).
*) MSI can select the UI language automatically based on the Regional Settings defined for the user. However, this behaviour is not officially supported and teh way to achieve it is also a little complicated.
Related
I'm using an embedded resource generated by 'PublicResXFileGenerator' which generates my ResourceManager class.
I'm trying to find a way to support multiple resx files for the same language or in some way being able to modify it from a deployed application but this doesnt seem possbible.
For example client 'x' is using the en-US translation:
Flat
and the other client 'y' are using the en-US translation:
Appartment
Maybe the above example is stupid but I hope you get my point.
Different users are using different namings for the same thing and I'd like to support this.
Is it possible?
Note:
My code is written in C#.
The strings in your default resource file (probably Resources.resx) are embedded in your executable file.
If you define a language specific resource file (e.g. Resources.en-US.resx) then Visual Studio will automatically generate a satellite DLL containing the localized resources.
The same applies if you add localized resources to a WinForms form, as shown here for Form1.
The satellite DLL is generated in a sub-directory of the bin directory.
The DLL must be deployed on the target machine in a sub-directory with exactly the same name.
This works for localized strings in any language, but it works exactly the same for strings in the current default language.
If the current default is en-US, and there is a satellite DLL for en-US, and it contains the required resources, then the .NET Framework will automatically use resources from the satellite DLL.
If you don't want the resources from the satellite DLL, no problem. Don't deploy it to the target machine. Then the .NET framework will use the default resources which are embedded in the executable.
If you only have two variations, then it is easy to manage in Visual Studio using the default resource file and an en-US resource file. If you have more than two variations, you are going to need a strategy to generate the resources. The simplest way would probably be to misuse another language.
Alternatively, you could use some other tool. Winres might do the job, but I'm not 100% sure.
Technically, you can define custom cultures, e.g. en-US-medical, or en-US-legal, but in my experience that is more bother than it is worth. I don't think (just my opinion) that Microsoft is strongly committed the concept.
I have an app on Windows Embedded which uses .resx files to translate the app to different languages.
Also I create an installation .cab file but I can't include the resx file to this cab.
How can I achieve this?
Thanks for any tip
A few things:
You'd not told us how you're trying to add the file. Are you using a custom INF file and just calling CABWIZ or are you using a Visual Studio Installer Project?
What have you done to try to include the file?
Most importantly, a RESX file does not contain the run-time resources and you rarely would deploy it. The RESX resources get compiled into a *.resource.dll assembly, that is typically in a subfolder with a name for the locale (e.g. en-us or fr-ca). You need to deploy those files/folders which is challenging because CABWIZ doesn't allow duplicate file names (and all resources have the same file name, just different folders). That scenario is handled by this SO question.
I have my auto generated Resource.resx file set up with keys and strings. I also have three other resx files for German, French and Spanish given to me from translators. I'm not able to get the localization functioning and I suspect that the resx files aren't being called correctly. I added them to the project by dragging them into the solution explorer under "Properties". I have a nagging suspicion that just dragging them in isn't creating the proper connections behind the scene.
Now It's totally possible my issue lies somewhere else. If anyone can tell me whether it's ok to add resource files this way or if not, what the correct way is, it would save me tons of time spent chasing my tail. Thanks!
Resx files in Visual Studio include a special tool which is run at build time and translates them into embedded resources. Right-click your original VS-created resx file and click Properties. You should see Build Tool or something similar. Also note the resource type (Embedded, etc.). Make sure that you match these settings for your manually added files.
Once this is set up, you will need to use the CurrentUICulture property to tell .NET to pick up the appropriate resources. You can choose to change the culture/language at install-time or run-time. Here is a comprehensive tutorial which describes the various options available to you:
WPF Localization Using RESX Files
That said, as a best practice, translated Resx files are generally deployed as satellite assemblies. The main application DLL/EXE contains only the language neutral resources file. Other resource files are compiled into separate assemblies and deployed side-by-side with specific naming conventions. This allows you to dynamically add translations, localizations, etc. even after the application is deployed. Here's an introduction: Packaging and Deploying Resources in Desktop Apps
I have many kinds of xml-files (all with extension .xml) with different root element name and namespace. I want to associate each type with a different application and also make it possible to have different file-icons for each type. Can this be done using C# .NET?
The only way to handle this is in a similar way to that which Visual Studio uses to handle .sln files which is the Visual Studio Version Selector. This application is the one that gets associated with .sln files and handles providing an icon and an eventual process to handle the specific .sln file. Assuming you have Visual Studio installed, take a look in the registry at HKEY_CLASSES_ROOT\VisualStudio.Launcher.sln to see how it's done.
So basically you need to:
Write an executable that can decide what to do with .xml files
Register the process as the one responsible for handling .xml files
Place logic in your executable, or in configuration that your executable consumes, that decides what to do on a per file basis.
For icons, take a look at the subkey ShellEx\IconHandler. You'll see that it points to (on an x64 machine with Visual Studio 2010 installed) HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{9A2B23E4-2A50-48DB-B3C3-F5EA12947CB8} which lists under InprocServer32 a DLL that is responsible for providing icons for files, in this instance C:\Program Files (x86)\Common Files\Microsoft Shared\MSEnv\VSFileHandler.dll. You'll need to implement a similar DLL that shares the configuration/logic of your launcher process to determine what icon to show on a per file basis.
The usual caveat: Writing shell extensions in managed code has always been a big "no no" because shell extensions get loaded into any process that shows the common file dialogs. This can cause merry chaos as, up until .net 4.0, only one version of the CLR can be loaded into a process, so you have to be very sure before doing this. Given that .net 4.0 supports in-process side by side, this may not be an issue for you.
No. To Windows, an XML file is an XML file. The OS doesn't look inside to see what namespace is associated with it; it's just an XML file.
Windows associates file types with their extension, so again, all XML files are XML files. You can see this for yourself: rename a normal .txt file that contains absolutely no XML, and then refresh the view of it's folder in Explorer. You'll see the icon change from a text file image to an XML file image.
There isn't a way that you can do this without having custom extensions or an intermediary program.
Maybe one option would be to have a custom applicaiton which is assigned to handle XML files. When this is program is spawned it works out what the "type" of the file is using one of the XML tags and spawns the correct process accordingly. It's unlikely, however that you can give different "types" different icons.
I have a project that reads in a file based on a value in a C# Setting class. This value however changes from machine to machine and Id rather not ask the user the first time the program is run as its a corporate environment, instead Id like it to be set in the installer, but where is the file located? Is there an easier method?
This is a visual studio addin not a standalone program
From your post it appears you have a windows application? , you can store an initial value in the application config, you can make an installer in Visual Studio and write custom actions that can write values to the file on first install in you install project.
The configure file is the easiest way to do what you are asking, however it is NOT the best. In fact it is recommended Not to use .config files for such cases.
whenever users install an 'update', there is a risk of overwriting their existing changes.
some businesses might have policy restrictions on the .config files.
the user cannot easily move his settings from one PC to another.
From my own experience, using XML, MS-Access, Registry or text files to store user settings has proven more useful than using the .config files.
I believe you are talking about designer-generated settings (the .settings file)?
The exact path usually contains some sort of a Hash (check this link). I usually have my own settings class which I serialize to and from xml using XmlSerializer, which gives me more freedom (I think C# settings files don't allow you to add custom enums, for example, or they make it a bit harder to do it than simply adding them to the .settings file).
However, maybe there is no need to set values during installation? For example, you could add a FirstStartup setting (set to true initially), which you can read when your App is started for the first time, and then set it to false. That way you can set your default settings when you detect a "first startup".
You will certainly need some sort of custom action at the end of your installer. You haven't mentioned what technology you're using to deploy your application so I will refrain from giving any specific guidance.
I recommend setting the value in your App.config. This is an xml file which will be named MyApplication.exe.config in the same directory as your application. Add it to your installer if it is not there already. In your installer, add a new setting:
<configuration>
<appSettings>
<add key="MySetting" value="My Value"/>
</appSettings>
</configuration>
In your code, retrieve the setting:
String setting = ConfigurationSettings.AppSettings["MySetting"];
If this is a machine-wide setting, this installer is the right place to set this. If you do it on the first execution you will run into a host of problems with permissions on the files and directories if the first person to run the app is a user with limited permissions.
Registry or an INI file or a XML file whatever suits you best.
Best option would be registry. Istalling the application will require Admin access so writing to the registry during installation will not be an issue.
More over if some one accidently deletes the ini or settings file then the program might stop working.
You said that this is for a corporate environment. You can create an administrative template for group policy to set the default in the registry. Then, your program can just query that one registry value if the default hasn't already been set.
I personally would never use web.config or app.config. Just read your own xml file, have a look at my post on this:
http://www.picnet.com.au/blogs/Guido/post/2009/09/10/XML-Settings-Files-No-more-webconfig.aspx
Thanks
Guido
To answer the "Where is the file located" bit of the original question for those interested (I'm assuming that the "settings file" in question is the "Settings File" item available from the "Add New Item" dialogue).
In Win7 (and probably all the other ones) the settings file will generate under the path:
C:\Users\[user]\AppData\Local
The folder structure from here on out depends on your AssemblyInfo and build information, the "AssemblyCompany" field (if populated) is used for the top-most folder, beneath this is a folder copying the application executable name, followed by the build and then finally the settings file (named "*.config").
In my case, the complete path is as follows:
C:\Users\[user]\AppData\Local\[company_name]\Application.exe_StrongName_zx0v1qxyoass4d0z3mtwe3vbrhaehkjg\0.0.5812.21662\user.config
My case is different, my project is a class library (dll) which have the app.config file. I decided to create 4 application settings variables (title, url, limit, rate). To create this, i right-click ont he project --> Properties --> Settings. this values you can retrieve in code using this command --> Settings.Default.title, ...etc
the problem is let say i instantiate 5 objects (same object for example MyProject.MyClass) from this library, i want the instance be able to have its own settings. i mean each of the instance may have their xml setting file. can this be done?