Application Settings in .Net Core (WPF) and single exe - wpf

To migrate an application I want to continue using the plain old settings that still come along with .Net5 (App.Config, Settings.settings and so on).
I need a simple built in solution without additional dependencies.
The proposed way seems to be appsettings.json or similar.
For that to use with WPF you need to add some additonal dependencies which bloat the project when
publishing it as single exe (not self contained). It is over-the-top for simple applications.
I followed the steps here:
Equivalent to UserSettings / ApplicationSettings in WPF dotnet core
The accepted answer from Alexander works for a normal exe built.
These are the generated files
MyApp.dll
MyApp.dll.config
MyApp.exe
Modifying "MyApp.dll.config" with an editor directly reflects the changed data in the code.
MessageBox.Show(Settings.Default.SomeConfigValue);
The used config file can be displayed using
var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
MessageBox.Show(config.FilePath);
It displays
C:\Projekte\MyApp\MyApp\bin\Debug\net5.0-windows\MyApp.dll.config
Unfortunately this fails for single exe
These are the generated files (in publish folder)
MyApp.dll.config
MyApp.exe
Modifying "MyApp.dll.config" or "MyApp.exe.config" has no effect. The file does not seem to be used by the framework.
Above messagebox now shows
C:\Projekte\MyApp\Publish<Unknown>.config
How to get the built-in configuration system work with single exe?

Related

WPF .NET Core 3.1 published self contained single exe missing DLL

Have a WPF .NET Core 3.1 app, and it was working on a computer for a while, then it would stop opening. Looking at the event viewer saw this error:
Description: A .NET Core application failed.
Application: MyApp.exe
Path: C:\Folder\MayApp.exe
Message: The application to execute does not exist: 'C:\Users\user\AppData\Local\Temp.net\MyApp\002t0akn.2dd\MyApp.dll'.
If you delete the folder and start the app again it works. Any idea why?
The app is published, .netcoreapp3.1, self-contained, win-86, produce a single file and ready to run
The NET Core "single file" mechanism is a lot like the self-extracting ZIP executables of old; it makes it easier to distribute, but it still needs to dump all of the dependent files out somewhere before it can run, and it looks like the specific temp folder may be giving you issues.
The process is described in Microsoft's documentation:
Extraction Location
For a single-file app, the extraction directory is <base>/<app>/<bundle-id>
<base> is
DOTNET_BUNDLE_EXTRACT_BASE_DIR environment variable, if set.
If not, defaults to:
Windows: %TEMP%\.net
<app> is the name of the single-exe binary
<bundle-id> is a unique Bundle-identifier.
You might try either disabling the single-file packaging or adjusting the environment variable to use a less transient folder for extraction.

WPF: Image Path doesn't work after publishing

I have a trayicon in my WPF App. When I was debugging in Visual Studio, it works well:
System.Windows.Forms.NotifyIcon ni = new System.Windows.Forms.NotifyIcon();
ni.Icon = new Icon("../../logo,ico");
But after I published it, the App threw an exception saying it could find the path of the image of the trayicon. I've search a lot resources on online, I saw many solutions use pack, but it seems pack only accept Uri variable and the path for trayicon must be string. I also tried to create a folder called Resource under the project solution and put the image file into it. This was the same: worked while debugging but would not work after publishing..
So based on #WPF Germany's suggestion, I solved the path issue after publishing the App by Clickonce. However, if I copy a App shortcut to system startup folder, it would find the ico in C:\WINDOWS\system32, which is not easy to workaround since systems32 usually requires admin right to access. Any idea for that?
Did you check, that your logo.ico file is copied to output path?
In VS you have multiple options to provide your Resource files.
First option:
Select your logo.ico file in solution explorer and choose None as Build Action and Copy always at Copy to Output Directory (at file properties).
After compiling you will find the file in a subdirectory of our OutputPath.
use (if logo.ico is placed in your projects root):
ni.Icon = new Icon("logo.ico");
other option:
Use Resource as Build Action and build your Icon using a Stream created from Resources.logo...

How does a WinForms .Net sub-application in a solution embed its app.config into itself?

