5

.NET 3.51 からアプリケーション (オペレーティング システム、マイ アプリケーション、および起動するアプリケーションはすべて 32 ビット) を起動しようとしています。

プロセスを起動するコードは他のアプリケーションにも使用されますが、頭を悩ませているものがあります。アプリケーションのアイコンを「ダブルクリック」すると、期待どおりに動作します。つまり、コンピュータ内のアプリケーションとして正常に動作します。.exe を直接ダブルクリックしても機能します。

オペレーティング システムは Windows 7 32 ビット (Home および/または Professional) です。

問題を回避するために、.NET アプリケーションは x86 でコンパイルされています。

「プロセス」を起動するコードは、私たちが作成した DLL (これも 32 ビット) 内にあります。基本的には、コード全体で使用する一般的なメソッド、関数、および全体にわたっていくつかの「共通コード」を保持する単純な DLL です。これらのメソッドの 1 つが次のようになります。

public static bool FireUpProcess( Process process, string path, bool enableRaisingEvents,
        ProcessWindowStyle windowStyle, string arguments )
    {
        if ( process != null )
        {
            try
            {
                process.StartInfo.FileName = @path;
                if ( arguments != null )
                {
                    if ( arguments != String.Empty )
                    {
                        process.StartInfo.Arguments = arguments;
                    }
                }
                process.StartInfo.WindowStyle = windowStyle;
                process.EnableRaisingEvents = enableRaisingEvents;
                process.Start();
            }
            catch
            {
                try
                {
                    process.Kill();
                }
                catch ( InvalidOperationException )
                {
                } // The process is not even created

                return false;
            }
        }
        else
        {
            return false;
        }
        return true;
    }

誰がこのメソッドを作成したのかはわかりませんが、さまざまなアプリケーションで約 6 年間動作しているため、「問題ない」と思います。ただし、その議論を通過したときに起動しないソフトウェアを持っている顧客がいます。

引数は次のとおりです。

  1. プロセスは、単純な「new Process();」で作成された System.Diagnostics.Process です</li>
  2. pathは、.exe「c:/path/to/my.exe」へのフル パスです。
  3. enableRaisingEventsが false
  4. windowStyleは最大化されています(ただし、他のものを試しました)。

それはくだらない MessageBox を与えます…私は喜んでそれを不滅にしました。それはスペイン語ですが、翻訳は簡単なはずです:

代替テキスト

それは言います:

アプリケーション エラー プログラム (0x0eedfade) で予期しない例外が発生しました …

0x0eedfade をグーグルで検索すると、恐ろしく見える奇妙な結果が得られますが、実際には、起動しようとしている .exe に移動してダブルクリックすると、完全に機能します。

記録のために : 他のもの (例: Notepad.exe、Adobe Acrobat Reader) を起動しようとすると、動作しますが、 Firefox が開かず、エラーも表示されません。

この「一部は機能し、一部は機能しない」という動作から、Windows 7 のセキュリティ メカニズムまたは同様の、私が知らない問題があるのではないかと考えてしまいます。

私は何が欠けているか、間違っていますか?

更新:わかりました。ソフトウェアのコピーを入手しました。面倒なソフトウェアですが、機能します。デバッグできるようになったので、FireUpProcessメソッドでプログラムを起動するとエラーが発生することがわかりました。

