这是核心问题:我有一个在单独的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#中正确清理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++/MFC应用程序通过DCOM相互通信.现在我们将更新应用程序,并且还希望用更现代的东西替换DCOM,这样更容易使用.但我们不知道是什么.你怎么看
编辑
交换的数据不是其他人可能感兴趣的.它只是在不同计算机上运行的程序的不同部分之间的状态信息.
我目前正在使用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)
我需要完全隐藏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)
我错过了什么?
有没有人想出一种方法来为Windows中的matlab数字制作缩略图类预览?
我已经厌倦了将.png和.fig文件一起保存,所以我知道它里面有什么.
对此有用的辅助工具是Windows的命令行实用程序,可以提供图像文件并告知它将其用作给定文件预览的基础.
我可以在matlab中编写一个辅助函数来保存.fig,制作一个临时图像文件,然后使用命令行实用程序将其推送到缩略图中.
我有来自第三方的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 … 在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不在别处使用.我正在将一些用C#编写的代码翻译成Java.此代码使用COM对象与第三方应用程序进行交互.我设法使用com4j库处理COM对象,但其中一个方法需要System.DBNull.value传递给它,这是一个C#对象.
如何从Java应用程序处理它?
我有一对使用相同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的接口都可以防止这是一个问题,但我似乎错了.有谁知道如何在两个库之间进行转换?也许是通过某种元帅?