5

I'm having an issue, when I'm trying to work with a config file, I've read a few posts here and somewhere else but I can't solve problem in work,

In my question here, I have added the Configuration.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
            <section name="CA.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
        </sectionGroup>
    </configSections>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
    <userSettings>
        <CA.Properties.Settings>
 
          <appSettings>
            <add key="ab123" value="D:\ab123\Source\ab123.c" />
          </appSettings>

        </CA.Properties.Settings>
    </userSettings>
</configuration>

Declared in the document

string ab123 = ConfigurationManager.AppSettings["ab123"];

But in the side , I show error is " win32 Exception was unhandled - System can not find the file specified"

System.Diagnostics.Process.Start(ConfigurationManager.AppSettings["ab123"]);

When I run this code, ab123 value is always null! I'm sure the path is normal.

How can I fix it?

Krzysztof Madej
  • 32,704
  • 10
  • 78
  • 107
kyoko
  • 65
  • 1
  • 7
  • 4
    Focus on the problem. First get the config value, then try to start a process. You're not getting a value, which is a legitimate question to ask, but the process start failure is just a byproduct. For your question itself, please follow some answers given here: http://stackoverflow.com/questions/1189364/reading-settings-from-app-config-or-web-config-in-net – Ofer Zelig Sep 04 '14 at 01:49
  • @Jonesy the question was about standard config keys, not a custom config section... – Ofer Zelig Sep 04 '14 at 01:51
  • @OferZelig It's mean can't get the value? – kyoko Sep 04 '14 at 02:03
  • In your xml file I don't understand what `` does in the context of the configuration manager. What happens if it is removed? – Michael Petch Sep 04 '14 at 02:05
  • @OferZelig: by "standard config keys", you mean ``? – John Saunders Sep 04 '14 at 02:07
  • I just realized it might be something trivial. You are specifying a `.c` file. Do you have a default file association set to open `.c` files? If not it would probably give you this error. Try this code with a txt file as an experiment and see if a default editor loads the txt file. To see if you can open `.c` files this way open a command prompt and simply issue this command `D:\ab123\Source\ab123.c` If putting that at the command prompt doesn't open a program then this would be reason Process.start can't either – Michael Petch Sep 04 '14 at 02:18
  • It is trivial - he's probably passing in null. See my answer. – Dave Sexton Sep 04 '14 at 02:33
  • If it had returned null the error would have been "Additional information: Cannot start process because a file name has not been provided." – Michael Petch Sep 04 '14 at 02:50
  • Perhaps, but clearly he's passing in null if he's using `AppSettings` to retrieve a setting from a config section defined for **Application Settings**. – Dave Sexton Sep 04 '14 at 03:11
  • @DaveSexton I use "AppSettings" It can run But can't open the file – kyoko Sep 04 '14 at 03:24
  • @kyoko But are you sure that AppSettings is actually returning the full path? Please confirm. – Dave Sexton Sep 04 '14 at 03:26
  • @DaveSexton I confirm it It full path – kyoko Sep 04 '14 at 03:29
  • @kyoko So then @MichaelPetch is probably correct in that `Start` requires a file extension mapping on your computer. I'm curious as to the results of his test that he recommended for you; namely, try changing the path to a .txt file and see if it runs notepad. – Dave Sexton Sep 04 '14 at 03:32
  • @DaveSexton I try to open .txt file , It's can't open it – kyoko Sep 04 '14 at 03:36
  • 1
    @kyoko If it's the same exact error as before then there must be some other problem. Please try to reproduce the problem in a [short but complete sample](http://www.yoda.arachsys.com/csharp/complete.html), including all C# code and XML configuration. – Dave Sexton Sep 04 '14 at 03:37
  • @DaveSexton When I run the code, I find "ab123" value always null !!!!! I sure path is normal – kyoko Sep 04 '14 at 06:19
  • Read the documentation that I linked you to and look at the example in my answer. `appSettings` is in the wrong place! – Dave Sexton Sep 04 '14 at 13:50

5 Answers5

4

It appears from your xml config files that you are really trying to use User Settings rather than Application setting and that you have mixed some of the ideas up. I think a more correct version of a config might be:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
            <section name="CA.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
        </sectionGroup>
    </configSections>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
    <userSettings>
      <CA.Properties.Settings>
        <setting name="ab123" serializeAs="String">
          <value>D:\ab123\Source\ab123.c</value>
        </setting>
        </CA.Properties.Settings>
    </userSettings>
