7

Windows 7、64 ビットの Visual Studio 2008 でソリューションを作成しました。

できます。

それを別のマシンに移動すると、同じくwin 7、64ビットで、ほとんど情報なしでクラッシュしました。

元の問題はこれでした:

呼び出しは呼び出し先によって拒否されました

次に、このソリューションを実装しました:

Visual Studio 2008 の GetTypeFromProgID を適切に取得する方法

ただし、現在私の問題は、別のマシンで実行可能ファイルを実行すると、プログラムが次の情報ですぐにクラッシュすることです。

Description:
  Stopped working

Problem signature:
  Problem Event Name:   APPCRASH
  Application Name: EmailSalesVolumeSolution.exe
  Application Version:  1.0.0.0
  Application Timestamp:    508064dd
  Fault Module Name:    KERNELBASE.dll
  Fault Module Version: 6.1.7601.17932
  Fault Module Timestamp:   503285c2
  Exception Code:   e0434f4d
  Exception Offset: 000000000000caed
  OS Version:   6.1.7601.2.1.0.256.48
  Locale ID:    1033

Read our privacy statement online:
  http://go.microsoft.com/fwlink/?linkid=104288&clcid=0x0409

If the online privacy statement is not available, please read our privacy statement offline:
  C:\Windows\system32\en-US\erofflps.txt

コードを でラップしましたtry/catchが、適切なエラー メッセージが表示されませんでした。

static void Main()
{
    try
    {
        EnvDTE80.DTE2 dte;
        object obj = null;
        System.Type t = null;

        // Get the ProgID for DTE 8.0.
        t = System.Type.GetTypeFromProgID("VisualStudio.DTE.9.0",
          true);
        // Create a new instance of the IDE.
        obj = System.Activator.CreateInstance(t, true);
        // Cast the instance to DTE2 and assign to variable dte.
        dte = (EnvDTE80.DTE2)obj;

        // Register the IOleMessageFilter to handle any threading
        // errors.
        MessageFilter.Register();
        // Display the Visual Studio IDE.
        dte.MainWindow.Activate();


        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        Application.Run(new Form1());

        // For example, get a reference to the solution2 object
        // and do what you like with it.

        // All done, so shut down the IDE...
        dte.Quit();
        // and turn off the IOleMessageFilter.
        MessageFilter.Revoke();

    }
    catch (Exception e)
    {
        MessageBox.Show(e.ToString());
    }
}

例外が発生した正確な場所とその例外を特定するにはどうすればよいですか?

アンマネージ コードがいくつかあります。

using System;
using System.Collections.Generic;
using System.Text;
using EnvDTE;
using EnvDTE80;
using EnvDTE90;
using System.Runtime.InteropServices;

namespace EmailSalesVolumeSolution
{
    public class MessageFilter : IOleMessageFilter
    {
        //
        // Class containing the IOleMessageFilter
        // thread error-handling functions.

        // Start the filter.
        public static void Register()
        {
            IOleMessageFilter newFilter = new MessageFilter();
            IOleMessageFilter oldFilter = null;
            CoRegisterMessageFilter(newFilter, out oldFilter);
        }

        // Done with the filter, close it.
        public static void Revoke()
        {
            IOleMessageFilter oldFilter = null;
            CoRegisterMessageFilter(null, out oldFilter);
        }

        //
        // IOleMessageFilter functions.
        // Handle incoming thread requests.
        int IOleMessageFilter.HandleInComingCall(int dwCallType,
          System.IntPtr hTaskCaller, int dwTickCount, System.IntPtr
          lpInterfaceInfo)
        {
            //Return the flag SERVERCALL_ISHANDLED.
            return 0;
        }

        // Thread call was rejected, so try again.
        int IOleMessageFilter.RetryRejectedCall(System.IntPtr
          hTaskCallee, int dwTickCount, int dwRejectType)
        {
            if (dwRejectType == 2)
            // flag = SERVERCALL_RETRYLATER.
            {
                // Retry the thread call immediately if return >=0 & 
                // <100.
                return 99;
            }
            // Too busy; cancel call.
            return -1;
        }

        int IOleMessageFilter.MessagePending(System.IntPtr hTaskCallee,
          int dwTickCount, int dwPendingType)
        {
            //Return the flag PENDINGMSG_WAITDEFPROCESS.
            return 2;
        }

