none
Error al guardar un valor en el fichero de configuración (app.config) RRS feed

  • Pregunta

  • Hola a todos,

    Estoy actualizando un proyecto que tenía de VS2005 (con .NET 2.0) a VS2013 (con .NET 4.5). Tenía un setup project en mi solución, pero parece que desde hace un tiempo ya no está soportado y por eso he tenido que crear un nuevo proyecto de InstallShield. El viejo instalador iba bien y no tenía problemas, pero con el nuevo parece que tengo un problema. No sé concretamente si el problema es del instalador o de .NET 4.5. El programa se instala en la carpeta C:\Program Files (x86)\NombreCompañía\NombreAplicación. Hago uso del fichero .config para leer y escribir algunos parámetros. Al leer los parámetros todo va bien, pero a la hora de guardar es cuando tengo el problema. Cuando usaba el viejo instalador (setup project y .NET 2.0), en el momento de guardar algún valor se creaba un archivo .config en la carpeta C:\Users\me\AppData\Local\VirtualStore\Program Files (x86)\NombreCompañía\NombreAplicación (¿esto es isolated storage?).

    Estos son todos los cambios que he realizado en mi solución:

    • Cuando abrí la solución con VS2013 el proceso de migración fue bien (con algunos warnings y mensajes), salvo el setup project (claro).
    • Actualicé todos los proyectos a .NET 4.5 (Project properties -> Application -> Target framework).
    • Instalé InstallShield Limited Edition y creé y configuré un proyecto de instalación.

    Creo que estos son todos los cambios que hice. Este es el código donde salta la excepción:

    public void SetXParamValue(string value)
    {
        try
        {
            Configuration conf = ConfigurationManager.OpenExeConfiguration(Application.ExecutablePath);
            conf.AppSettings.Settings["XParam"].Value = value;
            conf.Save();
        }
        catch (Exception e)
        {
            MessageBox.Show("Error setting X param.");
        }
    }


    Y esta es la excepción:

    Exception messsage:
    An error occurred loading a configuration file: Access to the path 'C:\Program Files (x86)\CompanyName\AppName\oy25i1se.tmp' is denied. (C:\Program Files (x86)\CompanyName\AppName\ExeFile 1.0.192b.exe.config)

    Stack trace:
    at System.Configuration.MgmtConfigurationRecord.SaveAs(String filename, ConfigurationSaveMode saveMode, Boolean forceUpdateAll)
    at System.Configuration.Configuration.SaveAsImpl(String filename, ConfigurationSaveMode saveMode, Boolean forceSaveAll)
    at System.Configuration.Configuration.Save()
    at VisualizadorCabecera.FormPrincipal.EstablecerIdioma(CultureInfo idioma)

    Inner exception messsage:
    Access to the path 'C:\Program Files (x86)\CompanyName\AppName\oy25i1se.tmp' is denied.

    Stack trace:
    at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
    at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
    at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access)
    at System.CodeDom.Compiler.TempFileCollection.EnsureTempNameCreated()
    at System.CodeDom.Compiler.TempFileCollection.AddExtension(String fileExtension, Boolean keepFile)
    at System.CodeDom.Compiler.TempFileCollection.AddExtension(String fileExtension)
    at System.Configuration.Internal.WriteFileContext..ctor(String filename, String templateFilename)
    at System.Configuration.Internal.InternalConfigHost.StaticOpenStreamForWrite(String streamName, String templateStreamName, Object& writeContext, Boolean assertPermissions)
    at System.Configuration.Internal.InternalConfigHost.System.Configuration.Internal.IInternalConfigHost.OpenStreamForWrite(String streamName, String templateStreamName, Object& writeContext, Boolean assertPermissions)
    at System.Configuration.Internal.InternalConfigHost.System.Configuration.Internal.IInternalConfigHost.OpenStreamForWrite(String streamName, String templateStreamName, Object& writeContext)
    at System.Configuration.ClientConfigurationHost.OpenStreamForWrite(String streamName, String templateStreamName, Object& writeContext)
    at System.Configuration.UpdateConfigHost.OpenStreamForWrite(String streamName, String templateStreamName, Object& writeContext)
    at System.Configuration.MgmtConfigurationRecord.SaveAs(String filename, ConfigurationSaveMode saveMode, Boolean forceUpdateAll)

    ¿Sabéis cuál puede ser el problema? ¿Puede ser del framework o es del instalador? ¿Tenéis alguna sugerencia?

    Gracias de antemano,

    Jon.

    viernes, 9 de enero de 2015 10:26

