none
[WPF][VB] Ecriture d'un fichier dans le dossier du programme après déploiement par 'Visual Studio Installer' RRS feed

  • Question

  • Bonjour,

    J'espère que vous pourrez m'aider, car cela me rend fou ;-)

    J'ai 2 projets dans une même solution. Le premier est le programme 'principal', l'autre est un petit gestionnaire relatif au programme principal.

    Les 2 sont codés en VB sous WPF.

    Il se fait que les 2 programmes ont une routine pour écrire un petit fichier .ini, au même niveau que l'application. Le code utiliser pour "prendre" ce chemin est "AppDomain.CurrentDomain.BaseDirectory"

    Lors du débogage, l'un et l'autre programme écrivent et lisent sans soucis ces fichiers.ini (donc, à partir de leur dossier bin>debug respectifs

    J'utilise donc "Visual Studio Installer" pour créer le programme d'installation.

    Et c'est après cette installation que le problème arrive:
    ---------------------------------------------------------------------

    Alors que le programme 'principal' (que j'ai écrit en premier) peut utiliser la lecture/écriture des fichiers présents au niveau du programme...impossible (et crash) de le faire avec le 2eme, qui utilise pourtant les mêmes routines (et qui je le rappelle, fonctionne parfaitement dans son dossier 'debug'). Après vérification, je coche dans les onglets "Security" et "Signing" de mon 2eme projet, les cases "Sign the ClickOnce manifest" et "Enable ClickOnce Security settings"...et là ca fonctionne...mais les fichiers sont créé et lu depuis un dossier "VirtualStore" dans "AppData" (de mémoire)

     

    En résumé, ma question est donc: pourquoi mon premier projet peut-il lire et écrire au niveau de l'application, alors qu'avec mon second cela ne semble pouvoir se faire que dans ce dossier "VirtualStore"

    D'avance un grand merci!!

    mardi 24 janvier 2012 17:34

Réponses

  • J'ai suivi ton conseil. J'utilise maintenant 2 répertoire:

    - celui pour lire les données (qui peut très bien rester dans le dossier de l'application)
      Public Shared startupPath As String = AppDomain.CurrentDomain.BaseDirectory

     

    - celui pour écrire les données
      Public Shared writingPath As String = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) & "\nom de l'application\"

    Avec une procédure pour créer ce dossier si il est inexistant:
    If Not Directory.Exists(writingPath) Then Directory.CreateDirectory(writingPath) End If

    Cela m'a donc été utile, pour me conformer à ce qui est préconisé....mais figurez-vous que cela ne m'a pas aidé directement dans mon problème de départ...qui existait toujours malgré cela!!

    Je vais vous donner la raison, si cela peut en aider d'autres!!

    Le 'streamwriter' n'arrivait pas à écrire les données...car il était resté 'ouvert' par une autre procédure de lecture, elle!!! (pourtant je savais qu'il fallait toujours fermer le streamwriter après lecture/écriture !!)

    C'est donc ce que j'ai fait: je l'ai fermé par un close() et tout est rentré dans l'ordre!

    Merci pour tout, Gilles!

    • Modifié jmdeb mercredi 25 janvier 2012 10:09
    • Marqué comme réponse jmdeb mercredi 25 janvier 2012 13:41
    mardi 24 janvier 2012 23:40

Toutes les réponses

  • Bonjour,

    Afin que vous partiez sur de bonnes bases, que contient ce fichier ini ? Est-ce des paramètres utilisateurs ?

    Pouvez-vous nous indiquer l'exception qui est levée lorsque l'application tente d'écrire dans votre fichier ini ?

    Cordialement


    Gilles TOURREAU - MVP C#
    Architecte .NET/Consultant/Formateur chez Winwise
    Blog : http://gilles.tourreau.fr
    - MCPD : Enterprise Developper / Windows Developper 3.5 / ASP .NET 3.5
    - MCITP : SQL Server 2008 Developper
    - MCTS : ADO .NET 3.5 / SQL Server 2008 Developper / Windows Forms 3.5 / ASP .NET 3.5
    mardi 24 janvier 2012 22:13
    Modérateur
  • Voici le message que donne l'appli quand elle crash:

     

    Signature du problème :
      Nom d’événement de problème:    CLR20r3
      Signature du problème 01:    mgalaxy_runway.exe
      Signature du problème 02:    2.0.0.0
      Signature du problème 03:    4f1f31e4
      Signature du problème 04:    mscorlib
      Signature du problème 05:    4.0.0.0
      Signature du problème 06:    4e181ae3
      Signature du problème 07:    3fd1
      Signature du problème 08:    13c
      Signature du problème 09:    System.UnauthorizedAccess
      Version du système:    6.1.7601.2.1.0.256.1
      Identificateur de paramètres régionaux:    2060
      Information supplémentaire n° 1:    0a9e
      Information supplémentaire n° 2:    0a9e372d3b4ad19135b953a78882e789
      Information supplémentaire n° 3:    0a9e
      Information supplémentaire n° 4:    0a9e372d3b4ad19135b953a78882e789
    

     

    Pour vous aider, je peux rajouter ceci:
    ------------------------------------------------

    Concernant le 2eme projet, celui qui pose problème, j'ai fait d'autres test sur lui seul...et je me suis rendu compte que l'application se comportait normalement si elle était dans le dossier 'debug' ou sur le bureau lui même...mais plantait dès que je la faisait tourner depuis n'importe quel autre dossier de "Program Files (x86)". Ce serait apparement un problème d'autorisation?!

    Merci!!


    • Modifié jmdeb mardi 24 janvier 2012 22:44
    mardi 24 janvier 2012 22:43
  • Bonjour,

    Ce serait apparement un problème d'autorisation?!
    Oui, l'utilisateur de votre application n'a pas par mesure de sécurité à écrire dans le répertoire Program Files.

    Afin que vous partiez sur de bonnes bases, que contient ce fichier ini ? Est-ce des paramètres utilisateurs ?

    Cordialement


    Gilles TOURREAU - MVP C#
    Architecte .NET/Consultant/Formateur chez Winwise
    Blog : http://gilles.tourreau.fr
    - MCPD : Enterprise Developper / Windows Developper 3.5 / ASP .NET 3.5
    - MCITP : SQL Server 2008 Developper
    - MCTS : ADO .NET 3.5 / SQL Server 2008 Developper / Windows Forms 3.5 / ASP .NET 3.5
    mardi 24 janvier 2012 23:01
    Modérateur
  • Gilles,

    Merci pour votre réponse!
    Je vous ai en fait donné le message d'erreur de l'application lancée depuis son emplacement dans le dossier
    Voici le message d'erreur donné lorsque je prend l'option de déboguer à partir de ce message d'erreur.

    Là, j'ai:
    The process cannot access the file 'D:\_Works\mGalaxy\mGalaxy Runway\Keys Editor\mGalaxy_Runway v2.0\bin\Debug\mg_keys.ini' because it is being used by another process.

    Et si j'enleve les options ClicOnce dans "Security" et "Signing", j'ai alors :
    Access to the path 'C:\Program Files (x86)\mGalaxy v2.0\mg_keys.ini' is denied.

    Et voici le sub incriminé, la ligne reportée étant: writer As StreamWriter = New StreamWriter(startupPath & "mg_keys.ini")

    Sub writekeys()
            Dim str As String = ""
            Using writer As StreamWriter = New StreamWriter(startupPath & "mg_keys.ini")
                For Each kvp As KeyValuePair(Of String, keySet) In keyList
                    str = kvp.Value.item.Name & "=" & kvp.Value.code
                    writer.WriteLine(str)
                Next
            End Using
    End Sub

    Ce fichier .ini contient un mapping des codes clavier utilisable par l'autre application (la principale)..ET doit être accessible facilement par l'utilisateur (c-à-dire, dans le dossier propre de l'application). Je vous rappelle que l'autre application fait la même chose (avec d'autres données) où que l'on la déplace!

    Merci!

    • Modifié jmdeb mardi 24 janvier 2012 23:23
    mardi 24 janvier 2012 23:11
  • Bonjour,

    Si le fichier ini contient des paramètres utilisateurs, n'enregistrez pas ce fichier dans le répertoire où est installé l'application, mais dans le répertoire des données de l'utilisateur qui est destiné à cet effet. Pour cela utilisez la méthode GetFolderPath de la classe Environment (http://msdn.microsoft.com/fr-fr/library/14tx8hby.aspx) en utilisant la constante ApplicationData ou LocalApplicationData.

    Pour information, sachez que les applications qui essaye d'écrire dans le répertoire Windows, Program Files,...etc sont des applications non compatible Vista/Seven (et ultérieur) qui ne respectent pas les standard Microsoft depuis Windows 2000 !

    Cordialement


    Gilles TOURREAU - MVP C#
    Architecte .NET/Consultant/Formateur chez Winwise
    Blog : http://gilles.tourreau.fr
    - MCPD : Enterprise Developper / Windows Developper 3.5 / ASP .NET 3.5
    - MCITP : SQL Server 2008 Developper
    - MCTS : ADO .NET 3.5 / SQL Server 2008 Developper / Windows Forms 3.5 / ASP .NET 3.5
    mardi 24 janvier 2012 23:35
    Modérateur
  • J'ai suivi ton conseil. J'utilise maintenant 2 répertoire:

    - celui pour lire les données (qui peut très bien rester dans le dossier de l'application)
      Public Shared startupPath As String = AppDomain.CurrentDomain.BaseDirectory

     

    - celui pour écrire les données
      Public Shared writingPath As String = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) & "\nom de l'application\"

    Avec une procédure pour créer ce dossier si il est inexistant:
    If Not Directory.Exists(writingPath) Then Directory.CreateDirectory(writingPath) End If

    Cela m'a donc été utile, pour me conformer à ce qui est préconisé....mais figurez-vous que cela ne m'a pas aidé directement dans mon problème de départ...qui existait toujours malgré cela!!

    Je vais vous donner la raison, si cela peut en aider d'autres!!

    Le 'streamwriter' n'arrivait pas à écrire les données...car il était resté 'ouvert' par une autre procédure de lecture, elle!!! (pourtant je savais qu'il fallait toujours fermer le streamwriter après lecture/écriture !!)

    C'est donc ce que j'ai fait: je l'ai fermé par un close() et tout est rentré dans l'ordre!

    Merci pour tout, Gilles!

    • Modifié jmdeb mercredi 25 janvier 2012 10:09
    • Marqué comme réponse jmdeb mercredi 25 janvier 2012 13:41
    mardi 24 janvier 2012 23:40
  • Bonjour,

    C'est tout simplement un problème de droit. Regardez les droits au niveau de votre fichier INI.

    Cordialement


    Gilles TOURREAU - MVP C#
    Architecte .NET/Consultant/Formateur chez Winwise
    Blog : http://gilles.tourreau.fr
    - MCPD : Enterprise Developper / Windows Developper 3.5 / ASP .NET 3.5
    - MCITP : SQL Server 2008 Developper
    - MCTS : ADO .NET 3.5 / SQL Server 2008 Developper / Windows Forms 3.5 / ASP .NET 3.5
    mercredi 25 janvier 2012 10:03
    Modérateur
  • Bonjour,

    Pensez à utiliser la clause Using afin d'éviter ce genre de problème.

    Cordialement


    Gilles TOURREAU - MVP C#
    Architecte .NET/Consultant/Formateur chez Winwise
    Blog : http://gilles.tourreau.fr
    - MCPD : Enterprise Developper / Windows Developper 3.5 / ASP .NET 3.5
    - MCITP : SQL Server 2008 Developper
    - MCTS : ADO .NET 3.5 / SQL Server 2008 Developper / Windows Forms 3.5 / ASP .NET 3.5
    mercredi 25 janvier 2012 14:20
    Modérateur