标签: com

COM互操作是否尊重.NET AppDomain边界以进行程序集加载?

这是核心问题:我有一个在单独的AppDomain中使用COM互操作的.NET应用程序.COM的东西似乎是将程序集加载回默认域,而不是从中调用COM内容的AppDomain.

我想知道的是:这是预期的行为,还是我做错了导致这些COM相关程序集被加载到错误的AppDomain中?请参阅以下情况的更详细说明......

该应用程序由3个程序集组成: - 主EXE,应用程序的入口点. - common.dll,只包含一个接口IController(采用IPlugin风格) - controller.dll,包含一个实现IController和MarshalByRefObject的Controller类.此类完成所有工作并使用COM interop与另一个应用程序进行交互.

主要EXE的相关部分如下所示:

AppDomain controller_domain = AppDomain.CreateDomain("Controller Domain");
IController c = (IController)controller_domain.CreateInstanceFromAndUnwrap("controller.dll", "MyNamespace.Controller");
result = c.Run();
AppDomain.Unload(controller_domain);
Run Code Online (Sandbox Code Playgroud)

common.dll只包含以下两件事:

public enum ControllerRunResult{FatalError, Finished, NonFatalError, NotRun}
public interface IController
{
    ControllerRunResult Run();
}
Run Code Online (Sandbox Code Playgroud)

controller.dll包含这个类(也调用COM互操作的东西):

public class Controller: IController, MarshalByRefObject
Run Code Online (Sandbox Code Playgroud)

首次运行应用程序时,Assembly.GetAssemblies()看起来像预期的那样,在两个AppDomain中都加载了common.dll,并且只将controller.dll加载到控制器域中.在调用c.Run()之后,我看到与COM互操作内容相关的程序集已加载到默认的AppDomain中,而不是在发生COM互操作的AppDomain中.

为什么会发生这种情况?

如果你有兴趣,这里有一些背景知识:

最初这是一个AppDomain应用程序.它与之接口的COM东西是一个服务器API,它在长时间使用时不稳定.当COM东西发生COMException(没有关于其原因的有用诊断信息)时,整个应用程序必须重新启动才能再次使用COM连接.只需重新连接到COM应用服务器,就会再次导致COM异常.为了解决这个问题,我试图将COM互操作内容移动到一个单独的AppDomain中,这样当神秘的COMExceptions出现时,我可以卸载发生它的AppDomain,创建一个新的并再次启动,所有这些都无需手动重启应用程序.无论如何,这就是理论......

c# com interop com-interop appdomain

8
推荐指数
1
解决办法
3397
查看次数

C#interop:在将新工作表添加到现有文件后,excel进程不会退出

可能重复:
如何在C#中正确清理Excel互操作对象

我在这里阅读了许多关于管理COM引用的其他线程,同时使用.Net-Excel互操作来确保Excel进程在退出时正确退出,到目前为止,这些技术已经运行良好,但我最近遇到了一个将新工作表添加到现有工作簿文件时出现问题.

下面的代码留下了僵尸Excel进程.

如果我将工作表添加到新创建的工作簿文件,它将退出正常.如果我运行除.Add()行之外的代码,它会退出.(我正在读取的现有文件是由注释掉的代码创建的空文件)

有任何想法吗?