</configuration>

The only significant difference is the way you define settings. For example I changed it to:

<setting name="ab123" serializeAs="String">
    <value>D:\ab123\Source\ab123.c</value>
</setting>

You can create more settings just like this using a different name

The client code is a bit different as it has to find the userSettings, find the program property settings and then query for the key (like ab123). I have added some trivial error handling but you need to deal with the errors yourself. I simply return on error for code simplification. The code has inline comments to help figure out what is going on.

using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;
using System.Diagnostics;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            // Retrieve the userSettings gorup
            ConfigurationSectionGroup group = config.SectionGroups[@"userSettings"];
            if (group == null) return;

            // Get the program settings
            ClientSettingsSection clientSection = group.Sections["CA.Properties.Settings"] as ClientSettingsSection;
            if (clientSection == null) return;

            // This retrieves the value associated with the key
            string sFileName = clientSection.Settings.Get("ab123").Value.ValueXml.InnerText;

            // Check if ab123 has a value and the file exists
            if (!string.IsNullOrEmpty(sFileName) && System.IO.File.Exists(sFileName))
            {
                using (StreamReader sr = new StreamReader(sFileName))
                {
                    string line;
                    // Read and display lines from the file until the end of  
                    // the file is reached. 
                    while ((line = sr.ReadLine()) != null)
                    {
                        System.Diagnostics.Debug.WriteLine(line);
                    }
                }
            }
        }
    }
}

If you are using Settings.settings to create and delete settings then the code can be simplified to this since Visual Studio will create bindings for your settings object that be accessed at design time and runtime. For information on using Settings.settings through the Visual Studio IDE please see this article. If for some reason the code below doesn't work you can use the code above:

using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;
using System.Diagnostics;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string sFileName = Properties.Settings.Default.ab123;

            // Check if ab123 has a value and the file exists
            if (!string.IsNullOrEmpty(sFileName) && System.IO.File.Exists(sFileName))
            {
                using (StreamReader sr = new StreamReader(sFileName))
                {
                    string line;
                    // Read and display lines from the file until the end of  
                    // the file is reached. 
                    while ((line = sr.ReadLine()) != null)
                    {
                        System.Diagnostics.Debug.WriteLine(line);
                    }
                }
            }
        }
    }
}
Michael Petch
  • 46,082
  • 8
  • 107
  • 198
1

It looks like you're mixing two models.

  1. Application Settings are defined by declaring a class that derives from ApplicationSettingsBase, though typically you don't do this manually. Instead, let VS create the class for you by going to your project's Properties > Settings tab. This creates a special section in your config file that looks similar to the XML that you posted.
  2. App Settings are defined in a special appSettings configuration section. Only these kinds of settings can be accessed via the ConfigurationManager.AppSettings property, as you're doing. See the XML example below.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="ab123" value="D:\ab123\Source\ab123.c" />
  </appSettings>
</configuration>

The reason that you're getting a Win32Exception is because, according to the documentation, it's thrown even if the specified path is null. And ConfigurationManager.AppSettings returns a null reference when the specified setting is not found in the config file. (Just to be clear, it's not found in your case because you're not using the appSettings config section as shown above.)

