Monday, January 10, 2011

How to add new event handlers

Hi Michae

I'm guessing you mean how to add new event handlers for the different components on your form (just clarifying).

I see two options
1. In the design view, highlight the control in question. In the properties window hit the event button (the lightning bolt). That will show you all of the events that the control can handle - find the one you want and type the name you want and you'll get thrown into the code editor with a function ready to be filled in
2. If adding the event handler manually via the C# code, try typing the name of the control, followed by a "." to trigger the intellisense. Pick the event your want (again the events have the lightning bolt) by hitting TAB, type in the "+=" needed to add the event handler delegate, then follow the instructions that popup (basically hit TAB twice again and VS.NET will add an event handler in for you automagically)


Monday, November 8, 2010

Location of ClickOnce Installation Files

C:\Documents and Settings\USERNAME\Local Settings\Apps\2.0

Friday, November 5, 2010

Show or hide file extensions

A file name extension is a set of characters added to the end of a file name that determine which program should open it. Follow these steps to choose whether Windows displays these file extensions.

  1. Open Folder Options by clicking the Start button Picture of the Start button, clicking Control Panel, clicking Appearance and Personalization, and then clicking Folder Options.

  2. Click the View tab, and then, under Advanced settings, do one of the following:

    • To hide file extensions, select the Hide extensions for known file types check box, and then click OK.

    • To display file extensions, clear the Hide extensions for known file types check box, and then click OK

Reference in the manifest does not match the identity of the downloaded assembly

If you try to reference an executable or a project with an executable you get an error when you try to update the application via ClickOnce.
The errror I got was:
"Reference in the manifest does not match the identity of the downloaded assembly"
The fix was found here:
And below are the steps:

I have test it with Visual Studio 2008 RTM, it works well now. The following steps are my test procedures.

1. Create a solution with two Windows Application projects, WinAppA and WinAppB.

2. Set WinAppA as publish project and add a reference to the WinAppB.

3. Open WinAppB properties window.

4. Click Signing tab, sign the ClickOnce manifests.

5. Click Security tab, enable the ClickOnce security settings.

6. Publish the WinAppA, publish well.

7. Test published WinAppA, it works well.



Bitmaps in WPF, disposing of bitmaps in WPF and other issues

The first thing is in WPF you can't set the Source of an Image Control to that of a Bitmap, you need to use the BitmapImage
This gives you a build error:
Image I = new Image(@"C:\Users\Public\Pictures\Sample Pictures\Penguins.bmp");
Imagecontrol.Image.Source = I
But this works:
Image I = new Image();
BitmapImage bi = new BitmapImage();
bi.UriSource = new Uri(@"C:\Users\Public\Pictures\Sample Pictures\Penguins.bmp", UriKind.Absolute);
Imagecontrol.Image.Source  = bi;
The problem with the above code is that whenever I used it and subsequently tried to delete the file Penguins.jpg or move it, I got an exception.  It seems like we were holding a lock on the file.  So the fix was to do the following:

      Imagecontrol.Image.Source = LoadImage(@"C:\Users\Public\Pictures\Sample Pictures\Penguins.bmp");

      private BitmapImage LoadImage(string myImageFile)
            BitmapImage myRetVal = null;
            if (myImageFile != null)
                BitmapImage image = new BitmapImage();
                using (FileStream stream = File.OpenRead(myImageFile))
                    image.CacheOption = BitmapCacheOption.OnLoad;
                    image.StreamSource = stream;
                myRetVal = image;
            return myRetVal;

Monday, October 4, 2010

Have Log4Net generate the log files to another location besides the Program Files

- To have log4net write to the temp directory

  <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
    <file value="${TMP}\log.txt" />
    <appendToFile value="true" />
    <rollingStyle value="Size" />
    <maxSizeRollBackups value="10" />
    <maximumFileSize value="100KB" />
    <staticLogFileName value="true" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%-5level [%date] %message%newline" />

or     <file value="${HOMEPATH}\log.txt" />

Wednesday, June 30, 2010

app.config and user.config FAQ

