我正在研究具有不同组件的C++项目。我们需要将应用程序作为Windows服务启动。该项目是非托管C++代码。我写了一个C#windows服务和一个C风格的dll,它有一个函数来启动不同的组件,另一个阻止它们。该DLL有两个文件,一个标题和一个.cpp文件: RTSS.h:从C#windows服务调用C++ dll(非托管代码)
namespace PFDS
{
extern "C" __declspec(dllexport) int runRTS(char*);
}
RTSS.cpp:
using namespace PFDS;
/* ... includes and declarations */
extern "C" __declspec(dllexport) int runRTS(char* service_name)
{
g_reserved_memory = (char*) malloc(sizeof(char) * RESERVED_MEMORY_SIZE);
_set_new_handler(memory_depletion_handler);
// this function is from a C++ .lib which is included in
// the linker input for the RTSS dll project setting.
// SetUnhandledExceptionHandler("RTS");
return 0;
}
在Windows服务的ServiceBase子类中,我有以下:
[DllImport("RTSSd.dll")]
public static extern int runRTS(string serviceName);
protected override void OnStart(string[] args)
{
try
{
// the bin directory has all dependencies (dlls needed)
Environment.CurrentDirectory = "D:/work/projects/bin";
eventLog1.WriteEntry("RTSWinService: Starting " + this.ServiceName);
int result = runRTS(this.ServiceName);
eventLog1.WriteEntry("Result of invoking runRTS = " + result);
}
catch (Exception e)
{
eventLog1.WriteEntry("Exception caught: " + e.ToString());
}
}
此外,我有一个控制台测试应用程序,主要类似于OnStart内的代码。当SetUnhandledException函数被注释时,应用程序和Windows服务都可以正常运行。但是,当我取消注释功能,在Windows控制台应用程序运行正常,但Windows服务输出以下异常:
System.DllNotFoundException:无法加载DLL“RTSSd.dll”:指定的模块找不到。 (来自HRESULT的异常:0x8007007E)D:\ work \ project \ ... \ RTSWinService.cs中的RTSWS.RTSWinService.OnStart(String [] args)上的RTSWS.RTSWinService.runRTS(String serviceName) 处的 :第39行
我已经在不同的论坛读过一些在C:\ WINDOWS \ System32中启动Windows服务的线程,而且它是真实的,因为初始化DirectoryInfo并打印其全名显示如此。我试图用Environment.CurrentDirectory =“更改默认的启动目录,”windows服务可执行文件和dll文件所在的目录“,但那不起作用。我也尝试更改Process目录,但也失败了。其他线索导致这个结论link text,但它是真的吗?它会更简单吗? 我应该注意到SetUnhandledException函数是用C++编写的,而不是C编写的,所以我需要调用很多其他函数。所有需要的dll都放在服务可执行文件的旁边。您的反馈非常感谢。
谢谢。
完整性检查:打开依赖关系的步行者,看看你的DLL依赖于什么,然后确保你的DLL和DLL依赖于你的路径上的某个地方。 – Shog9 2011-01-21 23:56:43
另外,您可以运行SysInternal的filemon来监视您的服务尝试加载的DLL。请记住,Windows服务运行在不同的用户会话(和桌面)中,因此它有自己的环境。并确保你的'd:'(或者你安装到的任何地方)实际上是一个真正的本地路径,而不是网络,也不是SUBST'ed(那里做过;-) – 2011-01-22 00:02:12