Dave Sexton
  • 2,562
  • 1
  • 17
  • 26
  • I try it but have problem "" win32 Exception was unhandled - System can not find the file specified"" – kyoko Sep 04 '14 at 02:47
  • Did you put it in the app.config file for your .exe project? The config file that is generated for .dll projects has no relevance at all. – Dave Sexton Sep 04 '14 at 03:08
  • YES put in exe project – kyoko Sep 04 '14 at 03:31
  • In that case, I'm sure that the path can be resolved now. The error is probably due to a missing file mapping as suggested by @MichaelPetch. – Dave Sexton Sep 04 '14 at 03:34
  • IS System.Diagnostics.Process.Start(ab123); ?? – kyoko Sep 04 '14 at 03:39
  • Earlier I asked about removing the line in your xml file that says ``. Did you do that as well? I ask because that line actually throws an error on VS2013 when the program is run. – Michael Petch Sep 04 '14 at 03:40
  • I'm not sure what you mean. By "Missing File Mapping" he means this: http://windows.microsoft.com/en-us/windows/change-file-open-program#1TC=windows-7 – Dave Sexton Sep 04 '14 at 03:42
  • @MichaelPetch The entire config is wrong for AppSettings. I'm 100% sure of that. Dropping the "setting" XML into the `` element (as you mentioned) is also invalid. .NET throws an error because of an invalid config file. I think he's past the config problem anyway. – Dave Sexton Sep 04 '14 at 03:44
  • On my VS2013 my App.config reads ` ` . I then created that directory structure with his file in it. When program is run on my system Visual Studio launches and loads that `.c` file – Michael Petch Sep 04 '14 at 03:46
  • 1
    Yep, because you're using `appSettings`, just like I described in my answer. Note that it's not the same as `setting`, as you described to me in the comments of your answer and it's NOT what the OP posted. – Dave Sexton Sep 04 '14 at 03:47
  • Yes oops. I amended my Answer with the actual XML I used. I was unaware until you pointed it out that it was different from his. Now things seem to be making sense. My answer clearly shows exactly what was in my xml file. Thanks – Michael Petch Sep 04 '14 at 03:52
  • 1
    Yea, I was confused there for a bit too. I think at this point the OP needs to follow my advice and post a short but complete sample. Based on the most recent comment left on another answer, it seems that he's attempting to use `Start` to "read" a file, so there are bigger problems here... – Dave Sexton Sep 04 '14 at 03:53
0

Sounds like the specified file doesn't exist: D:\ab123\Source\ab123.c

Also, are you trying to store a key value pair? What about something like:

  <setting name="ab123" serializeAs="String">
    <value>D:\ab123\Source\ab123.c</value>
  </setting>
Rufus L
  • 36,127
  • 5
  • 30
  • 43
0

If you are referring to App.Config file of application then I think you have additionally specified add element in the settings:

Setting should look like this:

 <setting name="ab123" serializeAs="String">            
       <value>D:\\ab123\\Source\\ab123.c</value>
 </setting>

Or use Key/Value attributes:

<appSettings>
   <add key="ab123" value="D:\\ab123\\Source\\ab123.c"/>   
</appSettings>

Code:

var appSettings = ConfigurationManager.AppSettings;
string sPath = appSettings["ab123"];

//furthermore check for path validity
if(!string.IsNullOrEmpty(sPath) && System.IO.File.Exists(sPath))    
{ 
   //System.Diagnostics.Process.Start(sPath);
    string[] readText = System.IO.File.ReadAllLines(sPath); //to read the lines in string array     
}
Hassan
  • 5,360
  • 2
  • 22
  • 35
0

I am proposing another answer. I assume that this was an excerpt from your config file (and not the whole thing

<setting name="ab123" serializeAs="String">
    <add key="ab123" value="D:\ab123\Source\ab123.c"/>
</setting>

This is wrong, when I created my config file it looked like this but wasn not aware that was different from your example:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <appSettings>
        <add key="ab123a" value="D:\ab123\Source\ab123.c" />
    </appSettings>
</configuration>

I'm also going to assume that this returns a vale with your file name in it

string ab123 = ConfigurationManager.AppSettings["ab123"];

You have stated that the file D:\ab123\Source\ab123.c exists. So I will assume that is true.

An issue I can see her if all of that is true is that you are not specifying an executable or batch/cmd file to System.Diagnostics.Process.Start . your code would be equivalent to

ConfigurationManager.AppSettings("D:\\ab123\\Source\\ab123.c");

This is acceptable but Windows will see ab123.c is not an executable program. It then looks for .c file associations in the windows registry. The file association tells windows how to open such a file. If there is a file association it will launch the program specifying D:\ab123\Source\ab123.c as its argument (such a program would be Visual Stuido for example)

If there is a file association this call you have done should work if all the assumptions are correct above. If however there is nothing to associate .c with a program then Windows won't know how top open it and you will get an error similar to this:

An unhandled exception of type 'System.ComponentModel.Win32Exception' occurred in System.dll Additional information: The system cannot find the file specified

One way to check if there is a default program for an extension is to simply open a cmd.exe terminal shell and issue this command:

D:\ab123\Source\ab123.c

If that launches a program and loads your file up then the association exists and my answer won't apply. I am suggesting this as an answer in the event someone does a search and lands here. This may be helpful for someone else, but may not be the OP's actual problem.

Michael Petch
  • 46,082
  • 8
  • 107
  • 198