        // Implement the IOleMessageFilter interface.
        [DllImport("Ole32.dll")]
        private static extern int
          CoRegisterMessageFilter(IOleMessageFilter newFilter, out 
          IOleMessageFilter oldFilter);
    }
    [ComImport(), Guid("00000016-0000-0000-C000-000000000046"),
    InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
    interface IOleMessageFilter
    {
        [PreserveSig]
        int HandleInComingCall(
            int dwCallType,
            IntPtr hTaskCaller,
            int dwTickCount,
            IntPtr lpInterfaceInfo);

        [PreserveSig]
        int RetryRejectedCall(
            IntPtr hTaskCallee,
            int dwTickCount,
            int dwRejectType);

        [PreserveSig]
        int MessagePending(
            IntPtr hTaskCallee,
            int dwTickCount,
            int dwPendingType);
    }
}

問題が発生したマシンに VS 2008 Express をインストールした後、次のようになりました。

ここに画像の説明を入力

4

4 に答える 4

2

AppDomain.CurrentDomain.UnhandledExceptionイベントで購読することもできます:

AppDomain.CurrentDomain.UnhandledException += 
      (sender, e) => MessageBox.Show(e.ExceptionObject.ToString());

Mainメソッドの先頭でこれを行います。

于 2012-10-18T20:47:02.127 に答える
2

例外からさらに印刷してみてください:

catch(Exception e)
{
    MessageBox.Show(e.Message + ":\n" + e.StackTrace);
}

これを使用して、すべての内部例外もキャッチできます。

string except = "Uncaught Exception: ";
while(e != null)
{
    except += e.Message + ";\n";
    e = e.InnerException;
}

プログラムが例外なくクラッシュする場合は、デバッガーを接続してみる必要があります。

コンピューターにVisual Studioをインストールするか、リモート デバッグにリモート デスクトップを使用できるようにする必要があります。方法: 実行中のプロセスにアタッチする

実行中のプロセスにアタッチするには:

  1. [デバッグ] メニューで、[プロセスにアタッチ] を選択します。

  2. [プロセスにアタッチ] ダイアログ ボックスで、アタッチするプログラムを [使用可能なプロセス] リストから見つけます。

    デバッグするプログラムが別のコンピューターで実行されている場合は、[修飾子] リスト ボックスを使用してリモート コンピューターを選択します。詳細については、「方法 : リモート コンピューターを選択する」を参照してください。

    プロセスが別のユーザー アカウントで実行されている場合は、[すべてのユーザーのプロセスを表示する] チェック ボックスをオンにします。

    リモート デスクトップ接続を介して接続している場合は、[すべてのセッションのプロセスを表示する] チェック ボックスをオンにします。

  3. [アタッチ先] ボックスに、デバッグするコードの種類が表示されていることを確認します。デフォルトの自動設定では、デバッグするコードのタイプを決定しようとします。自動設定が適切でない場合:

  4. [選択] をクリックします。

  5. [コード タイプの選択] ダイアログ ボックスで、[これらのコード タイプをデバッグ] をクリックし、デバッグするタイプを選択します。

  6. [OK] をクリックします。

  7. [添付] をクリックします。

実行可能ファイルを DEBUG モードでコンパイルする必要があります


アップデート

.NET 4.5Type.GetTypeFromProgIDを必要とするものを使用しているようです。エラーをスローしている PC に.NET 4.5がインストールされていることを確認してください。

他のPCに「 VisualStudio.DTE.9.0 」が登録されていないことを意味するCOMExceptiont = System.Type.GetTypeFromProgID("VisualStudio.DTE.9.0", true);を投げているようです。

プログラムの依存関係としてMicrosoft Visual Studio 2008 DTEを追加する必要があります。

于 2012-10-18T20:34:58.033 に答える
1

DLL がクライアント マシンに登録されていない可能性があります。COM オブジェクトを呼び出している DLL を確認Regsvr32 YouComDllName.dllし、管理コマンド プロンプトで実行します (コマンド プロンプト アイコンを右クリックして実行しますRun as Administrator。32 ビットまたは 64 ビット アプリケーションを使用しているかどうかに応じて、 Regsvr32 のコピー inC:\Windows\System32または in C:\Windows\SysWOW64(逆方向に、64 ビット バージョンは system32 にあり、32 ビット バージョンは SysWOW64 にあります)


コンピューターに DLL を登録するだけでは機能しない場合は、コンピューターのプログラムでDependancy Walkerを実行します。プログラムが触れるすべての DLL を取得したら、クライアント コンピューターに欠落がないことを確認します。呼び出している DLL は存在する可能性がありますが、依存する DLL が存在しない可能性があります。

于 2012-10-18T22:39:48.427 に答える
0

機能する唯一の解決策は、Visual Studio をインストールすることでした。インストールするとすぐに、正確な例外が発生しました。

于 2012-10-18T21:51:30.930 に答える