How to determine the \Temporary ASP.NET Files\root\{site hash} with PowerShell?

ε祈祈猫儿з 提交于 2019-12-05 00:30:42

问题


ASP.NET makes use of a temporary files directory to store files for Shadow Copying and Dynamic Compilation. A typical path will look like this. Note the hash on the end of the path.

C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\root\{hash}

I'm using automated deployments and have noticed that these folders and their contents are not automatically removed. I'd like to automate the process of removing unused temp files as part of my deployment process. Such that as soon as the new version of my site is deployed the old temp files are removed.

The hash seems to be generated in a deterministic manner so I'm hoping I'll be able to determine the hash as part of my pre-deployment script and delete it post-deployment.

How is the hash calculated for an ASP.NET website?

References:

  1. How .Net names its temp folder inside C:\Windows\Microsoft.NET\Framework\v{version}\Temporary ASP.NET Files\root
  2. http://blogs.msdn.com/b/junfeng/archive/2004/02/09/69919.aspx
  3. http://dotnetinside.com/en/type/System.Web/ApplicationManager/4.0.0.0

回答1:


Well, a few moments with Reflector, searching all members within System.Web for the word "Temporary" shows this call gets me here:

string str2 = AppManagerAppDomainFactory.ConstructSimpleAppName(AppDomainAppVirtualPath);

But then I remember that the source code is available for all of .NET, so I move to the actual code, rather than the reflectored code: https://referencesource.microsoft.com/#System.Web/HttpRuntime.cs,870

Later in that method "SetupCodeGenDirectory" the path appears to be built on top of with

 this._codegenDir = Thread.GetDomain().DynamicDirectory;

So, looks like that hash is from DynamicDirectory. That's over here at http://referencesource.microsoft.com/#mscorlib/system/appdomain.cs#2792 which looks like an extern that is inside some COM Fusion Loader stuff:

[ComImport,InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("7c23ff90-33af-11d3-95da-00a024a85b51")]

But that GUID leads me here http://referencesource.microsoft.com/#mscorlib/microsoft/win32/fusionwrap.cs#94

which implies it's a public key token part:

     public const uint HASH_VALUE            = PUBLIC_KEY_TOKEN + 1;
     public const uint NAME                  = HASH_VALUE + 1;

That perhaps it's NAME? I'm guessing it's yourAssembly.GetPublicKeyToken();

OR, just change the folder that your temporary ASP.NET files go to in config section http://msdn.microsoft.com/en-us/library/system.web.configuration.compilationsection.tempdirectory%28VS.80%29.aspx in system.web in web.config

<compilation tempDirectory="D:\MoveThemHere">



回答2:


I know this is an old question, but in case someone still need it, this is the C# code that makes the trick. I guess it's not that hard to port to powershell.

        string siteId = "/LM/W3SVC/3/ROOT"; // This can be composed by getting the site ID using the ServerManager (Microsoft.Web.Administration)
        string physicalPath = "E:\\home\\mysite\\web\\";

        string v_app_name = HashCode.GetString32((siteId + physicalPath).ToLower(CultureInfo.InvariantCulture)).ToString("x", CultureInfo.InvariantCulture);

        string dir_name_32_bits_app = HashCode.GetString32(v_app_name).ToString("x8");
        string dir_name_64_bits_app = HashCode.GetString64(v_app_name).ToString("x8");

        Console.WriteLine("32 bits: " + dir_name_32_bits_app);
        Console.WriteLine("64 bits: " + dir_name_64_bits_app);

The HashCode class:

public class HashCode
{        
    public static unsafe int GetString32(string s)
    {
        fixed (char* str = s)
        {
            char* chPtr = str;
            int num = 0x15051505;
            int num2 = num;
            int* numPtr = (int*)chPtr;
            for (int i = s.Length; i > 0; i -= 4)
            {
                num = (((num << 5) + num) + (num >> 0x1b)) ^ numPtr[0];
                if (i <= 2)
                {
                    break;
                }
                num2 = (((num2 << 5) + num2) + (num2 >> 0x1b)) ^ numPtr[1];
                numPtr += 2;
            }
            return (num + (num2 * 0x5d588b65));
        }
    }


    public static unsafe int GetString64(string s)
    {
        fixed (char* str = s)
        {
            int num3;
            char* chPtr = str;
            int num = 0x1505;
            int num2 = num;
            for (char* chPtr2 = chPtr; (num3 = chPtr2[0]) != '\0'; chPtr2 += 2)
            {
                num = ((num << 5) + num) ^ num3;
                num3 = chPtr2[1];
                if (num3 == 0)
                {
                    break;
                }
                num2 = ((num2 << 5) + num2) ^ num3;
            }
            return (num + (num2 * 0x5d588b65));
        }
    }
}


来源:https://stackoverflow.com/questions/24523915/how-to-determine-the-temporary-asp-net-files-root-site-hash-with-powershell

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!