U4-2156 - Umbraco local package installer uses wrong path for files when umbraco is installed in a virtual directory

Created by Jeremy Branham 25 Apr 2013, 19:04:05 Updated by Jacob Alvarez 25 Aug 2016, 20:18:01

When Umbraco is installed in a virtual directory, the local package installer creates a subfolder in the installation directory and copies the package files there. I have reproduced this on version 4.9.0 and 4.11.7

Example - I create a package called "test" and add "test.dll" in the "Package Files" section of my new package. After publishing this package, I download and install the package to another Umbraco site. The new Umbraco site is in a virtual directory called "UmbracoSite". So the url would be http://localhost/UmbracoSite And lets assume the Umbraco files are at "C:\www\UmbracoSite"

The binary file [test.dll] that was in the package was copied to "C:\www\UmbracoSite\UmbracoSite\bin\test.dll" Instead of "C:\www\UmbracoSite\bin\test.dll"

Found root cause - In this method, the calls to IOHelper.FindFile() add the virtual directory name to the path. The mistake is that, file paths passed into this function don’t need the virtual directory name attached when they are being moved. [the application root IS the virtual directory] The file object contains an absolute path to the file, so adding the directory moves the files into a subdirectory with the same name as the virtual directory.

I havent done regression testing, but everything appears to be working ok.

Project: umbraco.cms Namespace: umbraco.cms.businesslogic.packager File: Installer.cs

    /// <summary>
    /// Gets the name of the file in the specified path.
    /// Corrects possible problems with slashes that would result from a simple concatenation.
    /// Can also be used to concatenate paths.
    /// </summary>
    /// <param name="path">The path.</param>
    /// <param name="fileName">Name of the file.</param>
    /// <returns>The name of the file in the specified path.</returns>
    private static String getFileName(String path, string fileName)

        // JDB - the calls to IOHelper.FindFile() add the virtual directory name to the path, but the filename is already absolute
        // virtual dir support
        //fileName = IOHelper.FindFile(fileName);

        if (path.Contains("[$"))
            //this is experimental and undocumented...
            path = path.Replace("[$UMBRACO]", IO.SystemDirectories.Umbraco);
            path = path.Replace("[$UMBRACOCLIENT]", IO.SystemDirectories.Umbraco_client);
            path = path.Replace("[$CONFIG]", IO.SystemDirectories.Config);
            path = path.Replace("[$DATA]", IO.SystemDirectories.Data);

        // JDB - the calls to IOHelper.FindFile() add the virtual directory name to the path, but the path is already absolute
        //to support virtual dirs we try to lookup the file... 
        //path = IOHelper.FindFile(path);

        Debug.Assert(path != null && path.Length >= 1);
        Debug.Assert(fileName != null && fileName.Length >= 1);

        path = path.Replace('/', '\\');
        fileName = fileName.Replace('/', '\\');

        // Does filename start with a slash? Does path end with one?
        bool fileNameStartsWithSlash = (fileName[0] == Path.DirectorySeparatorChar);
        bool pathEndsWithSlash = (path[path.Length - 1] == Path.DirectorySeparatorChar);

        // Path ends with a slash
        if (pathEndsWithSlash)
            if (!fileNameStartsWithSlash)
                // No double slash, just concatenate
                return path + fileName;
                // Double slash, exclude that of the file
                return path + fileName.Substring(1);
            if (fileNameStartsWithSlash)
                // Required slash specified, just concatenate
                return path + fileName;
                // Required slash missing, add it
                return path + Path.DirectorySeparatorChar + fileName;

2 Attachments

Download Installer.cs

Download cms.zip


Jeremy Branham 01 May 2013, 16:30:34

I attached the modified source file. Also attached a dll that can be dropped in as a patch, if someone wants the fix, but doesnt want to build the project.

Jacob Alvarez 25 Aug 2016, 20:12:00

I can verify that this is still an issue in v7.4.3. How can we get somebody to respond to this?

Priority: Normal

Type: Bug

State: Submitted


Difficulty: Normal

Category: Packages

Backwards Compatible: True

Fix Submitted:

Affected versions: 4.9.0, 4.11.7, 7.4.3

Due in version:


Story Points: