- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个用 Delphi 7 编写的程序,它也是一个自动化服务器。
自动化服务器通过以下方式注册:
TAutoObjectFactory.Create(ComServer, TMyServer, Class_App,
ciMultiInstance, tmSingle);
我有两个 COM 加载项,一个用于 Word,一个用于 Outlook。他们都使用自动化服务器从主程序获取一些信息。从加载项调用以下代码,即:当用户单击加载项中的按钮时:
MyServerApp: Variant;
begin
MyServerApp := CreateOleObject('MyServer.App');
try
MyServerApp.DoSomething;
finally
MyServerApp := UnAssigned;
end–
问题是这样的:大多数时候代码运行良好。如果主应用程序已在运行,则加载项将连接到自动化服务器并执行其操作,如果主应用程序未运行,则加载项将启动主应用程序。
但由于一些未知的情况,尤其是 Outlook,有时可能会发生即使主程序正在运行,加载项也不会连接到它,而是会再次重新启动主应用程序并连接到这个新实例的自动化服务器。灾难来了:由于我的应用程序不允许自身在两个实例中运行,因此第二个应用程序实例将仅显示一条错误消息,并且我的加载项将卡住整个 Outlook。
为什么会发生这种情况?为什么 CreateOleObject 会像大多数时候那样进行连接,并时不时地再次启动我的应用程序?
最佳答案
您确实不应该在一篇文章中提出多个问题。
问题1
这种事在我身上发生过很多次。问题在于 Office 会为触发加载项中的代码的每个事件生成两个调用。我找到的解决方案是只响应第一个调用。
我使用了 Add-In Express
作为 COM 插件,它为我提供了一些可以链接到的事件。
我不确定您是否使用这个,但这是我使用的代码:
interface
....
var
MyApp: TAddInModule = nil;
implementation
procedure TAddInModule.adxCOMAddInModuleAddInFinalize(Sender: TObject);
begin
MyApp:= nil;
end;
procedure TAddInModule.adxCOMAddInModuleAddInInitialize(Sender: TObject);
begin
if not(Assigned(MyApp)) then try
MyApp:= Self;
except
{ignore}
end; {if try}
end;
在事件处理程序中,您必须测试是否引用了第一个实例或幽灵实例。 (两者有时都会被调用)。
procedure TAddInModule.adxCommandBar1Controls3Click(Sender: TObject);
begin
if (Self <> MyApp) then exit;
//ToggleDisplay
if not(ExcelBezig(xbQuestion)) then try
ToggleDisplay;
except {ignore}
end;
end;
这是一个拼凑(我承认),但它一劳永逸地解决了问题,并且此后该加载项一直稳定运行。
不要一遍又一遍地重新创建链接
您不应在每次需要查询应用程序时都使用 CreateOleObject('MyServer.App');
。激活插件后,您可以调用 CreateOleObject
一次,存储该实例,然后重用该链接。像这样的东西:
procedure TAddInModule.adxCOMAddInModuleAddInInitialize(Sender: TObject);
begin
if not(Assigned(MyApp)) then try
MyApp:= Self;
MyServerApp:= CreateOleObject('MyServer.App');
except
{ignore}
end; {if try}
end;
procedure TAddInModule.adxCommandBar1Controls3Click(Sender: TObject);
begin
if (Self <> MyApp) then exit;
try
MyServerApp.DoSomething;
except
{ignore}
end;
end;
使用变体访问自动化服务器很慢!
因为您使用变体来存储对自动化服务的引用,所以 Delphi 无法在编译时解析您的调用。
它也无法帮助您避免拼写错误和其他错误。
对通过变体访问的服务器的任何调用都是有效的。
所以
MyServer.StupidTyyyypo('hallo').doesnotexist('should be integer');
编译不会出错。
如果您导入类型库并将访问变量设置为特定类型,例如:
type
TMyServer = IMyServer;
您可以通过从 Delphi 自动化服务器导入类型库来获取 IMyServer,请参阅:http://www.blong.com/Articles/Automation%20In%20Delphi/Automation.htm
部分:使用接口(interface)控制自动化服务器
及以下部分。
问题2
Why does CreateOleObject connect to the running application instance and not create a separate instance all the time?
参见官方文档:http://docwiki.embarcadero.com/Libraries/XE2/en/System.Win.ComObj.CreateOleObject
它指出:
CreateOleObject creates a single uninitialized object of the class specified by the ClassName parameter. ClassName specifies the string representation of the Class ID (CLSID). CreateOleObject is used to create an object of a specified type when the CLSID is known, and when the object is on a local or in-proc server. Only objects that are not part of an aggregate are created using CreateOleObject.
Note: In Delphi code, CreateOleObject is called once to create each new single instance of a class. To create multiple instance of the same class, using a class factory is recommended.
问题3
does the tmSingle threading model mean that all calls to the automation server are executed in the application's main thread?
您应该在一个单独的问题中提出这个问题。
关于delphi - 自动化服务器使用 CreateOleObject 启动两次,但并非每次都启动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23633781/
关闭。这个问题需要details or clarity .它目前不接受答案。 想改进这个问题吗? 通过 editing this post 添加细节并澄清问题. 关闭 5 年前。 Improve t
背景 我有一个 Azure Runbook(名为 RunStoredProcedure2),定义如下: param( [parameter(Mandatory=$True)] [string] $Sq
我有一个名为“团队”的表,其中包含“非事件”列,另一个表“事件”,其中包含“时间”列。如果任何团队的“事件”中的最新日期发生在 X 时间之前,如何将“非事件”列更新(为 true)? 我知道这可以通过
下面的问题可能有点令人困惑,但我会尽力以最好的方式解释它。 假设我们为一家制造公司工作。它制造然后用于制造产品的组件。在以下示例中,有 3 个组件和 2 个最终产品。 组件和产品的需求如下: comp
我有代码可以让我在一个范围内选择一个项目: COleVariant vItems = cstrAddr; hr = AutoWrap(
我正在开发一个应用程序,该应用程序有 4 种语言的大约 50 个应用内购买,这给了我很多表单和子表单、框和子框,需要使用 iTunesConnect 的令人痛苦且设计糟糕的表单来填充。 我想知道是否有
我想在 Azure 自动化中使用 powershell 脚本来安排打开/关闭资源。 我想在不创建帐户的情况下执行此操作,因为我们的域强制重置密码。我知道自动化帐户会创建一个证书 - 当使用资源管理器(
我尝试从 azure 自动化 run book power shell 自动检索 azure SQL 数据库中的数据。我发现azure自动化帐户的模块中缺少SQL Server模块。我已经导入了该模块
我正在自动化 Outlook,并且需要控制电子邮件的发件人身份。用户将在 Outlook 中设置两个或多个帐户,我需要能够选择从哪个帐户发送电子邮件。有什么想法吗? 需要 Outlook 2003 及
我尝试从 azure 自动化 run book power shell 自动检索 azure SQL 数据库中的数据。我发现azure自动化帐户的模块中缺少SQL Server模块。我已经导入了该模块
假设我有一个网站,我可以(随时)登录并每隔 x 小时提交数据(单击登录后可见的链接),我将如何自动化此过程? 我构建了一个图形用户界面,它为用户(现在是我,为了我自己的方便)提供了一个包含一些信息的界
我正在开发一个程序,它的任务是我们为它定义一些号码(我们的一些手机号码)并且它应该在 Telegram 中注册它们,然后获取发送到该号码的所有消息。如您所知,在 Telegram 中注册需要提供电话号
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 3 年前。 Improve this qu
最近我在处理 CSS Sprite 。一切正常。 我创建了一个 sprite、.css 文件和 html 结构。看起来像 .sprites{ background-image:url
我想为一款名为 Dune 2000 的策略游戏创建一个叠加层。令人讨厌的是,要创建 10 个士兵,每次完成一个都必须单击该图标。没有队列。因此,在不干扰游戏运行方式的情况下,我想听听鼠标移动的声音,当
我是 python 的初学者,我想从自动化开始。以下是我正在尝试执行的任务。 ssh -p 2024 root@10.54.3.32 root@10.54.3.32's password: 我尝试通过
当我将一些 urlencoded Javascript 粘贴到 Firefox 和 Chrome 上的 URL 时,我看到了一些奇怪的事情发生。是否可以使用此技术告诉 Chrome 访问 URL,然后
我需要将大量请求自动提交到基于云的数据库接口(interface) (Intelex)。没有任何方法可以批量提交某些操作,但是提交单个请求所必需的只是让经过身份验证的用户尝试打开 Web 链接。因此,
假设我有一个进程的内存转储。我想对其运行报告,所以基本上我想打开 WinDBG,加载 SOS 并运行一个脚本,该脚本运行一些命令,解析输出,然后基于此运行更多命令。 除了像 SendKeys 这样的
我正在使用 ffmpeg 创建视频剪辑。我想自动化该过程并保存剪辑,而无需手动为要保存的每个文件命名。这是我拥有的代码。它将创建并保存剪辑,但只能使用扩展名和不是名字。 @echo off cd /d
我是一名优秀的程序员,十分优秀!