我很确定这必须在某种教科书中(或者更有可能在所有这些教科书中)但我似乎使用了错误的关键词来搜索它...... :(
我在编程时遇到的一个反复出现的任务是我正在处理来自不同来源的对象列表,我需要以某种方式保持同步.通常有一些"主列表",例如由一些外部API返回,然后是我自己创建的对象列表,每个对象都与主列表中的对象相对应(想想"包装"或"适配器" - 它们通常包含扩展信息关于特定于我的应用程序的外部对象和/或它们简化了对外部对象的访问.
那么我通常如何解决这个问题呢?我应该google算法的名称是什么?
在过去,我已经以各种方式实现了这一点(参见下面的示例),但总觉得应该有更清洁,更有效的方式,尤其是不需要两次迭代的方法(每个列表一个).
这是一个示例方法:
更新1
感谢您的所有回复!我需要一些时间来查看链接.
[...] (文字移至问题主体)
更新2 将中间段重构为(希望)更易于解析的项目符号列表,并在第一次更新中添加后续添加的详细信息.
我们的安装程序是用Inno Setup编写的,我们对它非常满意.然而,一些客户不断要求MSI安装程序,他们可以通过Active Directory更轻松地分发.我们已经花了一些时间,通过/LOADINF
使用我们自己的选项扩展Inno Setup的机制,使安装程序与自动化和无人值守安装相得益彰.
为了满足客户要求MSI,我一直在考虑简单地将我们的常规安装程序包装在MSI中,可能是使用WIX创建的.问题是:我可以保持当前安装程序提供的高可配置性吗?在无人值守/大规模安装方案中,如何通过外部MSI公开Inno Setup安装程序的选项?
请注意,我还没有真正深入到实际挖掘MSI创建和WIX的程度.现在我只关心那些知道他们在说什么的人认为这是一种可行/合理的方法来投入我们的能量......
[编辑:]最初我认为我可以使用临时提取和执行方法,即MSI只是用作将Inno安装程序交付到目标PC并在其中以/VERYSILENT
-mode 执行的容器.但我想要求MSI的客户也希望能够从中央位置卸载甚至修改安装,我想在那种情况下这是不可能的,不是吗?
PS:我们在这里也有一份WISE for MSI的旧版本,但这种体验实际上就是为什么我们开始使用Inno来开始...
从几个初步测试开始,似乎EnumWindows
总是以反向实例化顺序返回窗口,即最近实例化的窗口.这是一个有效的观察吗?如果是这样,在所有版本的Windows中都是如此吗?这是一个可靠的假设,即某种行为记录在哪里?
上下文:我正在处理我触发第三方应用程序打开几个非模态窗口的情况,我需要在打开后向这些窗口发送一些窗口消息,但我没有确定的方式鉴定它们的窗口类别和它们的标题都不会有所不同,我也不知道它们的预期坐标.但是,如果我可以依赖上面的行为,EnumWindows
我可以简单地使用返回的第一个句柄,EnumWindows
其类和标题符合我的期望.这仍然留下一些假设的循环漏洞,但我认为这将是足够好的.尽管如此,欢迎另类建议.
几个星期以来,我们一直在努力解决一个问题,即少数客户的Outlook插件因未确定的原因而被卸载和禁用."禁用"是指Outlook将以下注册表值从3更改为2,这实际上意味着下次启动时不会加载该插件:
HKEY_LOCAL_MACHINE\Software\Microsoft\Office\Outlook\Addins\[OurAddin.sProgID]\LoadBehavior
没有错误消息,也没有任何异常显示在我们的addin生成自己的日志文件中.
我已经找到以下专门处理LoadBehavior更改问题的页面:http://blogs.msdn.com/vsod/archive/2008/04/22/Troubleshooting-com-add-in-load-failures.aspx
但是,那里提出的任何可能的理由似乎都不适用:
IDTExtensibility2
方法中和代码中的任何其他地方都没有未处理的异常.所有代码都包含在try/catch等效项中,并且所有异常输出仅通过OutputDebugString
日志文件发送或发送到日志文件中.那么,还有什么可以导致Outlook禁用插件?
更多细节/观察:
OutputDebugString
消息放入initialization
部分(这是一个Delphi DLL).当插件无法加载时,它们都不会出现.只有极少数客户受此问题影响.我们有数万个安装,我们没有收到任何关于此的报告.
更新:似乎经常(但不总是)在addin被卸载之前记录的最后一件事是文本"OLE错误800A01A8"的异常.该异常被我正在使用的框架(Add-in-Express)中内置的全局异常处理程序捕获,并且看起来并不是源自我自己的代码,而现在每个方法完全包含在其中try..catch
.这通常发生在我从Inspector的Activate事件处理程序设置我的CommandBarButtons的可见性之后.
所有受影响机器的共同属性:
还有一点需要注意的是,这可能也很重要(尽管可能没有我想象的那么多):
我们正在使用来自第三方供应商的许可/复制保护模块,该模块将已编译的DLL包装在"shell"中,并且仅在运行时解包.自从我发现即使在我们自己的代码被执行之前,addin被卸载,这一直是我的主要嫌疑人.但是,虽然供应商确认其代码中可能存在未处理的异常,但是由保护shell的特殊调试版本生成的日志文件显示解包过程已成功完成,并且在Outlook卸载插件之前控件已经传回受保护的DLL .因此,无论是什么导致Outlook卸载我们的插件都发生在保护shell初始化完成和我们自己的代码之间.
还有什么想法吗?
因此,在最近的一些更改后,我们发现我们最老的应用程序之一有时会在关机时崩溃.这表现为"运行时错误216"消息的形式,或者来自Windows错误报告的消息,表明应用程序已停止工作.该应用程序已经OutputDebugString
在每个回合发出消息,AFAICT我们自己的所有代码都正确执行完成.所有析构函数都被称为所有终结部分和类析构函数,其中没有一个会引发任何异常.
此外,madExcept和FastMM4的完全调试模式似乎都没有什么可抱怨的(尽管这可能是一个错误的结论,因为甚至在这些组件自己的终结代码运行之前就可能发生崩溃).
那么,你会做什么?你会从哪里开始的?
这个问题应该更多地关于这类问题的一般方法,而不是我目前面临的具体实例,所以我故意遗漏细节.请随意询问您是否认为它们可能与调试方法的选择相关,我稍后会添加它们.
我正在尝试使用SetWindowsHookEx
设置一个WH_SHELL
钩子来获得系统范围HSHELL_WINDOWCREATED
和HSHELL_WINDOWDESTROYED
事件的通知.我传递0作为最终dwThreadId
参数,根据文档,它应该"将钩子过程与在与调用线程相同的桌面上运行的所有现有线程相关联".我也将参数传递给我的DLL(HInstance
在Delphi中),hMod
就像我看到的所有例子一样.
然而,我只收到由我自己的应用程序创建的窗口的通知 - 通常情况下 - 我的测试导致桌面进程在关闭我的应用程序后熄火.在你问之前,我打电话UnhookWindowsHookEx
.我也经常CallNextHookEx
在我的经纪人内部打电话.
我正在从一个有限的用户帐户运行我的测试应用程序,但到目前为止我还没有找到任何提示,表明这将起作用...(虽然这实际上让我感到惊讶)
AFAICT,我按书完成了一切(显然我没有,但到目前为止,我没有看到哪里).
我正在使用Delphi(2007),但我认为这不应该真的重要.
编辑:也许我之前应该提到这个:我确实下载并尝试了几个例子(尽管很遗憾没有那么多可用于Delphi - 特别是没有用于WH_SHELL
或者WH_CBT
).虽然它们不会像我的测试应用程序一样崩溃系统,但它们仍然不会捕获来自其他进程的事件(即使我可以使用ProcessExplorer验证它们是否可以加载到它们中).所以我的系统配置似乎有问题,或者示例错误,或者根本无法从其他进程捕获事件.任何人都可以开导我吗?
编辑2:好的,这是我的测试项目的来源.
包含钩子过程的DLL:
library HookHelper;
uses
Windows;
{$R *.res}
type
THookCallback = procedure(ACode, AWParam, ALParam: Integer); stdcall;
var
WndHookCallback: THookCallback;
Hook: HHook;
function HookProc(ACode, AWParam, ALParam: Integer): Integer; stdcall;
begin
Result := CallNextHookEx(Hook, ACode, AWParam, ALParam);
if ACode < 0 then Exit;
try …
Run Code Online (Sandbox Code Playgroud) 我们正在使用trac并且对它非常满意.但是,开箱即用,trac最适合单项目环境.我有兴趣了解人们采取的各种方法,以使其与多个项目一起工作,以及他们的经验.有推荐的插件吗?任何补丁,调整或诸如此类的东西?您是否甚至可以使用完全不同的错误跟踪系统来提供所有trac的功能以及多项目支持?
我们最近开始自己管理第二个项目,这通常可以正常工作但也有一些缺点,特别是在两个项目重叠的情况下,因为我们编写的公共库代码在两个项目中都使用.你怎么处理这个?
(我将附上我们自己当前的方法作为这篇文章的答案.)
在我的几个应用程序中,我的代码类似于以下内容:
if ForceDirectories(ExtractFilePath(lLogName)) then
begin
AssignFile(lLog, lLogName);
try
if FileExists(lLogName) then
Append(lLog)
else
Rewrite(lLog);
Writeln(lLog, lLogLine);
finally
{$I-}CloseFile(lLog);{$I+}
end;
end;
Run Code Online (Sandbox Code Playgroud)
在一个应用程序中,第一次尝试执行此操作时,我一直在使用Append语句的行上获得I/O错误103异常(在调用此文件之前文件确实存在).此操作的所有后续尝试都将正常工作 - 直到我重新启动应用程序.
所有我发现这个错误的文档到目前为止表示,这将通过调用引起CloseFile
恕不另行Reset
或者Rewrite
(Append
通常没有提及),或者如果该文件是由另一个进程使用.由于异常发生在调用CloseFile
它之前显然不可能是前者.
我已经尝试Reset
在AssignFile
for good措施之后插入一个权利,但之后我在该行上获得了异常.
也没有其他应用程序直接访问该文件.我说的"阳谋",因为我有一个轻微的怀疑,防病毒(TrendMicro的在我的情况)可能是cuplrit这里(所以也许该文件是在使用中).如果这确实是问题,那么围绕它的最佳方法是什么?硬编码自动重试对我来说真的不是一个干净的解决方案......
在那里我有时会收到103错误另一种情况是这样的代码,我用它来创建一个空文件(或者更经常清空现有的文件):
AssignFile(lFile, AFileName);
try
Rewrite(lFile);
finally
CloseFile(lFile);
end;
Run Code Online (Sandbox Code Playgroud)
在这种情况下,重现起来要困难得多.它发生的次数要少得多.大多数情况下,这似乎是在我重新编译应用程序后的第一次运行时发生的.这可能再次成为反病毒的阻碍吗?我从未见过这种情况发生在我的开发机器上,从未得到过客户的报告.与第一个场景一样,每个应用程序会话只发生一次(如果有的话).后续尝试总是成功的.
有关创建空文件或清空现有文件的其他可能更安全的故障安全方法的建议吗?
我正在尝试以编程方式确定当前用户是否对给定的Active Directory对象具有某些权限(特别是在这种情况下,我正在尝试确定用户是否具有另一个Exchange用户或通讯组列表对象的"代理发送"权限).
我已经想通了如何访问ntSecurityDescriptor
使用ADSI属性:我可以在枚举的ACE IADsSecurityDescriptor
的DiscretionaryACL
财产.但:
FWIW,我使用ActiveDs.dll类型库在Delphi中编码(即本机Win32代码),因此特定于.NET的解决方案对我没有多大帮助,除非他们的源代码为我提供了如何在本机中执行相同操作的线索码.PowerShell也是如此.
在任何人开始之前:我已经知道了PR_EMS_AB_PUBLIC_DELEGATES
和PR_EMS_AB_PUBLIC_DELEGATES_BL_O
扩展的MAPI属性.但是,这不是我追求的.这些属性引用"代表发送"-right(又名委托),而不是"发送为"权限,这是完全不同的事情.
我还处于关于单元测试的学习阶段,特别是关于模拟(我正在使用PascalMock和DUnit框架).我现在偶然发现的一件事是,我找不到将测试类/接口的硬编码实现细节硬编码到我的单元测试中的方法,这只是感觉不对...
例如:我想测试一个实现非常简单的接口的类,用于读取和编写应用程序设置(基本上是名称/值对).呈现给消费者的界面完全不知道实际存储值的位置和方式(例如,注册表,INI文件,XML,数据库等).当然,访问层是由一个不同的类实现的,该类在构造时被注入到测试类中.我为这个访问层创建了一个模拟对象,现在我可以完全测试接口实现类,而无需实际读取或写入任何注册表/ INI文件/任何内容.
但是,为了确保模拟行为与被测试类访问时的真实行为完全相同,我的单元测试必须通过非常明确地定义预期的方法调用和测试类所期望的返回值来设置模拟对象.这意味着如果我必须更改访问层的接口或测试类使用该层的方式,我还必须更改内部使用该接口的类的单元测试,即使接口我实际上测试的类没有改变.这是我在使用模拟时必须要使用的东西,还是有更好的方法来设计避免这种情况的类依赖性?
delphi ×3
winapi ×2
windows ×2
add-in ×1
adsi ×1
algorithm ×1
crash ×1
debugging ×1
dunit ×1
enumeration ×1
exception ×1
file-io ×1
hook ×1
hwnd ×1
inno-setup ×1
list ×1
mocking ×1
oop ×1
outlook ×1
pascalmock ×1
permissions ×1
trac ×1
unit-testing ×1