A great tutorial and insight into the app.config file and user.config file

One of the cool new features in .NET 2.0/VS 2005 is an easy to use,
extensible API to manage application/user settings, i.e., data that
needs to be persisted across runs of a client application. You can
find more information about this feature on MSDN or in my earlier blog
posts on this topic.

While the feature is easy to use in general, we often get questions
from users trying more advanced scenarios about why a certain aspect
of the feature works in a particular way or how to customize some
behavior. The answers to these questions are generally in the MSDN
docs, but can sometimes be hard to find. I thought it would be useful
to cover this information in a FAQ for easy future reference. I will
be updating the FAQ as and when there are more questions to add.

Q: I notice there are two kinds of settings - application scoped and
user scoped. Application scoped settings seem to be read-only and I
cannot change them at runtime. Why is that?

A: There are two main types of settings that applications generally
want to store: (1) certain data like connection strings and web
references that don't change often, but should be possiblep for an
admin to change and therefore cannot be hardcoded into the application
and (2) user preferences and customization that can change any time.
Application scoped settings are useful in scenario (1) and user scoped
settings, in the latter. They are essentially read only from tche
application's point of view and aren't meant to be changed by the
user, but admins could go and edit the file if they want to. An
additional reason for this has to do with how the default
SettingsProvider stores settings - application scoped settings go in
the exe configuration file and user scoped settings in user.config
files located in the user data path. Generally, exe config files
shouldn't be written to at runtime by the application, since the user
may not have access to them (if the application is installed in
c:\Program Files\..., only privileged users have access, for example).
Even if they do, it is not usually a good idea for a user to control
changing a file that affects every other user of the application.

Q: You said user.config files go in the user data path. How can I
locate the file? Are there multiple files for an application or just

A: As mentioned before, the default SettingsProvider for client
applications (called the LocalFileSettingsProvider) stores settings in
the application configuration files. In .NET v1 and v1.1, there were
two levels of config files - machine.config and app.exe.config (where
'app.exe' is the name of the application). In v2.0, we have added two
more levels of configuration to store user specific data - one that
goes in the roaming user profile path and another in the local user
profile path. On XP, the profile directories would be something like
'c:\Documents and Settings\<username>\Application Data' and
'c:\Documents and Settings\<username>\Local Settings\Application Data'
respectively. These directories are the recommended location (per
Windows Logo requirements) for storing user specific information and
most applications (like Outlook and Visual Studio) put user data
somewhere under here.

The exact path of the user.config files looks something like this:

<Profile Directory>\<Company Name>\<App Name>_<Evidence
Type>_<Evidence Hash>\<Version>\user.config


<Profile Directory> - is either the roaming profile directory or the
local one. Settings are stored by default in the local user.config
file. To store a setting in the roaming user.config file, you need to
mark the setting with the SettingsManageabilityAttribute with
SettingsManageability set to Roaming.

<Company Name> - is typically the string specified by the
AssemblyCompanyAttribute (with the caveat that the string is escaped
and truncated as necessary, and if not specified on the assembly, we
have a fallback procedure).

<App Name> - is typically the string specified by the
AssemblyProductAttribute (same caveats as for company name).

<Evidence Type> and <Evidence Hash> - information derived from the app
domain evidence to provide proper app domain and assembly isolation.

<Version> - typically the version specified in the
AssemblyVersionAttribute. This is required to isolate different
versions of the app deployed side by side.

The file name is always simply 'user.config'.

If you want to get to the path programmatically, you can do it using
the Configuration Management API (you need to add a reference to
System.Configuration.dll). For example, here is how you can get the
local user.config file path:

Configuration config =
Console.WriteLine("Local user config path: {0}", config.FilePath);

Q: Why is the path so obscure? Is there any way to change/customize it?

A: The path construction algorithm has to meet certain rigorous
requirements in terms of security, isolation and robustness. While we
tried to make the path as easily discoverable as possible by making
use of friendly, application supplied strings, it is not possible to
keep the path totally simple without running into issues like
collisions with other apps, spoofing etc.

