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

我将代码包装在 atry/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

尝试从 Exception 打印更多内容:

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. 单击确定。

  7. 单击附加。

您必须使用 DEBUG 模式编译可执行文件


更新

我看到您使用Type.GetTypeFromProgID需要.NET 4.5,请确保您在引发错误的 PC 上安装了.NET 4.5 !

似乎t = System.Type.GetTypeFromProgID("VisualStudio.DTE.9.0", true);正在抛出COMException,这意味着“ VisualStudio.DTE.9.0 ”未在另一台 PC 中注册。

您应该添加Microsoft Visual Studio 2008 DTE作为程序的依赖项。

于 2012-10-18T20:34:58.033 回答
2

您也可以尝试订阅AppDomain.CurrentDomain.UnhandledException事件:

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

在方法的顶部执行此Main操作。

于 2012-10-18T20:47:02.127 回答
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 回答