I'm trying to write a C++ windows service that can render to a texture. I've got the code working as a regular console app, but when run as a service wglGetProcAddress()
returns NULL.
我正在尝试编写一个可以渲染到纹理的C ++窗口服务。我已经将代码作为常规控制台应用程序运行,但是当作为服务运行时,wglGetProcAddress()返回NULL。
Can anyone tell me if this is possible, and if so, what do I need to do to make OpenGL work inside a service process?
任何人都可以告诉我这是否可行,如果可以,我需要做些什么才能使OpenGL在服务流程中工作?
Edit:
I still haven't got this to work under Vista, but it does work under XP.
我仍然没有在Vista下工作,但它确实在XP下工作。
3 个解决方案
#1
Services run in non-interactive desktops. These desktops do not connect to the physical display device of the computer but rather to logical display devices. The logical display devices are very basic generic VGA devices set to 1024 X 768 with no bells and whistles.
服务在非交互式桌面中运行。这些桌面不连接到计算机的物理显示设备,而是连接到逻辑显示设备。逻辑显示设备是非常基本的通用VGA设备,设置为1024 X 768,没有铃声和口哨声。
Services can use most GDI functions but no advanced graphics functions such as DirectX or OpenGL. So you can create windows, create or retrieve device contexts and do some fairly complex drawing and rendering but you can't use anything but straightforward GDI (and some GDI+).
服务可以使用大多数GDI函数,但没有高级图形函数,如DirectX或OpenGL。因此,您可以创建窗口,创建或检索设备上下文并执行一些相当复杂的绘制和渲染,但除了简单的GDI(和一些GDI +)之外,您不能使用任何东西。
If you check GetLastError after wglGetProcAddress returns NULL you should get the reason for the failure.
如果在wglGetProcAddress返回NULL后检查GetLastError,则应该找到失败的原因。
#2
You can get a fully capable software renderer by using Mesa3D. Simply build Mesa3D and put the opengl32.dll built there alongside your application. This should enable you to use OpenGL 2.1 and extensions. We use this for testing Opengl applications in a Windows service.
您可以使用Mesa3D获得功能完备的软件渲染器。只需构建Mesa3D并将opengl32.dll与您的应用程序一起构建在那里。这应该使您能够使用OpenGL 2.1和扩展。我们使用它来测试Windows服务中的Opengl应用程序。
#3
OpenGL needs desktop access to create a render context and a service by default don't have desktop access.
OpenGL需要桌面访问才能创建渲染上下文,默认情况下服务没有桌面访问权限。
You need to run the service in interactive mode. To do that go in the service properties in Administrative Tools. Where you set the service's log on user, you will have an option to run the service in interactive mode, or something similar as "Allow service to interact with desktop". You can try logging the service as another user too.
您需要以交互方式运行该服务。要执行此操作,请转到“管理工具”中的服务属性。在您设置服务登录用户的位置,您可以选择以交互模式运行服务,或类似“允许服务与桌面交互”之类的操作。您也可以尝试将该服务记录为另一个用户。
If you are working through a .Net IIS application, you will also have to force the managed part of the server to log as another user.
如果您正在使用.Net IIS应用程序,则还必须强制服务器的托管部分以另一个用户身份登录。
EDIT:
I forgot to say, a user must currently be logged on the accelerated hardware desktop and the machine must not be locked. That sucks but that's the only way I made it work before. We had dirty script that logged a user on as soon as the machine started.
我忘了说,用户当前必须登录加速硬件桌面,并且不能锁定机器。这很糟糕,但这是我以前唯一的工作方式。我们有一个脏脚本,一旦机器启动就会记录用户。
As a side note, we were using DirectX, so it might not apply to OpenGL.
作为旁注,我们使用的是DirectX,因此它可能不适用于OpenGL。
#1
Services run in non-interactive desktops. These desktops do not connect to the physical display device of the computer but rather to logical display devices. The logical display devices are very basic generic VGA devices set to 1024 X 768 with no bells and whistles.
服务在非交互式桌面中运行。这些桌面不连接到计算机的物理显示设备,而是连接到逻辑显示设备。逻辑显示设备是非常基本的通用VGA设备,设置为1024 X 768,没有铃声和口哨声。
Services can use most GDI functions but no advanced graphics functions such as DirectX or OpenGL. So you can create windows, create or retrieve device contexts and do some fairly complex drawing and rendering but you can't use anything but straightforward GDI (and some GDI+).
服务可以使用大多数GDI函数,但没有高级图形函数,如DirectX或OpenGL。因此,您可以创建窗口,创建或检索设备上下文并执行一些相当复杂的绘制和渲染,但除了简单的GDI(和一些GDI +)之外,您不能使用任何东西。
If you check GetLastError after wglGetProcAddress returns NULL you should get the reason for the failure.
如果在wglGetProcAddress返回NULL后检查GetLastError,则应该找到失败的原因。
#2
You can get a fully capable software renderer by using Mesa3D. Simply build Mesa3D and put the opengl32.dll built there alongside your application. This should enable you to use OpenGL 2.1 and extensions. We use this for testing Opengl applications in a Windows service.
您可以使用Mesa3D获得功能完备的软件渲染器。只需构建Mesa3D并将opengl32.dll与您的应用程序一起构建在那里。这应该使您能够使用OpenGL 2.1和扩展。我们使用它来测试Windows服务中的Opengl应用程序。
#3
OpenGL needs desktop access to create a render context and a service by default don't have desktop access.
OpenGL需要桌面访问才能创建渲染上下文,默认情况下服务没有桌面访问权限。
You need to run the service in interactive mode. To do that go in the service properties in Administrative Tools. Where you set the service's log on user, you will have an option to run the service in interactive mode, or something similar as "Allow service to interact with desktop". You can try logging the service as another user too.
您需要以交互方式运行该服务。要执行此操作,请转到“管理工具”中的服务属性。在您设置服务登录用户的位置,您可以选择以交互模式运行服务,或类似“允许服务与桌面交互”之类的操作。您也可以尝试将该服务记录为另一个用户。
If you are working through a .Net IIS application, you will also have to force the managed part of the server to log as another user.
如果您正在使用.Net IIS应用程序,则还必须强制服务器的托管部分以另一个用户身份登录。
EDIT:
I forgot to say, a user must currently be logged on the accelerated hardware desktop and the machine must not be locked. That sucks but that's the only way I made it work before. We had dirty script that logged a user on as soon as the machine started.
我忘了说,用户当前必须登录加速硬件桌面,并且不能锁定机器。这很糟糕,但这是我以前唯一的工作方式。我们有一个脏脚本,一旦机器启动就会记录用户。
As a side note, we were using DirectX, so it might not apply to OpenGL.
作为旁注,我们使用的是DirectX,因此它可能不适用于OpenGL。