Include version number in a file on successful build - c#

I developed an ASP.NET web site. When viewing the application in the browser the version number is shown in the footer of the application. But I want to communicate the version number with the customer even if the appliction is not running.
Is it good to use a post build event for it to write it into a text file? If so, how can I access the version number (there is no predefined variable for this) and how can I write it into a text file via the command-line?
Are there any other, maybe simpler ways of getting this done?
Thanks for you help.
Edit: What I forgot to say is that it should be included when publishing the project using the Publish dialog.

You could use a build tool such as msbuild and nant to control the build number and update a application setting in the web.config.
or you can use some reflection code to retrieve it
Assembly web = Assembly.Load("App_Code");
AssemblyName webName = web.GetName();
string myVersion = webName.Version.ToString();
preferably store the string in cache

Related

C# application which installs and allows for global command line

I would like to build a simple .NET application that installs on a windows machine which will allow the end user to open a command prompt and type "google test" which will open google and search for test. But I'm not sure how to install a global "keyword" such as "google". Is this down via Environment variables? How does this link up to my .NET application?
Any advice or pointers is appreciated.
Thanks
This is beyond a .NET application and belongs into the Area of Setup programms. Visual Studio used to have a Installer Project, but as there are so many 3rd party ways this was removed.
Having "google test" parsed as a google search for "test" is tricky, but possible. However it depends entirely on how the commandline is parsed in a Windows. Wich is pretty much the way it was parsed since DOS 1.0.
If you just enter a word like "google", the commandline will look if there is a Excetuable file (.exe, .com, .bat) of that name in the current folder (working directory). It will then look into all the folders defined in the path variables. However using path variables is so dated, I could find only a single entry in my Windows Path variable now. And it is for MS backward compatibility: "%USERPROFILE%\AppData\Local\Microsoft\WindowsApps;"
Most starting of programms is done via file associations with a specific type. And protocoll associations with a protocoll (like http, https, steam). Indeed my advise would be to make a .NET Programm named "google" whose sole purpose is to to format the proper URL, then send it to console parsing via ProcessStart. And let Windows solve wich programm to use from there.
Edit: And as I only realized after wirting this, apparently Windwos finally supports commandline aliases. https://learn.microsoft.com/en-us/windows/console/console-aliases
Apparently they even added a way to make them via the WinAPI in Windows 2000. However that requires moving to unmanaged code. And I have no experience, but it appears those aliases might only be valid for one console instance. So you might have to put it into a place like hte autoexec.bat to be called everytime a console is created.

Multiple language support in Universal App