The LocalFileSettingsProvider does not provide a way to change the
files in which settings are stored. Note that the provider itself
doesn't determine the config file locations in the first place - it is
the configuration system. If you need to store the settings in a
different location for some reason, the recommended way is to write
your own SettingsProvider. This is fairly simple to implement and you
can find samples in the .NET 2.0 SDK that show how to do this. Keep in
mind however that you may run into the same isolation issues mentioned
above .

Q: I deployed my application using Clickonce and saved some settings,
but can't find the user.config file.

A: The path algorithm mentioned above is not used in the Clickonce
case. Instead, the local user.config file goes in the Clickonce Data
directory (the <Version> part of the path will still be included).
There is no roaming user.config file for Clickonce applications.

Q: How are my strongly typed properties serialized as settings? I
couldn't get the <insert type here> class to serialize correctly.

A: There are two primary mechanisms that ApplicationSettingsBase uses
to serialize settings - (1) If a TypeConverter exists that can convert
to and from string, we use it. (2) If not, we fallback to the
XmlSerializer. While most common types can be serialized in one of
these ways, there are some types that may not. In such cases, you have
a few different options:

* Implement a TypeConverter for the type that can convert to and
from string. The implementation can use a suitable serialization
mechanism like one of the formatters/serializers that ship in the
Framework or any custom mechanism you wish. You can then specify this
converter on the type itself or on the property in your settings
* Specify a particular SettingsSerializeAs enum value using a
SettingsSerializeAsAttribute. For example, if you wish to serialize a
setting in binary format, simply specify SettingsSerializeAs.Binary.

Q: My application has a few user scoped settings, but I notice Visual
Studio puts them in app.config. I thought they go in user.config

A: The configuration system is hierarchical and has this ordering:
machine -> application -> roaming user -> local user. When you query a
configuration section at any level, you get a merged view of the
sections declared in that level and those below it (with machine being
the lowest level and local user the highest). The section handler
defines how the merge happens and for settings, a setting value
specified in, say, local user config trumps the one specified in
application config.

So for user scoped settings, you can think of the values specified in
app.config to be install time defaults. When the settings are saved
into user.config, those values will override these defaults. This way
admins have the option of changing the defaults. Note that the
defaults can also be specified by means of a
DefaultSettingValueAttribute. The provider will use this value if no
value is specified for a setting in any level of config.

Q: Why is there a version number in the user.config path? If I deploy
a new version of my application, won't the user lose all the settings
saved by the previous version?

A: There are couple of reasons why the user.config path is version
sensitive. (1) To support side-by-side deployment of different
versions of an application (you can do this with Clickonce, for
example). It is possible for different version of the application to
have different settings saved out. (2) When you upgrade an
application, the settings class may have been altered and may not be
compatible with what's saved out, which can lead to problems.

However, we have made it easy to upgrade settings from a previous
version of the application to the latest. Simply call
ApplicationSettingsBase.Upgrade() and it will retrieve settings from
the previous version that match the current version of the class and
store them out in the current version's user.config file. You also
have the option of overriding this behavior either in your settings
class or in your provider implementation.

Q: Okay, but how do I know when to call Upgrade?

A: Good question. In Clickonce, when you install a new version of your
application, ApplicationSettingsBase will detect it and automatically
upgrade settings for you at the point settings are loaded. In
non-Clickonce cases, there is no automatic upgrade - you have to call
Upgrade yourself. Here is one idea for determining when to call

Have a boolean setting called CallUpgrade and give it a default value
of true. When your app starts up, you can do something like:

