Application is a C# .Net 3.5 WCF Service.
I'd like during the build process to dynamically add some build information to the final binary and assemblies that can then be read programatically and sent back to the WCF client when it sends a GetVersionInfo request to the web service.
.Net assembly versioning isn't enough. I want to include additional string data that contains the state of the system at the time the application was built.
I'm thinking that I'd do this by adding a post build event to call a script to update the app.config file with the data I want. Does this sound about right, or should I be considering some other approach?
Update
I'd additionally like this string to appear in the "Special Build Description" property of the final exe. I.e. I'd like to right click on the file and see this information in the version tab for the file.
Thanks in advance.
I suspect a pre-build event may be more appropriate than post-build... have you considered adding a buildinfo.xml file (or similar) to be built into the assembly as an embedded resource? You could then load it with Assembly.GetManifestResourceStream. That way you don't need to worry about fitting in with existing files or anything like that - just overwrite buildinfo.xml with a new file in the pre-build step.
You have to decide how important it is that the information you want to exchange is tied to the executable file itself.
Updating the config file during the built is a workable model, but it places the information in a location where it could be altered by anyone with access and a text editor.
Updating information after a build in a compiled assembly is certainly possible, but it's fragile and breaks down if you ever decide to sign the assemblies. It's also a lot of work, since there's no built it support for re-writing assembly files in this manner.
An alternative you should consider, is creating your own custom assembly-level metadata attributes and assigning them during the build process. You could even place them in a separate code file (or append them to AssemblyInfo.cs) as part of you build.
You could also consider creating an embedded resource (an XML file, for instance), and retrieving it from the assembly manifest at runtime.
Either of the above approaches would require you to use a pre-build custom step rather than a post-build step.
Personally, I find the metadata attributes a convenient approach if there isn't a lot of data. Otherwise, I would consider using an embedded resource file.
Related
My app has been designed to be able to run on two different languages, english and czech. In order to accomplish this, I've created 2 resource files:
If an end-user would like to add another language, for example GlobalStrings.fr-FR.resx, is it possible to allow for this functionality without rebuilding the application?
If we look at the properties of these resource files:
I'm not understanding what embedded resource means. Does this mean that in order for the app to consume this file, the application must be rebuilt?
How do we create a resource file, that is open to be extended/changed by the end user, without having to rebuild the entire application
?
Regular .Net resources are compiled into assembly with particular name and loaded by matching that name. So if "end-user" is ok to translate strings in resx file and compile resources into assembly with particular name (like "MyResources.cs-cz.dll") you can do that with default .Net behavior without recompiling main code. See MSDN:Packing and Deploying resources and related links for more information.
Note that you don't need Visual Studio for it and can use csc command line compiler to embed resources on user's machine - so if your really want you can provide simple script that compiles corresponding resx locally. Note that editing XML (resx) as text is generally not possible by regular person due to required encoding of some characters - consider technical level of your "end-users" before going that route. Plain text version of source for resource may work in more cases.
Usually this is not the case - if end-user localization is requirement you would create some sort of custom resource string management by loading strings from plain text files or database that users can update locally.
My question is essentially the same as this one but for a Windows Store App, c# and Visual Studio. I want to have an easy way to keep secret values in the project, in a file that can be ignored in (not checked in to) source control. How should I structure my project to store the app secret in a way that makes building/source control easy?
My first idea was to store it in an XML file (not checked in), and load it at runtime, but this leaves it available to the user who installs it, so it should be done at build time. How can I store a couple secret values and have visual studio replace them in my code when my project is built?
In my company we decide to you following solution. In config file we link sections with "secret" values in external configs.
External configs are on source control. First it wasn't but after a problem when our build server lost a disk we decide it it safer to store it on a place which has backup. The folder in source control (can be also on file server) is really restricted to read and write to only people who needs this. Build process checkouts "project" folder plus "configuration" folder and do build. After build "configuration" folder is deleted. Access to build server is also restricted.
One option is to store the secrets in source control, but store them in an encrypted form. In your development or build environments, use a environment variable to store the key, and decrypt on the fly. That way you get the benefits of source control while keeping your info safe.
It is possible to do this even if you are using app.config or web.config, you just need to modify the configuration from code at startup.
Erick
Updated
If you put a secret in an untrusted area (e.g. public source control), it is vulnerable. Even if it's encrypted, with enough diligence it can be retrieved.
The only way to really keep it out of reach is to have an external service that interacts with the 3rd party API. That has its own trade-offs (e.g. user authentication as you mentioned in comments). Especially if your developers need to utilize the 3rd party API when testing, I see no other alternative that will limit the secret's exposure.
Create a new class file in your project that has slots for all of your secret values, and holds dummy/test values for all of them. Check that into source control with the rest of your project, so that anybody building it without access to the secrets will get some sort of test version.
Then, create a copy of that class file with the real secret values, and put it somewhere outside of source control. Write a batch script in the pre-build event that looks for this class file, and if found, replaces the dummy file that is included in the project with it.
This way, your project can still be in source control and anybody can check it out, build it, and run it in the test mode. Your secret file/values are stored on your build server only, so only when you build the project there will it have the real values.
Do remember to back up your secrets file somewhere. And also remember that .NET code can be decompiled easily, so your secrets may not be as secret as you hope them to be - any user with a .NET reflector can see all of the code in your release assembly, including your secret class.
Hello guys I think the question i asked in the previous post is unclear OK fine. i am explaining in brief.
for example.
I have a form where i have placed one textbox and command button.
I have fired a event when i click the button the text under the textbox change to "hello" ok fine.
what is my problem is..
the application is created and I published ok.
After some week I thought I want to update my application. where in the place of "hello" I want "hi". I know that we can compile the whole project and publish it.
but I don't want my whole application to be updated.
for example.
What antivirus company do they have a definition file where they only update the definition file not the whole application. after the update it applies to whole application.
I want my application also to do same process like antivirus company do.
You should read that "Hello" from a content file (XML). Then you can just push out the new file.
Use a configuration file. You can add an application.config (or if you're developing a web app, web.config) file to your primary project. Within this configuration file, you can define AppSettings (which are built-in, usually simple and atomic string or number fields that the application will need), ConnectionStrings (which specifically provide information applications will need to connect to a database), or custom configuration sections (used for more complex, related sets of data that are loaded into custom classes you define, such as a basic company profile). Within your code, you access AppSettings by using the static ConfigurationManager.Appsettings[] collection; you tell it the name of the setting you defined in the file, and it returns the value (or null, if it can't find the setting you defined).
Related, but different, is the use of Resource files. Resource files usually contain a dictionary of location-specific data used by the UI, such as text strings, icons and images. Actual resources can be compiled into one big file, or resource files can be a list of paths and filenames to the actual resources. You can use resource files to create different "skins" for your application to be used by different companies by referencing images to use for UI elements, or to translate labels and other text on your application's UI. Resource files are accessed through a ResourceManager; you tell it where the resource file is, and it will load the information into a similar "dictionary"; you then tell it the name of the resource and you get the resource back.
For your specific question, I'll answer the same thing as Henk. But, I think that your real question is "How I do create patch in .NET".
You can check this link:
How can I patch .NET assemblies?
You could design your application to use plugins. This way you only have to update a plugin and not the whole application.
if you want to create a patch for asp.net application , first of all , you have to deploy your project with Web Deployment Project.
then choose Create a separate assembly for each page and control output in output assemblies tab and re-build your solution .
the result of deployment is bunch of DLL which mapped to each page or control.
Now if you changed one page's data (in code behind) , you need to deploy your project again but in this case you can just upload the changed dll file.
I want to store settings for my C# application, such that default setttings can be easily shipped with my binaries and the end-user can change them using a simple text editor(or in some other simple way).
I seem to face several alternatives : a .config file, .settings file or a .resx file. What are the pros and cons of these?
Edit1: End-users are computer professionals mainly, so editing these files should not be much of a problem.
Edit2: The settings are something like connection strings, and some other parameters (mostly one-time stuff). Building some kind of GUI/API for changing them is not really an option. Also my application will not edit any of these values, so persistence through code is not required.
Yes, Project + Properties, Settings tab was designed to do this. Add your settings here, change the Scope to Application. That generates a app.exe.config file in your build direcctory, deploy it along with your EXE. Use Properties.Settings.Default.SettingName in your code to obtain the setting value. Your user will normally need admin privileges to edit the .exe.config file on the target machine to change the setting value.
The small print: settings do not work well for DLL assemblies, you have to merge the .config files by hand. When using the debugger, settings are retrieved from the app.vshost.exe.config file.
The .settings file is a helper file used by the IDE, ignore it. .Resx files store resources, they get compiled and embedded in a binary form in an assembly. They are not editable by the user.
I think you can have two ways of doing this.
For regular users, you can make a custom GUI that will make it simple for them to use.
For advanced users, they can edit the configurations using a text editor if it's stored in a text file (ini file, config file, etc..) or you can make an API.
The .settings file is typically used for user-specific preferences and configuration information (whereas the .config file is used for global settings for the application or anything that modifies the .Net runtime. Simply putting parameters in a .config file can alter the behavior of your application even without you writing a single line of code for it).
Check out the Settings article on MSDN for more: http://msdn.microsoft.com/en-us/library/aa730869(VS.80).aspx
Since the file will be modified by the users, I think using app.config is not a good idea. What if they break the file structure? Or set an invalid value? Probably your application will crash directly.
One of the solutions would be to use a custom XML file. You will then validate it when your application starts. XSD will probably be the more elegant way to do it, but you can also parse it directly and validate it in code. If the file is invalid, instead of crashing, you will try to solve the problem, and if impossible, display a pretty error to the user, explaining that there is an error in XML at line n, position n, which is [error description here].
If the end user is really going to be editing them, I'm not sure I would want them editing my app.config file.
You have another couple alternatives that you haven't included. You could use an old-school .INI file that is simpler for an end user to understand. You could also use the registry. I would recommend the INI file, unless your users are very savvy, in which case use the .config file.
The answer depends on the deployment method. For instance, if you are using ClickOnce and offer updates, you might encouter problems using Application Settings.
I believe the best way to go is to create a GUI, something that is most certainly suitable for novice users. Given that you already excluded that option, use John's suggestion (ini files).
does somebody know how can I embedd an exe file into a dll ?
I have a tool which is an exe file that I call from c# code.
The thing is that I want to have 1 dll containing this tool (exe file) and the dll containg my c# code.
Is it possible to embedd this exe file within the resources?
Thx in advance
Sure it is. You can add any file as RC_DATA in application as resource. But I believe you will need to extract it to disk first before calling it!
Which IDE/Language you are using?
[EDIT]
Sorry! you did mention that you are using C#.
Add a resource file to you application (right click application in IDE and select "Add new item".
Use the toolbar in resource editor to add an existing file.
Then extract the exe whenever required by calling code something like:
System.IO.File.WriteAllBytes (#"C:\MyEXE\", Resource1.MyEXE);
It's worth baring in mind that your uses may not be too happy about you doing this. Embedding an executable that they've got no control over into a DLL that you'll extract and run will probably make people worry about the running a Trojan on their machine.
It's better to leave the .EXE in the filesystem and be transparent about what your application is doing.
You can load an Assembly from a byte[]. This can be obtained via the ManifestResourceStream of an embedded resource.
An alternative may be to not embed the .exe itself, but rather include its functionality in the dll, and use rundll32[1] to execute it.
On a side note, remember that when you pull a file from your resources to disk and then execute code on it, you may trigger Windows Data Execution Prevention - basically, Windows tries to automatically detect if something is supposed to be code or data, and if it looks like data (which a resource would), then it will prevent that data from being executed as code.
This becomes a particularly sticky issue if your .NET assembly is going to be used over a network instead of from a local drive - there are all sorts of .NET security configurations that might prevent this from working correctly.
Another option, and not knowing the details of your project, take this with a grain of salt: add a .exe.readme file to your install that describes to any curious users or IT people why there is an executable they weren't expecting in the installation directory :)