This is not a question about standard localization - I know how to localize the app, use resources, Uid's and so on - this works perfectly.
The problem is that the app comes within a bundle, therefore when the user installs the app it covers only languages that are selected in device/phone settings. But I would like to provide an option in settings that would allow choosing a language regarding the settings. For this purpose, I can use ApplicationLanguages.PrimaryLanguageOverride, which works very nice when deployed via VS, but as I've mentioned - version from the store lacks resources, as not all are installed.
Does anybody know how to bypass this bundle behavior?
The problem is also that I'm using MAT (multilingual app toolkit) and my translation comes with xliff files. I've spent quite a lot of time to find a way to convert them to resw files, without success. Is there any way to do it (or I've to write my own converter)?
You need to use ResourceContext:
var context = new ResourceContext(); // deliberately not using getForCurrentView()
context.Languages = new string() {"fr-fr"};
ResourceMap resourceMap = ResourceManager.Current.MainResourceMap.GetSubtree("Resources");
String str = resourceMap.GetValue("string1", context).ValueAsString;
More info at:
'How to load string resources' and
'ResourceContext class'ResourceContext class'.
PS. I have app in store and there is no problem with changing language without reinstall so all resources must be there
Check out this: UWP: Resource file for languages is not deployed correctly you need to get rid of bundle in order for my code from above to work. Or you could check if chosen language is installed in OS and if not you could not allow user to choose it using:
Windows.System.UserProfile.GlobalizationPreferences.Languages

Using ClickOnce when i need to generate several large files?

I'm building a digital signage application and I want to deploy it using ClickOnce. (I feel this is the best approach.) When I start the application from Visual Studio (VS) it works great. The application downloads a lot of images from my web service and saves them to disk:
string saveDir = new FileInfo(Assembly.GetExecutingAssembly().Location).Directory.FullName;
When I start my deployed application, it shows the splash screen and then disappears. The process keeps running, but the UI doesn't display. I'm wondering if my saveDir as shown above is giving me trouble?
How do I locate my installed application? (I need to make license files, etc.)
I'm not sure if this is the root of your problem, but I highly recommend you change the structure of how you store your application information.
When an application is installed through ClickOnce, the application is installed within the User's folder, and it's considerably obfuscated. Furthermore, locations may change with subsequent application updates, so you can not be guarantee than any cached, downloaded file will exist from update to update.
To solve this problem, ClickOnce does provide a Data directory, that is not obfuscated and can be used for caching local data. The only caveat is this directory is not available for non-ClickOnce instances of your application (like the version that is running within the VS debugger.)
To get around this, you should write a function that you can use to get your data directory, regardless of your method of distribution or execution. The following code is a sample of what the function should look like:
//This reference is necessary if you want to discover information regarding
// the current instance of a deployed application.
using System.Deployment.Application;
//Method to obtain your applications data directory
public static string GetAppDataDirectory()
{
//The static, IsNetworkDeployed property let's you know if
// an application has been deployed via ClickOnce.
if (ApplicationDeployment.IsNetworkDeployed)
//In case of a ClickOnce install, return the deployed apps data directory
// (This is located within the User's folder, but differs between
// versions of Windows.)
return ApplicationDeployment.CurrentDeployment.DataDirectory;
//Otherwise, return another location. (Application.StartupPath works well with debugging.)
else return Application.StartupPath;
}

Embed individualized code into ClickOnce setup.exe?

I know that it is possible to pass in parameters via URL to ClickOnce apps launched online. However, most users downloads setup.exe and launch it from their machine. Is there any way that I can re-write setup.exe at download, insert a code (let's say the user's email address), and then have the app launch with knowledge of the code? Assume that we can somehow re-sign setup.exe so that it is legit.
Assume .NET 3.5.
Update The goal here is to pass on either email address and/or referrer information to setup.exe so that even when the user runs the installer from a different machine and a different ip we can figure out who did the referral.
Update 2 Assume .NET 3.5 SP1, does it help? Apparently one can now pass parameters to .application while offline. Is it possible to embed parameters into the setup.exe so that it calls .application?ref=someone right when setup.exe is run?
Well, if your goal is to embed a customer id (email, code, etc) into the exe, the easiest way I can think of is using the IPropertyStorage and IPropertySetStorage interfaces. If you are feeling brave, you could call methods directly on IPropertySetStorage via p/invoke, or you could go the easy route and use Microsoft's prepared COM wrapper, which is called dsofile.dll.
Note that while dsofile is intended for office documents, it does indeed work on any file - including .exe files - you are just stuck with the pre-defined property names. Why not throw your customer id into something like the .Comments property. Just do it in such a way that you can parse it out again.
Here's a sample:
var doc = new OleDocumentPropertiesClass();
doc.Open(pathToFile);
doc.SummaryProperties.Comments = "joe#test.com";
doc.Save();
Of course, you need to first copy it to a temp location, and some time after the user downloads it you'll want to delete it.
You can bundle dsofile.dll with your application and register it as a dependancy and use it in your installer to read the property back out. Or if you can p/invoke the IPropertyStorage without it, then you won't have the dependancy.
The other thing to look into would be using the extended file properties that are read by the Shell32.dll. I just haven't been able to find a clean way to write them easily. If you go this route, please share how you wrote the properties to your .exe.
Have a look whether InPlaceHostingManager class can help you in this case. It won't probably do exactly what you have asked for. But may be able to help...
Any ClickOnce application based on an .exe file can be silently
installed and updated by a custom installer. A custom installer can
implement custom user experience during installation, including custom
dialog boxes for security and maintenance operations. To perform
installation operations, the custom installer uses the
InPlaceHostingManager class.
Walkthrough: Creating a Custom Installer for a ClickOnce Application
EDIT
I am not sure whether you could achieve what you want exactly in the way that you have described in the question. Check whether these threads help you.
Accessing Local and Remote Data in ClickOnce Applications
How to include custom data files in ClickOnce deployment?
How to: Retrieve Query String Information in an Online ClickOnce Application
How would you imagine to "rewrite" setup.exe at download? if instead of opening your application with the provided link (url) users are downloading the file locally directly from the network share, you can't intercept this.
I would try to play with permissions and have the users to execute it from the link provided to them, but unable to connect directly to the share or web address and download it. Not sure this is possible anyway.
You can try embedding that information as a resource into the exe.
Here's a c++ example of updating a resource of an exe. http://msdn.microsoft.com/en-us/library/ms648008(v=vs.85).aspx#_win32_Updating_Resources
You should combine approach by Charith and Josh - essentially, configure your web server so that you can generate a new setup based on URL parameters. Use custom installer to read from the referral information from resource for setup.exe. Check this link for how to manipulate resources for a native application in C# - you have to write to resource file while generating setup and need to read it from your custom installer.
Yet another way of generating custom setup would be to build your executable or helper assemblt from command line embedding the necessary information. And then build the setup from command line tools (see http://msdn.microsoft.com/en-us/library/xc3tc5xx.aspx). It appears to be quite cumbersome and will take long time to generate the custom setup as opposed to modifying the resource of already built setup.
A completely different approach would be to email the unique referral code (registration code) whenever user downloads the application. In the setup (or application), use custom installer to prompt user for this code. If the setup is invoked via URL then the code will be available from there and in such case Custom Installer need not ask for the code. The email that you send when user download the setup should inform user to preseve the code into some text file along with the setup file.

Configuration file with ClickOnce deployment

I've been trying to modify my application to deploy and update using ClickOnce. I've managed to get the program working but I'm having trouble with the program configuration. My program uses a custom XML configuration file located in the application directory. This raises 2 major problems.
1.) The configuration file is very hard to get to. Without knowledge of how ClickOnce works the user will not be able to locate it.
2.) Currently if I change the configuration file ClickOnce automatically "updates" the configuration file to the original version, destroying my configuration.
Ideally I would like it to move the configuration file to another location and create a start menu shortcut to it next to my application. But if I change the program to do this can I still deploy the application using ClickOnce?
Thanks in advance,
Fr33dan
Why don't you put a copy of the configuration in the users app data folder (this can be done on first run) - then have a button in your application which opens it (either externally or in your application)?
You can always store your configuration data in the Application Settings. This won't get overwritten on every ClickOnce change or update (unless you change the Type of the setting). You can then create a simple form to update it. That's the technique many .NET developers use for screensavers.
There are a number of things you can do here to mitigate this as a problem.
Firstly, using what's already there - the configuration data has two parts (excuse me as I'm working from memory) app config and user config. The app config is basically defined when the app is pulled down however the user config is just that - you set up the defaults and then, once set by the application on behalf of the user, it won't be overwritten when the app is updated.
It should be straightforward enough to provide a configuration editor - something as simple as a two column grid would be sufficient with a read only label column and an editable value column (although you're going to be somewhat challenged on validation).
Alternatively, if you're happier with a more traditional configuration, then you need precisely 1 user value and that would be the location for the config file... if you don't know if (or can't find the file) prompt to create, dump your default config to the specified location from a resource within you app and then you've got your config file and away you go.
One project I worked on, we made the app download a configuration file from the server it was deployed from (this was done on each startup to cope with if app was added to the Start Menu and cached). The ClickOnce API gives you the server address.
On another project we just pass a few config values as query strings to the ClickOnce app, these were generated by the Asp.net page that had the link to the app.
This allowed customers to change the config for their site without having to resign etc.
(This does not help with per-user config)

Categories