Respuestas

  • Pues no, el problema no es del Framework ni del instalador. Es problema de la versión de Windows. Seguramente el programa que tenías hecho con la versión 2.0 lo probabas bajo Windows XP, y ahora que te has pasado a una versión más moderna del Visual Studio lo has instalado en un Windows más moderno.

    En XP, si el programa lo ejecutaba un usuario que era administrador de Windows, entonces podía escribir en las carpetas que "cuelgan" por debajo de "c:\program files". Pero desde Windows Vista en adelante, se introdujo el UAC (user access control), que hace que incluso aunque seas administrador de la máquina, no puedas escribir bajo "c:\program files" sin antes hacer una elevación de privilegios. Esto se hace para que no se modifiquen los programas instalados de forma inadvertida o maliciosa.

    La conclusión es que, en un Windows moderno, los programas no deben modificar nada en la carpeta donde se instaló el programa. Esto incluye el .config, que no debe ser modificado desde dentro del propio programa (aunque podrías hacerlo si realmente te empeñas, haciendo clic-derecho sobre el programa en el Explorador de Windows y seleccionando la opción de "ejecutar como administrador").

    Como alternativa, utiliza los "Settings" en lugar del .config. Éstos se graban en la carpeta de documentos del usuario, que sí que es de lectura/escritura.

    • Propuesto como respuesta Jesús López viernes, 9 de enero de 2015 10:58
    • Marcado como respuesta Jon 123 viernes, 9 de enero de 2015 12:16
    viernes, 9 de enero de 2015 10:40

Todas las respuestas

  • Pues no, el problema no es del Framework ni del instalador. Es problema de la versión de Windows. Seguramente el programa que tenías hecho con la versión 2.0 lo probabas bajo Windows XP, y ahora que te has pasado a una versión más moderna del Visual Studio lo has instalado en un Windows más moderno.

    En XP, si el programa lo ejecutaba un usuario que era administrador de Windows, entonces podía escribir en las carpetas que "cuelgan" por debajo de "c:\program files". Pero desde Windows Vista en adelante, se introdujo el UAC (user access control), que hace que incluso aunque seas administrador de la máquina, no puedas escribir bajo "c:\program files" sin antes hacer una elevación de privilegios. Esto se hace para que no se modifiquen los programas instalados de forma inadvertida o maliciosa.

    La conclusión es que, en un Windows moderno, los programas no deben modificar nada en la carpeta donde se instaló el programa. Esto incluye el .config, que no debe ser modificado desde dentro del propio programa (aunque podrías hacerlo si realmente te empeñas, haciendo clic-derecho sobre el programa en el Explorador de Windows y seleccionando la opción de "ejecutar como administrador").

    Como alternativa, utiliza los "Settings" en lugar del .config. Éstos se graban en la carpeta de documentos del usuario, que sí que es de lectura/escritura.

    • Propuesto como respuesta Jesús López viernes, 9 de enero de 2015 10:58
    • Marcado como respuesta Jon 123 viernes, 9 de enero de 2015 12:16
    viernes, 9 de enero de 2015 10:40
  • La verdad es que con la vieja versión lo tenía testeado en Windows XP, 7 y 8, pero seguramente por ahí irán los tiros. De todas formas, ya he probado la alternativa que me has dado y funciona perfecto. Por curiosidad, ¿me podrías decir en qué carpeta se guarda el fichero de settings?

    ¡Gracias por todo Alberto!

    viernes, 9 de enero de 2015 12:14
  •  ¿me podrías decir en qué carpeta se guarda el fichero de settings?

    %USERPROFILE%\Local Settings\Application Data\<Company Name>\<appdomainname>_<eid>_<hash>\<version>\user.config

    viernes, 9 de enero de 2015 12:28