//using Excel = Microsoft.Office.Interop.Excel;
//using System.Runtime.InteropServices;
public static void AddTest()
{
  string filename = @"C:\addtest.xls";
  object m = Type.Missing;
  Excel.Application excelapp = new Excel.Application();
  if (excelapp == null) throw new Exception("Can't start Excel");
  Excel.Workbooks wbs = excelapp.Workbooks;

  //if I create a new file and then add a worksheet,
  //it will exit normally (i.e. if you uncomment the next two lines
  //and comment out the .Open() line below):
  //Excel.Workbook wb = wbs.Add(Excel.XlWBATemplate.xlWBATWorksheet);
  //wb.SaveAs(filename, …
Run Code Online (Sandbox Code Playgroud)

c# com excel interop pia

8
推荐指数
2
解决办法
3万
查看次数

我们应该用什么取代DCOM通信?

我们目前有许多C++/MFC应用程序通过DCOM相互通信.现在我们将更新应用程序,并且还希望用更现代的东西替换DCOM,这样更容易使用.但我们不知道是什么.你怎么看

编辑

交换的数据不是其他人可能感兴趣的.它只是在不同计算机上运行的程序的不同部分之间的状态信息.

c++ com mfc dcom

8
推荐指数
1
解决办法
851
查看次数

Python干净的方式来包装try块中的单个语句

我目前正在使用com进行Excel的Python自动化.它功能齐全,可以满足我的需求,但我发现了一些令人惊讶的东西.有时,我使用的某些Excel命令会因为没有明显原因的异常而失败.其他时候,他们会工作.

在我正在做的VB等效代码中,这个问题显然被认为是正常的,并且用一个On Error Resume Next语句贴满了.当然,Python没有声明.

我无法将整个集合包裹在一个try except循环中,因为它可能会在中途"失败"并且无法正常完成.那么,将几个独立语句包装到try除块之外的pythonic方法是什么?具体来说,比以下更清洁:

try:
   statement
except:
   pass
try:
   statement
except:
   pass
Run Code Online (Sandbox Code Playgroud)

相关的代码是excel.Selection.Borders位.

def addGridlines(self, infile, outfile):
    """convert csv to excel, and add gridlines"""
    # set constants for excel
    xlDiagonalDown = 5
    xlDiagonalUp = 6
    xlNone = -4142
    xlContinuous = 1
    xlThin = 2
    xlAutomatic = -4105
    xlEdgeLeft = 7
    xlEdgeTop = 8
    xlEdgeBottom = 9
    xlEdgeRight = 10
    xlInsideVertical = 11
    xlInsideHorizontal = 12
            # open file
    excel = win32com.client.Dispatch('Excel.Application') …
Run Code Online (Sandbox Code Playgroud)

python com excel vba try-catch

8
推荐指数
2
解决办法
3520
查看次数

如何隐藏excel列?


我需要完全隐藏excel列.我使用下面的代码,但没有工作:

public void Hide (params string[] columns)
{
    foreach(var column in columns)
    {
        Range range = (Range) oSheet.Columns[column, Type.Missing];
        range.EntireColumn.Hidden = true;
    }
}
Run Code Online (Sandbox Code Playgroud)

我错过了什么?

c# com excel

8
推荐指数
2
解决办法
1万
查看次数

Windows资源管理器中matlab数据的预览(将图像设置为另一个文件的缩略图的实用程序)

有没有人想出一种方法来为Windows中的matlab数字制作缩略图类预览?

我已经厌倦了将.png和.fig文件一起保存,所以我知道它里面有什么.

对此有用的辅助工具是Windows的命令行实用程序,可以提供图像文件并告知它将其用作给定文件预览的基础.

我可以在matlab中编写一个辅助函数来保存.fig,制作一个临时图像文件,然后使用命令行实用程序将其推送到缩略图中.

windows com matlab preview matlab-figure

8
推荐指数
1
解决办法
947
查看次数

如何抑制由我​​无法更改的代码显示的对话框?

我有来自第三方的Inproc COM服务器.如果它捕获特定类型的错误,我调用的函数之一将显示错误消息对话框.问题是我正在尝试批量处理数据,而我使用的数据源导致错误对话框弹出很多.如果它生成了1000个对话框,这不会成为问题,而是它会阻塞,直到您按OK才会返回该功能.

在此输入图像描述

如何禁止显示对话框,或以编程方式按OK?

这是一个调用堆栈的副本,​​因为它正在等待我按OK

    [Managed to Native Transition]  
>   System.Windows.Forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(System.IntPtr dwComponentID, int reason, int pvLoopData) Line 2198 + 0x1e bytes   C#
    System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int reason, System.Windows.Forms.ApplicationContext context) Line 3422 + 0x1b bytes C#
    System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int reason, System.Windows.Forms.ApplicationContext context) Line 3306 + 0xc bytes   C#
    System.Windows.Forms.dll!System.Windows.Forms.Application.Run(System.Windows.Forms.Form mainForm) Line 1495 + 0x31 bytes    C#
    UniversalDataImporter.exe!UniversalDataImporter.Program.Main() Line 18 + 0x1d bytes C#
    [Native to Managed Transition]  
    [Managed to Native Transition]  
    mscorlib.dll!System.AppDomain.ExecuteAssembly(string assemblyFile, System.Security.Policy.Evidence assemblySecurity, string[] args) Line 2023 + 0x18 bytes  C#
    Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() + 0x27 bytes  
    mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object …

.net c# com messagebox .net-4.0

8
推荐指数
1
解决办法
7990
查看次数

SetApartmentState和[STAThread]

在Watin的源代码中,有这段代码:

    public void NavigateToNoWait(Uri url)
    {
        var thread = new Thread(GoToNoWaitInternal);
        thread.SetApartmentState(ApartmentState.STA);
        thread.Start(url);
        thread.Join(500);
    }

    [STAThread]
    private void GoToNoWaitInternal(object uriIn)
    {
        var uri = (Uri)uriIn;
        NavigateTo(uri);
    }
Run Code Online (Sandbox Code Playgroud)

由于创建的线程设置了其单元状态,为什么该[STAThread]属性被添加到方法中?我对特定的代码段不感兴趣,但我想知道是否STAThread需要属性.

笔记:

  • 该方法GoToNoWaitInternal不在别处使用.
  • 整个watin项目是关于操纵WebBrowser对象(一般的Internet Explorer窗口).因此,我们正在操纵COM对象.

c# com multithreading watin sta

8
推荐指数
1
解决办法
7085
查看次数

如何在Java中使用C#System.DBNull.value?

我正在将一些用C#编写的代码翻译成Java.此代码使用COM对象与第三方应用程序进行交互.我设法使用com4j库处理COM对象,但其中一个方法需要System.DBNull.value传递给它,这是一个C#对象.

如何从Java应用程序处理它?

c# java com

8
推荐指数
1
解决办法
1707
查看次数

在C#中使用相同的COM接口在2个不同的库之间进行转换

我有一对使用相同COM接口的库.在一个库中,我有一个实现该接口的类.另一个库需要一个实现接口的对象.

但是两个库都有自己的接口定义.两者略有不同,但基本上是相同的界面.

所以我尝试将它们放在如下:

 Library2.Interface intf = (Library2.Interface)impl;
Run Code Online (Sandbox Code Playgroud)

但这引起了例外.如果我执行以下操作:

 Library1.Interface intf = (Library1.Interface)impl;
Run Code Online (Sandbox Code Playgroud)

然后它没有问题,但我不能再将类传递给Library2.

我天真地假设两个具有相同GUID的接口都可以防止这是一个问题,但我似乎错了.有谁知道如何在两个库之间进行转换?也许是通过某种元帅?

.net c# com casting com-interop

8
推荐指数
1
解决办法
536
查看次数