2012-04-22 4 views
2

私は、Windowsサービス内からインタラクティブなユーザーとしてプロセスを開始するthis CodeProject pageからProcessStarter C#クラスを使用してきました。P/CreateEnvironmentBlockは30秒まで取りにコールを呼び出しますか?

CreateEnvironmentBlockRunメソッド)へのP/Invoke呼び出しが返されるまでに30秒かかることがあります(Win7とXPの両方を実行する〜50台の異なるコンピュータでコードをテストした後で、速い、他の回ではない)。

私は(私のためにそれは常に動作します)someone else had this problem, but they were getting an errorことがわかりました。

はなぜCreateEnvironmentBlockへの呼び出しはそう長く取ることができますか?


P /呼び出し宣言:

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

EDIT:追加情報:

  • それは常に 30秒ではありません - それは30秒に数秒の間(異なるコンピュータ間で)変化します。

  • procmonレジストリの全体の束がHKLM\System\CurrentControlSet\Control\Session Manager\EnvironmentHKCU\Volatile Environmentが、ないネットワーク活動ようなキーに読み出す示します。

  • ドメインワークステーション上のドメインコントローラへのアクセスは、コールの長さに違いはありませんように見えます。

  • perfmonなしCPUの使用率にはほとんど、とだけ最初と最後のI/Oスパイクを示しています

    perfmon graph

    この例ではCreateEnvironmentBlock通話が約12秒かかりました。など

    ユーザー固有の環境変数:ない負荷、ユーザのプロファイル(およびそのプロファイルがロードされなければならないので、ユーザは既に、とにかくログインしている)を行うCreateEnvironmentBlockへの呼び出し

  • The MSDN documentation推論%USERPROFILEのの%は、ユーザーのプロファイルをロードした場合のみに設定されています。ユーザーのプロファイルを読み込むには、LoadUserProfile関数を呼び出します。

+1

30秒でネットワークのタイムアウトのように大変聞こえます。 procmon(http://technet.microsoft.com/en-us/sysinternals/bb896645)を使用して、待機期間の開始時に何が起こっているのか確認できますか? – Gabe

+0

@Gabe:procmonは、 'HKLM \ System \ CurrentControlSet \ Control \ Session Manager \ Environment'、' HKCU \ Volatile Environment'などにレジストリを読み込んで環境変数を取得しますが、ネットワークアクティビティは一切ありません。ドメインコントローラにネットワークアクセスすることなく、ドメインアカウントを持つドメインコンピュータにログインしていることをテストしました。 – Xenon

+0

また、必ずしも30秒であるとは限りません。それは5秒から30秒の間であればどこでもかまいませんが、それは純粋にレジストリの読み込みに起因する場合(一部のコンピュータ/ユーザは他のものよりも多くの環境変数を持っているので)意味がありますが、 – Xenon

答えて

0

別のユーザーのための環境ブロックを作成すると、そのユーザーのプロファイルをロードする必要があるため。ドメイン制御マシンを使用している場合は、ネットワーク上のActive Directoryマシンと通信してそのプロファイルをダウンロードする必要があるため、これは2倍遅くなります。

+0

いいえ、この回答は正しくありません。 'CreateEnvironmentBlock'は既にログインしているユーザの環境変数を取得します。そのユーザのプロファイルはすでに読み込まれています。これが、ユーザートークンが 'CreateEnvironmentBlock'に渡される理由です。 – Xenon

+0

@Xenon:ログオントークンの存在は、ユーザーのプロファイルが既に読み込まれていることを意味するものではありません。 'LoadUserProfile'はトークンをパラメータとして受け付けます。 –

+0

@BenVoigt:ああ、確かに。ただし、CreateEnvironmentBlockのMSDNドキュメントでは、ユーザープロファイルを読み込まないことが推測されます。 'CreateEnvironmentBlock'を呼び出すと、インタラクティブセッションにログインしたユーザのトークンを渡しているので、そのプロファイルは既に読み込まれていますか? – Xenon

関連する問題