P / Invoke调用CreateEnvironmentBlock最多需要30秒?

时间:2012-04-22 23:52:57

标签: c# performance winapi pinvoke

我一直在使用this CodeProject page中的ProcessStarter C#类从Windows服务中作为交互式用户启动进程。

我注意到(在大约50台不同的计算机上测试代码,同时运行Win7和XP),P / Invoke调用CreateEnvironmentBlock(在Run方法中)可以占用返回30秒(有时候很快,其他时候没有)。

我看到someone else had this problem, but they were getting an error(对我而言,它始终有效)。

为什么拨打CreateEnvironmentBlock这么长时间?


P / Invoke声明:

[DllImport("userenv.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern bool CreateEnvironmentBlock(out IntPtr lpEnvironment, IntPtr hToken, bool bInherit);


CreateEnvironmentBlock致电:

IntPtr lpEnvironment = IntPtr.Zero;
bool resultEnv = CreateEnvironmentBlock(out lpEnvironment, primaryToken, false);

编辑:补充信息:

  • 总是 30秒 - 它在几秒到30秒之间变化(在不同的计算机上)。

  • procmon显示了对HKLM\System\CurrentControlSet\Control\Session Manager\EnvironmentHKCU\Volatile Environment等密钥的一大堆注册表读取,但 没有网络活动

  • 对域工作站上的域控制器的访问似乎对调用的长度没有影响。

  • perfmon显示几乎没有CPU使用率,只显示初始和结束I / O峰值:

    perfmon graph

    此示例中的CreateEnvironmentBlock调用大约需要12秒。

  • The MSDN documentation推断对CreateEnvironmentBlock的调用不加载用户的个人资料(并且用户已经登录,因此必须加载他们的个人资料) :

      

    仅在加载用户的配置文件时设置用户特定的环境变量,例如%USERPROFILE%。要加载用户的配置文件,请调用LoadUserProfile函数。

1 个答案:

答案 0 :(得分:0)

因为为其他用户创建环境块需要加载该用户的配置文件。如果您使用域控制的计算机,这将会加倍,因为它需要与网络上的Active Directory计算机进行通信并从中下载配置文件。