none
MSI: "Error writing to file: ******.dll. Verify that you have access to that directory. GAC problem?

    Question

  • Hi,

    I have a "Setup Project" in Visual Studio 2005 that generates an .msi installation file. My setup project references several merge modules. When I try to run the generated installation I get the following error message:

    "Error writing to file: general.dll. Verify that you have access to that directory."

    I think that the problem is related to the fact that I have two separate copies of my general.dll in my setup project. My application uses one version of general.dll, but my application also uses an assembly called mi.dll, that uses another version of general.dll. So for my application to work both versions of general.dll is included in the installtion in the form of referenced merge modules. The merge modules have the "Module Retargetable Folder" set to "Global Assembly Cache Folder".

    The user that I'm using on my computer is part of my local Adminsitrators group. Eaven soo I've also tried to logon as Adminsitrator. So I don't really think that the problem is because of a file access problem. And when I check the file structure in C:\Windows\Assembly I notice a tmp folder that contains one version of my general.dll file:

    c:\WINDOWS\assembly\tmp\T38EJOTY\General.dll

    This file is somehow locked, I guess by the installation process, because it cannot be deleted. That's why I think that the installtion tries to write the second copy of generl.dll to the same temporary location.

    I really need help with this, and I'm prepared to open a support issue with Microsoft if I cannot find a workaround to my problem in this forum.

    I'm using the GAC just to be able to share my assemblies across different applications and to be able to have several versions installed beside eachother. I think that there must be some way that the installation procedure could handle this, as this is what is the meaning of the GAC?

    Explenation of my related assemblies:

    Application A references:
    * General.dll v1.1
    * MI.dll -> references General.dll v1.0

    Hence both versions of General.dll must be installed. Or should I rethink my whole reference strategy? If so, how?

    Best Regards,
    Lani

    Monday, June 19, 2006 12:49 PM

Answers

  • The isue appears to be that both files are going to the same temp location before being installed into the GAC. This is most likely because installing into the GAC is not just a simple install, it's a two-step process:

    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/installation_of_assemblies_to_the_global_assembly_cache.asp

    The other issue at the back of this that might be related is that Visual Studio is apparently building an invalid MSI file because internally it's generating two components with the same installer component guid, and that breaks the reference counting.  It's possible that the problem might go away if you started a brand new merge module project for the other version of the assembly. That *might* cause Visual Studio to use different internal component guids, and that might get around the duplicate location issue. 

    (I think Visual Studio uses the file name as a seed for component guids, that seems to be the underlying cause for the duplicate guids. )

     

    Monday, June 19, 2006 9:04 PM

All replies

  • I have now managed to reproduce this error in an isolated test solution.

    This is how I've done it:

    1. Create a new solution.
    2. Add a Class Library project.
    3. Add a strong key to the project.
    4. Build version 1.0.0.0 of the library.
    5. Copy the .dll to a new folder.
    6. Increase the library version to 2.0.0.0.
    7. Build version 2.0.0.0 of the library.
    8. Copy the .dll to a new folder.
    9. Add a Merge Module (v1) project and add the version 1.0.0.0 dll.
    10. Add a second Merge Module (v2) project and add the version 2.0.0.0 dll.
    11. Build the Merge Modules.
    12. Add a "Setup Project".
    13. Add the v1 and v2 merge modules to the setup project.
    14. Set the merge modules "Merge Module Retargetable Folder" property to "Global Assembly Cache Folder" for both merge modules.
    15. Build the setup project.
    16. Try to install the result by running the generated msi file.

    I have uploaded the test solution that I have made to my server:

    http://www.lani.nu/MSI_Error_Sample.zip

    Any thoughts on this would be appriciated. If I add the files directly to the setup project, skipping the merge modules, it seams to work. Both versions are then correctly installed into the GAC. But I would like to be able to keep the files in the merge modules, as they get compiled automaticly for my assembly projects, and they contain more than just the .dll files.

    Best Regards,
    Lani

    Monday, June 19, 2006 7:49 PM
  • The isue appears to be that both files are going to the same temp location before being installed into the GAC. This is most likely because installing into the GAC is not just a simple install, it's a two-step process:

    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/installation_of_assemblies_to_the_global_assembly_cache.asp

    The other issue at the back of this that might be related is that Visual Studio is apparently building an invalid MSI file because internally it's generating two components with the same installer component guid, and that breaks the reference counting.  It's possible that the problem might go away if you started a brand new merge module project for the other version of the assembly. That *might* cause Visual Studio to use different internal component guids, and that might get around the duplicate location issue. 

    (I think Visual Studio uses the file name as a seed for component guids, that seems to be the underlying cause for the duplicate guids. )

     

    Monday, June 19, 2006 9:04 PM
  • Thank you very much for your input regarding this matter. I would not have been able to find this out on my own, as I'm rather inexperienced with Windows Installer.

    I tried to change the GUID for the ComponentId in one of the merge modules with ORCA, and rebuild the sample MSI. The installation was then successful, and both versions of the assembly showed up in the GAC.

    But I have no solution as how to automate this process when I build my solutions. I have looked at the .vsproj file, but the GUID cannot be found there, it seams that it is generated at build time, as you suggested. Creating a new merge module always gives me the same GUID.

    I've been looking into some third party command line utilities for working with Windows Installer .msi and .msm files. But those that I have found are not very straight forward to use. I'm also looking in to the WiX project, maybe building my merge modules that way instead.

    Thank you once again for your help. If anyone knows of an easy workaround, then please let me know.

     

    Tuesday, June 20, 2006 11:04 AM
  • I had a similar problem.

    I have 2 assemblies A and B, B references A. I wanted to put both in the GAC through the MSI. Putting both assemblies in the GAC folder caused the same error as you had during installing the MSI - this was because it was trying to install assembly A twice, once for itself and once as a reference from assembly B.
    To get round this I only added assembly B to the GAC folder, and assembly A was automatically added to the GAC by the MSI.
    Tuesday, July 25, 2006 7:40 AM
  • I've had the same problem and found a slightly different solution, so just wanted to update this thread.

    During setup, it appears that files to be installed to the GAC are uncompressed into a random temp folder under the Assembly folder ("C:\WINDOWS\assembly\tmp\Z01Q3ST6\<assembly_name>.dll"). Obviously, if there are multiple files in the setup package with the same name it can't uncompress both to the same folder and it throws an error ("Error writing to file" "Verify that you have access to that directory").

    The problem occurs when a solution contains multiple projects where one or more projects contain references to each other. Each of the projects containing references to others ALSO include the output from the referenced projects in their project output.

    Example:
    Solution1
     - Library_A
     - Library_B - References Library_A
     - Setup - Includes Project Output for both A & B

    So, although the Setup already contains the Project Output for Library_A and Library_B projects, because Library_B contains a reference to Library_A, it's Project Output will ALSO add another instance of Library_A.dll to the Setup package.

    The solution is to edit the Project Output Properties for Library_B and add "Library_A.dll" to the "ExcludeFilter".

    Monday, December 22, 2008 10:03 PM