提案どおり、WorkingDirectory コードを追加しましたが、コードは次のとおりです。

    public static bool FireUpProcess(Process process, string path, bool enableRaisingEvents, ProcessWindowStyle windowStyle)
    {
        if (process != null)
        {
            try
            {
                if ( !String.IsNullOrEmpty(@path) )
                {
                    process.StartInfo.FileName = @path;
                    process.StartInfo.WorkingDirectory = System.IO.Path.GetDirectoryName(@path);
                    process.StartInfo.WindowStyle = windowStyle;
                    // Suscribe to the exit notification
                    process.EnableRaisingEvents = enableRaisingEvents;
                    // Disable to prevent multiple launchs
                    Framework.Check.LogWarning("LAUNCHING EXTERNAL DEVICE WITH PATH: " + path);
                    process.Start(); // HERE The program reports the following:

代替テキスト

つまり、「ddip.dll が見つからないため、プログラムを開始できませんでした… bla bla を再インストールしてみてください」ということです。

問題は、コマンド ラインから同じ @path を実行すると、プログラムが完全に開くということです。

代替テキスト

これにより、プログラムが開きます。「プログラム」メニューにある「ショートカット」をクリックしても同じことが起こります。そのショートカットにはパラメーターはありません。実行可能ファイルへの単純な呼び出しです。

質問は今です:私のコードと他の方法の違いは何ですか?

私のプロセスが開始されない原因は何か違うはずです。

何か案は?

更新と解決策

以下の回答のいずれかを使用して機能させました。解決策を直接教えてくれる人は誰もいなかったことが判明しましたが、彼らは皆、あちこちで良いアイデアをくれました。

アプリケーションにアプリ マニフェストを追加しました( vista の時代からあるはずでしたが、なぜ最初の場所になかったのかわかりません)。VStudio 2008 add file -> app manifest を使用して追加したアプリ マニフェスト。

その中で、これがあることを確認しました:

<requestedExecutionLevel level=“asInvoker” uiAccess=“false” />

管理者などは必要ありませんが、明らかに Vista/7 はそれを知る必要があります。

それが追加された後、プロセスは正しく起動されます。

: UseShellExecute はデフォルトでtrueです(一部の人が示唆しているように)。それが必要な場合は、明示的に false に変更する必要があります。

4

6 に答える 6

8

process.StartInfo.WorkingDirectory プロパティを設定していません。EXE が格納されているディレクトリが作業ディレクトリであると想定している、よく書かれていないソフトウェアがたくさんあります。少なくとも次の行を追加します。

 process.StartInfo.WorkingDirectory = System.IO.Path.GetDirectoryName(@path);

ただし、例外はかなり奇妙です。マルウェア対策ツールを更新するようお客様に伝えることを強くお勧めします。

于 2010-10-29T14:07:39.753 に答える
5

exe にマニフェストがある場合は、Start を呼び出す前に、プロセス オブジェクトで UseShellExecute を true に設定する必要があります。いずれにせよ、それは悪い考えではありません。

于 2010-10-29T13:51:27.200 に答える
3

Kate Gregory が指摘したように、ユーザーがアイコンをダブルクリックして「エミュレート」したい場合は、UseShellExecuteを true に設定する必要があります。このフラグを設定すると、基になる Windows のShellExecute関数を使用して、コードがまったく異なるパスを使用するようになります。

さらに、UAC を搭載した Windows (Vista、7、2008 など) で実行している場合は、ここここで説明されているように、 runas動詞も使用してみてください。

.NET では、次のようになります。

if (System.Environment.OSVersion.Version.Major >= 6)  // UAC's around...
{
   processStartInfo.Verb = "runas";
}
于 2010-12-05T09:39:58.653 に答える
1

私は過去に同様の問題を抱えていました。次のようにcmdアプリを実行して解決しました:

public static bool FireUpProcess(Process process, string path, bool enableRaisingEvents, ProcessWindowStyle windowStyle) 
{ 
    //if path contains " ", surround it with quotes.
    //add /c and the path as parameters to the cmd process. 
    //Any other parameters can be added after the path.

    ProcessStartInfo psi = new ProcessStartInfo("cmd", "/c" + path ));            
    psi.WorkingDirectory = System.IO.Path.GetDirectoryName(@path);          
    psi.WindowStyle = windowStyle;          
    // Suscribe to the exit notification          
    process.EnableRaisingEvents = enableRaisingEvents;          
    // Disable to prevent multiple launchs          
    Framework.Check.LogWarning("LAUNCHING EXTERNAL DEVICE WITH PATH: " + path);          
    process.Start(); ...}
于 2010-12-01T16:24:51.173 に答える
1

可能であれば、プロセスモニターを使用してみますシスインターナルズから。起動すると、ツールバーの [レジストリとネットワーク アクティビティ] の選択を解除できます (右側の 5 つのアイコン)。次に、プロセスとディスクのアクティビティのみが表示されます。ファイルが見つからない問題のように見えるので、[フィルター] ダイアログ (左の 6. アイコン) を使用して、ドロップダウン リストから [プロセス名] を選択し (アーキテクチャーがデフォルトです)、失敗した実行可能ファイルの名前を入力します。これにより、キャプチャされた出力が大幅に制限されるため、何が起こっているかを確認できます。次に、実行可能ファイルを開始し、結果列で NAME NOT FOUND の結果を確認します。これは、ファイルが検索されたが見つからなかった場所です。問題のある dll 名がわかっている場合は、通常どおり Ctrl+F で検索して掘り出すことができます。次に、作業中のアプリケーションからのさまざまな検索パスと、アプリケーションから開始されたときの検索パスを比較できます。

環境変数 PATH がプロセス内で異なる値を持っている可能性がありますか? を追加することもできます。(現在のディレクトリ) は、dll 検索パスを修正するのに役立ちます。または、アプリケーションが別のユーザー アカウントから起動されていますか? また、アプリケーションが Programm Files に何かをインストールしているが、権限がない (管理者のみがこれを実行できる) 場合、Windows が書き込みをユーザー プロファイルにリダイレクトするという新機能である可能性もあります。これは、安全性を高めるための安全で透過的な方法です。ただし、これにより、最初のアプリケーションの起動時などに、UAC ダイアログからの同意なしにアプリケーションを実行しているときに、構成ファイルなどが管理者プロファイルに展開される可能性があります。

于 2010-12-04T00:03:08.210 に答える
0

ハンス・パッサンは正しい道を歩んでいると私は信じています。彼が言ったことに加えて、ddip.dll と exe が同じディレクトリにあることを確認してください。ビンの外側でアセンブリをバインドする他の方法があるため、これは常に当てはまるとは限りません。つまり、GAC と AssemblyResolve イベントです。あなたの状況を考えると、GAC が関与する理由はわかりません。AssemblyResolveイベントへのフックがないか、起動された exe のコードを確認します。フックされている場合は、別のプロセスがそれを起動できるように実装を更新する必要がある場合があります。

欠落している DLL に関する例外が発生しているため、パス区切り文字の問題に関する回答にはほとんど自信がありません。ただし、アプリケーション コードはあるので、それが ddip.dll を参照していることを確認してください。これにより、実際に正しい .exe を参照していることにかなりの自信が持てます。したがって、コマンド プロンプトの単なるパス区切りの問題ではありません (例: 誤って解釈されたスペース)。

于 2010-12-06T22:04:54.370 に答える