I am using a variation of Jeff Atwood’s Unhandled Exception handler it steps in when there is an Unhandled Exception in the application. It then logs the error, generates a screen shot and notifies the user.
When compiled in a solution the project generates an EXE that is called when needed. In updating the program I am using Visual Studio 13 to edit the existing settings items in the project properties. In the code I use commands such as this from ConfigurationManager.
string appProduct = unhandledExceptions.Properties.Settings.Default.AppProduct;
I was happy to see that it worked and reflected the changes I made in the IDE. However I couldn’t find the settings in the solutions generated confg file (MyApplication.exe.config). I assumed it was reaching back to the other project folder for the UnhandledExceptions.exe.config.
I created an installer and installed it to a virtual machine. My settings carried over, but again I could not see a config file.
It turns out the values are embedded in the executable UnhandledException.exe.
The project does not have any resources listed. Searching the web and StackOverflow looking a questions that want to do this, and there are a lot of them, it seems this was generally considered not possible and not desirable. Questions usually end in “You don’t want to do that, it’s called config for a reason”.
I may want to turn this off, so it is editable externally. The properties of app.config in both projects are identical.
What setting is making this possible after all? Is it a new capability with Visual Studio 2013?
There is no Visual Studio setting required. If you don’t want the user to have access to the configuration file, don’t include it in the distribution. One can always be added if the settings names are known.
In the description below application generically represents the name of the application being used.
I’ve found through observation some interesting things about the way ConfigurationManager works.
For User settings it will look in the following places in order of priority:
user.config for the application in the user’s AppData area
application.exe.config in the program folder
application.exe itself
Each setting is searched for individually. If your application requests a setting that is not found in either user.config or the application.exe.config it will get it from the executable.
For Application settings it looks in the following places in order of priority:
application.exe.config in the program folder
application.exe itself.
There is no equivalent to user.config for application settings.
Opening the application.exe in the Visual Studio IDE does not reveal a resource for the configuration information.
application.exe.config is handy because it can be modified externally and used as a default value for new installations. Once a setting is overridden in the user.config the value in application.exe.config is ignored.
The same is not true for the AppSettings section, the older configuration method from .Net 1.0. If I delete the configuration file it does not have them in the executable.
These observations were made with Visual Studio 2013 Update 4 and tested in Windows 7 Professional 64-bit. I suspect they are true in all versions.

Does every form and/or console application require installation?

Let's say that I have created a form or a console application. This form application's only dependency is .NET Framework (not a 3rd library) and application doesn't have any kind of requirements. What it does is to take a file and transforms to something else.
Does this application need to be installed? Can I just copy .exe file that is under \bin folder and share it?
First, you need to make sure that Copy Local is set to true for all the references of your start up project. Setting copy local to true will make sure that the DLLs get copied to the output directory. Then, build the solution and copy all the files from your output directory to any machine where you want to run the application. The application should work, as long as it has the appropriate .NET framework installed.
Here's a link about how to set copy local to true: http://msdn.microsoft.com/en-us/library/t1zz5y8c%28v=vs.100%29.aspx
There are 2 Ways to Do This... I just did this 20 Min Ago :)
Method 1 : Right Click on Your Project, Publish, Choose Location For
The installer. This installer can be copied onto other machines, installed and run
Method 2 : Your bin/release folder will contain .exe files which need to be copied and Installed, i prefer the 1st method. It avoids missing important / Needed Files for execution
Just a Side Note. Make Sure the Output Type Is of Console Type (Right Click on project... Output type...), Some windows applications give Problems when Publishing and Installing them due to the frameworks that might be missing

Silverlight fails to fetch resource assemblies

We use the .NET resource manager to localize our Silverlight application and want to embed the satellite assemblies for the german language ("de") into the XAP file. Therefor, we set the neutral language to "en" and added "de" to the list of supported languages in the csproj file. This works fine, when we build the project locally. If we build the Silverlight solution with MSBuild (TFS), Silverlight will try to fetch the satellite assemblies with HTTP requests from /ClientBin/de/*.dll instead of taking those files embeded into the XAP (which do exist). Because the webserver returns 404 error codes for the non existent files, Silverlight crashes with an initialization error.
It turned out that if we remove a custom TFS build activity manipulating the assembly info code files, the Silverlight applications works as expected. Strangely, after re-enabling the activity the compiled XAP application still works (verified for two different build definitions working on seperate branches). The custom activity manipulates the assembly attributes AssemblyConfiguration, AssemblyCompany, AssemblyProduct, AssemblyCopyright, AssemblyTrademark, AssemblyVersion, and AssemblyFileVersion.
Some additional hints:
The custom activity will change the assembly info files before any compilation is done
Compiling the manipulated sources with Visual Studio will build a working XAP
The content of the XAP files (working and not working) is equal (nearly same sizes, no difference in manifest file)
The resource manager is instantiated using ResourceManager("Resource", Assembly.GetExecutingAssembly())
My questions are:
Why does Silverlight try to fetch those satellite assemblies from /ClientBin/de/ instead of just using those in the XAP file?
What kind of attribute in the assembly info file could cause such a behavior?
Why does re-enabling the versioning activity not break the XAP again?
And here's the solution: We use a tool named "Total Commander" for editing a file in the generated XAP to adjust the URL the (generic) client connects to. Since we added the localization dlls, editing the XAP with the Total Commander will lead to the behavior described above. If we manipulate the XAP with WinRAR or the internal Windows archive manager, all works as expected.
Edit: After comparing the XAP files we found, that Total Commander uses the backslash (\) to seperate directories, whereas WinRAR and the Silverlight Tools use slashes (/). It seems that we discovered a hidden Silverlight feature here ;-)

Resources