【问题标题】:How to determine the \Temporary ASP.NET Files\root\{site hash} with PowerShell?如何使用 PowerShell 确定 \Temporary ASP.NET Files\root\{site hash}?
【发布时间】:2014-07-02 06:02:15
【问题描述】:

ASP.NET 使用临时文件目录来存储用于影子复制和动态编译的文件。典型的路径将如下所示。注意路径末尾的哈希。

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

我正在使用自动部署,并注意到这些文件夹及其内容不会自动删除。作为部署过程的一部分,我想自动化删除未使用的临时文件的过程。这样,一旦部署了我的站点的新版本,旧的临时文件就会被删除。

哈希似乎是以一种确定性的方式生成的,所以我希望我能够将哈希确定为我的部署前脚本的一部分,并在部署后将其删除。

如何为 ASP.NET 网站计算哈希?

参考资料:

  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

【问题讨论】:

    标签: asp.net appdomainsetup temporary-asp.net-files


    【解决方案1】:

    好吧,用 Reflector 稍等片刻,在 System.Web 中的所有成员中搜索“临时”一词表明这个调用让我来到这里:

    string str2 = AppManagerAppDomainFactory.ConstructSimpleAppName(AppDomainAppVirtualPath);
    

    但后来我记得源代码可用于所有 .NET,所以我转向实际代码,而不是反射代码:https://referencesource.microsoft.com/#System.Web/HttpRuntime.cs,870

    稍后在该方法“SetupCodeGenDirectory”中,路径似乎建立在 with 之上

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

    所以,看起来该哈希来自 DynamicDirectory。就在http://referencesource.microsoft.com/#mscorlib/system/appdomain.cs#2792,它看起来像是在一些 COM Fusion Loader 东西中的外部:

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

    但是那个 GUID 把我带到这里 http://referencesource.microsoft.com/#mscorlib/microsoft/win32/fusionwrap.cs#94

    这意味着它是一个公钥令牌部分:

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

    那也许是 NAME?我猜是yourAssembly.GetPublicKeyToken();

    或者,只需在 web.config 的 system.web 中的配置部分 http://msdn.microsoft.com/en-us/library/system.web.configuration.compilationsection.tempdirectory%28VS.80%29.aspx 中更改临时 ASP.NET 文件所在的文件夹

    <compilation tempDirectory="D:\MoveThemHere">
    

    【讨论】:

    • 感谢您的回复。我认为除了公钥令牌部分之外一切都是正确的。看起来我无法确定 CodegenDir 将来自网站的 AppDomain/Process 之外的内容。我认为我最好的选择是配置tempDirectory
    • 我有 300 个使用相同代码的 Web 应用程序,有点恼人的是,在不同的服务器上生成的文件夹是不同的,这让我很难使用 warm 来“预热”所有实例从一个实例中提取文件。
    【解决方案2】:

    我知道这是一个老问题,但如果有人仍然需要它,这就是 C# 代码的诀窍。我想移植到 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);
    

    HashCode 类:

    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));
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多