我正在开发一个包含不同组件的C ++项目。我们需要将应用程序作为Windows服务启动。该项目是非托管C ++代码。我写了一个C#windows服务,还有一个C风格的dll,它有一个启动不同组件的功能,另一个用来阻止它们。该DLL有两个文件,一个头文件和一个.cpp文件: RTSS.h:
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) 在RTSWS.RTSWinService.runRTS(String serviceName) 在D:\ work \ project \ ... \ RTSWinService.cs:第39行的RTSWS.RTSWinService.OnStart(String [] args)中
我已经在不同论坛的某些主题中读过Windows服务在C:\ WINDOWS \ System32中启动,并且由于初始化DirectoryInfo并打印其全名显示为真。我尝试使用Environment.CurrentDirectory =“Windows服务可执行文件和dll所在的目录”更改默认启动目录,但这不起作用。我也尝试更改Process目录,但也失败了。其他线索导致了这个结论link text,但它真的是这样吗?这可能更简单吗? 我应该注意,SetUnhandledException函数是用C ++而不是C编写的,因此我需要调用许多其他函数。所有需要的dll都放在服务可执行文件旁边。非常感谢您的反馈。
感谢。
答案 0 :(得分:2)
当某些东西在控制台上运行但不作为服务时,我会怀疑访问权限。确保服务正在运行的用户具有对d:\ work \ projects \ bin的读/执行访问权限。
另一个建议是调用SetDllDirectory,这是一种比直接使用当前目录更直接的方式来说明DLL的位置。请参阅pinvoke dll搜索路径中的this SO thread
您还可以使用SysInternal's ProcMon观看系统尝试并找到您的DLL。有时它不是DLL,而是你的DLL所依赖的DLL有问题,而ProcMon很适合发现这些问题。
答案 1 :(得分:1)
只是想更新这个帖子。 事实证明,问题是我的机器独有的。相同的代码集在不同的机器上工作,就像一个相同的Windows版本(Windows XP 32位,SP2)。在这两台机器上,Visual Studio 2008用于构建服务。 非常感谢所有评论和答案。我很感激。