バッチファイルを呼び出すサービスがあります。バッチファイルの実行には5〜10秒かかります。
_System.Diagnostics.Process proc = new System.Diagnostics.Process(); // Declare New Process
proc.StartInfo.FileName = fileName;
proc.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
proc.StartInfo.CreateNoWindow = true;
proc.Start();
proc.WaitForExit();
_
ファイルが存在し、コンソールで同じコードを実行するとコードが機能します。ただし、サービス内で実行すると、WaitForExit()
でハングアップします。続行するには、プロセスからバッチファイルを強制終了する必要があります。 (プロセスリストで確認できるので、ファイルが存在することを確認しています。)
このハングアップを修正するにはどうすればよいですか?
Kevinのコードにより、出力を取得できます。バッチファイルの1つがまだハングしています。
"C:\ EnterpriseDB\Postgres\8.3\bin\pg_dump.exe" -i -h localhost -p 5432 -U postgres -F p -a -D -v -f "c:\ backupcasecocher\backupdateevent2008.sql" -t "\" public\"。\" dateevent\"" "DbTest"
他のバッチファイルは次のとおりです。
"C:\ EnterpriseDB\Postgres\8.3\bin\vacuumdb.exe" -U postgres -d DbTest
パスを確認しましたが、postgresql
パスは問題ありません。出力ディレクトリは存在しますが、サービスの外部で機能します。何か案は?
バッチファイルのパスの代わりに、_proc.StartInfo.FileName
_の「C:\ EnterpriseDB\Postgres\8.3\bin\pg_dump.exe」を書き込み、すべてのパラメーターを_proc.StartInfo.Arguments
_に追加しました。結果は変わりませんが、プロセスウィンドウに_pg_dump.exe
_が表示されます。繰り返しますが、これはサービス内でのみ発生します。
管理者グループのユーザーでサービスを実行しましたが、役に立ちません。サービスのユーザー名とパスワード用にnull
を復元しました
イベントログにトレースを書き込み、その中に「dir」を含むバッチファイルを実行する単純なサービスを作成しました。 proc.Start();
でハングするようになりました-アカウントをLocalSystemからserに変更しようとしましたが、管理者のユーザーとパスワードを設定しましたが、まだ何もしていません。
これが私がバッチファイルを実行するために使用するものです:
proc.StartInfo.FileName = target;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.UseShellExecute = false;
proc.Start();
proc.WaitForExit
(
(timeout <= 0)
? int.MaxValue : timeout * NO_MILLISECONDS_IN_A_SECOND *
NO_SECONDS_IN_A_MINUTE
);
errorMessage = proc.StandardError.ReadToEnd();
proc.WaitForExit();
outputMessage = proc.StandardOutput.ReadToEnd();
proc.WaitForExit();
それでうまくいくかどうかはわかりませんが、ハングアップする問題はありません。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
namespace VG
{
class VGe
{
[STAThread]
static void Main(string[] args)
{
Process proc = null;
try
{
string targetDir = string.Format(@"D:\adapters\setup");//this is where mybatch.bat lies
proc = new Process();
proc.StartInfo.WorkingDirectory = targetDir;
proc.StartInfo.FileName = "mybatch.bat";
proc.StartInfo.Arguments = string.Format("10");//this is argument
proc.StartInfo.CreateNoWindow = false;
proc.Start();
proc.WaitForExit();
}
catch (Exception ex)
{
Console.WriteLine("Exception Occurred :{0},{1}", ex.Message,ex.StackTrace.ToString());
}
}
}
}
string targetDir = string.Format(@"D:\");//PATH
proc = new Process();
proc.StartInfo.WorkingDirectory = targetDir;
proc.StartInfo.FileName = "GetFiles.bat";
proc.StartInfo.Arguments = string.Format("10");//argument
proc.StartInfo.CreateNoWindow = false;
proc.Start();
proc.WaitForExit();
テスト済み、動作します。
pg_dump.exeはおそらくユーザー入力を求めています。このデータベースには認証が必要ですか?サービスに存在しないENVIRONMENT変数に依存していますか? pg_dumpはわかりませんが、入力を求める他の理由は何ですか?
バッチファイルは何をしますか?バッチファイルを実行するのに十分な権限を持つプロセスが起動されていることを確信していますか?サービスは、許可されていることを制限できます。
また、copyコマンドなどを使用して、次のようなファイルを上書きしていることを確認してください。
echo Y | copy foo.log c:\backup\
また、バッチコマンドなどのフルパスを使用していることを確認してください。バッチファイルが何らかの「コンソール」モードでGUIアプリを起動している場合、それも問題になる可能性があります。サービスには、「デスクトップとの対話」を有効にしない限り、あらゆる種類のウィンドウやメッセージボックスを描画するための「デスクトップ」がないことに注意してください。プログラムでは、エラーメッセージなどを受け取った場合に備えて、stdoutパイプとstderrパイプを開き、実行中にそれらを読み取ることができます。
WebServicesはおそらくIUSRアカウントまたは匿名アカウントとして実行されているため、問題になる可能性があります。コンソールで実行したときに機能する場合、それは最初のステップにすぎません。 :)
System.Diagnosticsかどうか覚えていません。デバッグでのみ使用できます。おそらくそうではありませんが、一部はそうかもしれません。私はそれを確認する必要があります。
これがあなたにいくつかのアイデアを与えることを願っています。
ラリー
次のステップは、デバッガーを起動して、プログラムが待機しているものを確認できるかどうかを確認することです。アセンブリでのデバッグに精通している場合は、ProcExp、FileMonなどのツールを使用して、何が起こっているかIDEAを取得できる可能性があります。
WebサービスではなくWindowsサービスであるため、かなりの違いがあります。とにかく、「サービスがデスクトップと対話することを許可する」を設定するという私の提案を試しましたか?
絶望的な場合は、バッチファイルの代わりにcmd.exeを起動してみてください。次に、cmd.exeのcmd行パラメーターを使用して、ITにバッチファイルを開始させることができます。これにより、デスクトップとの対話をオンにした場合、実際の出力を表示するcmdプロンプトウィンドウが表示されます。
Cmd.exeの完全なヘルプを表示するには、cmd /?と入力してください。任意のコマンドプロンプト。
ラリー
これが解決策です。私はコードを何度も変更し、現在は機能しているため、解決策は明確ではありません。
ユーザーアカウントを使用しようとしましたが、うまくいきませんでした。 LocalSystemを使用します。実行するコードは、主にKevinから提供されたものです。
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo.FileName = fileName;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.UseShellExecute = false;
proc.Start();
proc.WaitForExit();
output1 = proc.StandardError.ReadToEnd();
proc.WaitForExit();
output2 = proc.StandardOutput.ReadToEnd();
proc.WaitForExit();
みんなありがとう、私はみんなに賛成投票し、ケビンは最初から私を助けてくれたので受け入れます。それは今動作するので非常に奇妙です...
Daok、変更したのは最初のWaitForExit()のタイムアウト期間だけだったようです。あなたはそれに非常に注意する必要があります。もし何か[〜#〜] does [〜#〜]があなたのサービスをハングさせた場合、それは決して返ってきません(そして、まあ、これまでのようにかなりの作業は.. hehですが)。エンドユーザーには良くありません...
おそらく、これがハングしている原因がわかっているので、さらにデバッグして完全な解決策を見つけることができます...
または、監視できるスレッドでこれをスピンオフし、ハングしすぎる場合は強制終了します。
私の2セント相当ですが、通常はそれほど多くありません。 ;)