以编程方式确定代码是否在IIS Express下运行

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了以编程方式确定代码是否在IIS Express下运行相关的知识,希望对你有一定的参考价值。

我不确定这是否可能,但我希望找到一条线索,以确定当前正在执行的代码是否在IIS Express下运行。到目前为止,我的最佳近似值,令人难以置信的hackish,肯定会在某些时候失败/突破:

bool IsExpress = 
  Request.ServerVariables["SERVER_SOFTWARE"] == "Microsoft-IIS/7.5"
  && Int32.Parse(Request.ServerVariables["INSTANCE_ID"]) > 1000000000;

当然必须有更好的方法。我对Application,Server和Request对象的检查似乎没有揭示可能提供更好洞察力的任何内容。也许我只需要看一些其他对象?

更新:

如果有一种方法可以检测到这一点,我真的很好奇 - 在这一点上它真的是学术性的,我没有迫切需要使用它。最初的问题就是。但本着回应评论的精神,特别是我有兴趣回答本网站上另一个问题/答案的批评:How to search the server's MIME map。批评是,发布的答案不适用于IIS Express,只适用于传统的IIS实例。 IIS Express将MIME配置存储在applicationhost.config XML文件中,我想更新该答案,以便为IIS Express提供返回该信息的方法。我当然可以添加一些从XML中获取适当值的代码(Yay for LINQ to XML!)但我真的想让它变得更聪明。为了清楚起见,我不需要帮助解析该文件 - 只是尝试检测代码当前是否在IIS Express引擎中执行时更优雅。

更新2:

IIS 8.0 Express Beta是released this week,它进一步表明我的问题中的方法很脆弱并且会破坏。虽然它不是针对特定版本的交易破坏者,但考虑到这一点并尝试确保代码至少与今天的已知版本一起使用将会很好。

答案

检查当前进程名称会起作用吗?

bool isExpress = 
  String.Compare(Process.GetCurrentProcess().ProcessName,"iisexpress") == 0;

正常的IIS在w3wp.exe下从内存运行。

另一答案

如果您不介意放入COM级API,则可以使用IIS Version Manager API

http://msdn.microsoft.com/en-us/library/gg418429.aspx

关于如何在这个SO帖子中使用它有一些讨论:Starting and stopping IIS Express programmatically - 不完全是你想要的,但他们确实讨论了使用API​​。

编辑:我应该补充一点,我自己没试过,但看起来很有希望,祝你好运!

另一答案

我们可以不尝试看看是否有一个或多个limitation of IIS Express工作,如果它工作,它不是IIS Express。示例IIS Express不支持sharepoint服务

另一答案

Oran Dennison的回答对我来说不再适用于dotnet核心。

我通过首先创建一个可以获取父进程的方法来扩展它:

/// <summary>
/// A utility class to determine a process parent.
/// </summary>
/// <remarks>
/// From https://stackoverflow.com/a/3346055/240845
/// </remarks>
public static class ParentProcessUtilities
{
    /// <summary>
    /// Gets the parent process.
    /// </summary>
    /// <param name="process">The process to get the parent of</param>
    /// <returns>The parent process.</returns>
    public static Process Parent(this Process process)
    {
        return GetParentProcess(process.Handle);
    }

    /// <summary>
    /// Gets the parent process of the current process.
    /// </summary>
    /// <returns>An instance of the Process class.</returns>
    public static Process GetParentProcess()
    {
        return Process.GetCurrentProcess().Parent();
    }

    /// <summary>
    /// Gets the parent process of a specified process.
    /// </summary>
    /// <param name="handle">The process handle.</param>
    /// <returns>The parent process.</returns>
    public static Process GetParentProcess(IntPtr handle)
    {
        ProcessInformation pbi = new ProcessInformation();

        // Note, according to Microsoft, this usage of NtQueryInformationProcess is 
        // unsupported and may change
        int status = NtQueryInformationProcess(
            handle, 0, ref pbi, Marshal.SizeOf(pbi), out _);
        if (status != 0)
        {
            throw new Win32Exception(status);
        }

        try
        {
            return Process.GetProcessById(pbi.InheritedFromUniqueProcessId.ToInt32());
        }
        catch (ArgumentException)
        {
            // not found
            return null;
        }
    }

    [DllImport("ntdll.dll")]
    private static extern int NtQueryInformationProcess(
        IntPtr processHandle, int processInformationClass,
        ref ProcessInformation processInformation, int processInformationLength, 
        out int returnLength);

    /// <summary>
    /// Used in the NtQueryInformationProcess call.
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    public struct ProcessInformation
    {
        // These members must match PROCESS_BASIC_INFORMATION
        internal IntPtr Reserved1;
        internal IntPtr PebBaseAddress;
        internal IntPtr Reserved2_0;
        internal IntPtr Reserved2_1;
        internal IntPtr UniqueProcessId;
        internal IntPtr InheritedFromUniqueProcessId;

    }
}

然后,您可以执行以下操作:

public bool IsUnderIisExpress()
{
    var currentProcess = Process.GetCurrentProcess();
    if (string.CompareOrdinal(currentProcess.ProcessName, "iisexpress") == 0)
    {
       return true;
    }

    var parentProcess = currentProcess.Parent();
    if (string.CompareOrdinal(parentProcess.ProcessName, "iisexpress") == 0
        || string.CompareOrdinal(parentProcess.ProcessName, "VSIISExeLauncher") == 0)
    {
        return true;
    }

    return false;
}

以上是关于以编程方式确定代码是否在IIS Express下运行的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式启动和停止 IIS Express

以编程方式将 IIS 应用程序池标识“用户”分配给组

如何配置 ASP.NET Core 1.0 以使用本地 IIS 而不是 IIS Express?

asp.net 成员资格 - 如何以编程方式确定用户是不是在角色中

以编程方式将证书导入 IIS?

如何以编程方式确定字体是不是为 CFF?