以编程方式确定代码是否在IIS Express下运行
本文关键字:IIS Express 运行 是否 编程 方式确 代码 | 更新日期: 2023-09-27 18:26:24
我甚至不确定这是否可能,但我希望能找到一条线索来确定当前正在执行的代码是否在IIS Express下运行。到目前为止,我最好的近似值,非常粗糙,肯定会在某个时候失败/崩溃:
bool IsExpress =
Request.ServerVariables["SERVER_SOFTWARE"] == "Microsoft-IIS/7.5"
&& Int32.Parse(Request.ServerVariables["INSTANCE_ID"]) > 1000000000;
当然,必须有更好的方法。我对Application、Server和Request对象的检查似乎没有发现任何可以提供更好见解的东西。也许我只需要看看其他物体?
更新:
我真的很好奇是否有办法检测到这一点——在这一点上,这真的很学术——我没有迫切需要使用它。最初的问题仍然存在。但本着回应评论的精神,特别是我有兴趣回答本网站上另一个问题/答案的批评:如何搜索服务器的MIME映射。批评的是,发布的答案不适用于IIS Express,只适用于传统的IIS实例。IIS Express将MIME配置存储在applicationhost.config XML文件中,我希望更新该答案,以便为IIS Express提供返回该信息的方法。我当然可以添加一些代码,从XML中获取适当的值(对LINQ到XML来说是Yay!),但我真的想让它更智能。需要明确的是,我不需要解析该文件的帮助,只需要在尝试检测代码当前是否在IIS Express引擎中执行时更优雅一些。
更新2:
IIS 8.0快速测试版于本周发布,它进一步表明了我问题中的方法是脆弱的,而且会崩溃。虽然针对特定版本不会破坏交易,但最好考虑到这一点,并尽量确保代码至少能与目前已知的版本一起使用。
检查当前进程名称会成功吗?
bool isExpress =
String.Compare(Process.GetCurrentProcess().ProcessName,"iisexpress") == 0;
正常IIS在内存w3wp.exe
下运行。
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;
}
如果您不介意使用COM级API,您可以使用IIS版本管理器API
http://msdn.microsoft.com/en-us/library/gg418429.aspx
在这篇SO文章中,有一些关于如何使用这一点的讨论:以编程方式启动和停止IIS Express——这并不完全是您想要的,但他们确实讨论了使用API。
编辑:我应该补充一点,我自己还没有尝试过,但看起来很有希望,祝你好运!
我们可以不试着看看IIS Express的一个或多个限制是否有效吗?如果有效,那就不是IIS Express。示例IIS Express不支持共享点服务