if (Properties.Settings.Value.CallUpgrade) {
Properties.Settings.Value.CallUpgrade = false;

This will ensure that Upgrade() is called only the first time the
application runs after a new version is deployed.

Update: 12/10/2005

Q: Is there a way to access settings from the configuration files if I
don't have a reference to the settings class that owns them?

A: Yes, you might sometimes require to access certain settings, but
you don't have access to the settings class itself. For example, the
default settings class generated by the settings designer in VS 2005
is internal to the assembly it is defined in. What if you need to
access some settings from a different assembly, let's say, a dll that
is loaded by your application? The settings API provides a useful
mechanism for this through the SettingsGroupNameAttribute. Usually,
the settings provider uses the fully qualified name of your settings
class as the key to isolate your settings from those belonging to
other classes. This attribute allows you to access settings with a
different key or 'group name'. So to access settings from the
application's settings class, all the dll needs to do is define its
own settings class with properties that match the other class, and
apply a SettingsGroupNameAttribute, giving it the other class' name as
the group name. A small caveat: if you want to do this in VS, make
sure you apply the attribute to the user partial class you get to by
clicking 'View Code', and not the designer owned partial class, since
any changes to the latter can get overwritten by the settings

Q: Wait, you might ask, this is a rather powerful capability. Is it a
security hole? Someone might access my settings without my knowledge
or permission!

A: Well, this isn't really a security hole for two reasons:

From a security point of view, isolation is provided at the app
domain level. The CLR recommended way of hosting untrusted code is to
load it in a separate app domain. When you create an app domain, you
can specify a unique friendly name for it and point it to an
application configuration file of your choice. The unique friendly
name ensures that the app domain gets separate user configuration
files as well. Thus, the code cannot access your settings, since it
doesn't have access to your configuration files. Conversely, any code
that has access to your configuration files can access the settings
without using the SettingsGroupNameAttribute anyway, since it can use
the low level configuration APIs to do so (this requires
ConfigurationPermission for read though, and much higher permissions
for write).
If you are really paranoid and don't want users of the
application or anyone else, including code running in the same app
domain as your settings class, to be able to read your settings
outside of your class, you can choose to encrypt the settings before
pushing them to the provider, and decrypt when you read them out. The
settings API does not provide any specific way to do this, but you can
use the crypto API in the .NET Framework. The configuration API also
has the ability to encrypt configuration sections - see this article
for more information.

Q: Does all this mean I cannot access settings in partial trust?

A: Not at all. We have done the work to ensure you can safely access
your settings in partial trust. In fact, this should 'just work' for
you in terms of reading and writing user scoped settings from your
application. The only difference is that you cannot write out an
unlimited amount of data, for obvious reasons. The number of bytes you
can write through the settings API (specifically, the
LocalFileSettingsProvider) in partial trust is restricted by an admin
controlled quota, which is specified by the IsolatedStoragePermission
class. This is just like how Isolated Storage itself works.

Q: You mentioned the configuration API a couple of times. What is this
and how is it different from the settings API? I am a little confused.

A: There is a fundamental distinction between the settings API and the
configuration API. The former provides an object model to manage
application settings. This model uses a provider based storage scheme,
so the storage aspect is abstracted away. Where the settings are
stored is a provider specific detail - it could store them in raw
files, in SQL server, in the registry or call a remote web service to
retrieve them. The default settings provider we ship happens to use
configuration to store settings, since that's the most obvious store
for settings in client applications. The configuration API is a little
more low level and lets you create and update configuration sections
in config files. So in some sense, the settings API sits on top of

So if what you want to do is store application settings and user
preferences, then the settings API is the way to go. If you really
need to implement configuration sections and/or access certain
sections in config directly, use the configuration API.

Q: Is the settings functionality available only to Windows Forms applications?

A: The settings API itself has no restrictions at all - you can use it
in any kind of application - client, web, VSTO, console, WPF etc. The
default settings provider, LocalFileSettingsProvider, uses
configuration to store settings, so it has certain limitations. For
example, ASP.NET applications do not have user.config files, so you
cannot write user scoped settings in web applications using this
provider. Ofcourse, you can use the Profiles feature in ASP.NET 2.0 to
very conveniently store user scoped settings. User.config files are
also not supported for VSTO apps (in general, where the host
application is native, like Outlook, Word or even IE). In these cases,
you will need to write your own settings provider (which is quite easy
to do, by the way, and there are good samples and docs in MSDN that
describe how to do this) to be able to read/write user scoped
settings. For the basic kinds of managed client applications like
console, Windows Forms and WPF however, the LocalFileSettingsProvider
is fully supported.