We have a windows service (written in C#) that uses a 3rd party DLL to communicate with a COM printer.
Already tested the windows service in 4 local machines, and in every case the printer works correctly.
We also have this windows service already deployed in production in several clients and it also works correctly, but now we where deploying it to a new client and in every test we make the DLL is unable to open the COM port (already checked to see if it's in use by another application and nothing).
But the strangest thing is that if we launch the service .exe from command line it works correctly, so we tried launching the service as the user connected to the machine (instead of Local System) and even so it doesn't work.
What can be causing this? Is there any way, either by Windows configuration or by some software, to prevent Windows Service to communicate with the COM port? Or is there any other explanation?
Sorry to all of you that came here looking for a solution to your problem, but my solution was to change the 3rd party DLL.
Related
Background:
I'm developing an windows service and using the registry to get the parameters (using the key Parameters below the service entry).
Delphi is installed as an AppWave app (long story I cannot tell here) and therefore when debugging it goes to an virtualized copy [1] instead of the real deal [2].
I detected that after going logging registry activity of the service using
Process Monitor. If I run the service outside Delphi, the application
access the real key normally.
Question: there's some way to circunvent Streaming Core and debug the app
accessing the real registry key?
Note to mods: since there's no AppWave tag, I could not include it - I tried.
Virtualized copy: HKEY_LOCAL_MACHINE\software\Embarcadero\StreamingCore\Profiles\fabricio\Applications\{<<GUID>>}\Virtualization\Keys\whklm\SYSTEM\CurrentControlSet\services\[service]\Parameters]
Real deal: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\[service]\Parameters
The whole point of AppWave to is sandbox and virtualize applications. So no, AFAIK your service cannot bypass AppWave's Registry virtualization while running inside of the sandbox.
I've never used AppWave myself, but assuming it allows network connections, you may have to resort to using the IDE's remote debugger. Run the service outside of the sandbox, and then have the IDE connect to the remote debugger, which can then debug the service process.
I didn't found an way. The remote debugger approach - suggested by Remy's answer - when used on the same machine ended affected by the StreamingCore service.
So the approach used is logging to do the debugging. For that, used CodeSite Express (which is very handy and included in Delphi) to do the logging.
I have a Linux system with:
a daemon that communicate with another device via RS232 port.
a php + javascript web site that talks to the daemon through a
socket.
Now the boss wants to find out how much of an effort is required to port all these onto Windowze.
Having never really programmed on Windows before, I'd like to ask how easy/hard this is going to be and what the options are.
Thanks,
PHP will probably run as is. Javascript runs in the web browser, and will run as is. Your daemon is a service on windows. Apparently it listens on a socket for commands from the web page via javascript.
You did not state what language you are targeting for the service. Some languages such as C# dot Net, have built-in libraries for making clean services that can pause, stop, start, and interact with the Windows Service Control system. C# would be a good choice to make a service that can install and remove itself easily, and it supports nice high level socket control to listen to the PHP and javascript code. I have used perl, C#, C++, and even Visual Basic running as a service, so the choice is yours.
If your choice of Windows language is that compiles to some .EXE, then a low-level way to add a service is as follows. You will need INSTSRV.exe and SRVANY.EXE, which come on the Windows Resource Kit, or can be downloaded easily with a quick web search.
The short version :
After you get the server runnign when you are logged in and debugged, install the APP server as normal to the C:\Program Files\APP directory. This would be the app that connects to the serial port and does what you want via sockets.
Copy instsrv.exe to your C:\WINDOWS\system32 directory/
Copy SRVANY.EXE to C:\Program Files\YOURAPP
From command prompt, run this command – INSTSRV YOURAPP "C:\Program Files\YOURAPP\srvany.exe"
Run the Registry Editor (REGEDT.EXE)
Under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\YOURAPP: create a ‘Parameters‘ key (folder)
Under the this key, create a REG_SZ string value called Application and add in this data C:\Program Files\YOURAPP\YOURAPP.exe
Close Regedit, then open the services console in administrative tools, or start, run, services.msc, confirm it is set to start automatically and the logon account is LocalSystem. Then unclick the Allow Service to Interact with Desktop. If you click this, it will interrupt you on Windows 7 boxes whenever it writes to the screen.
Start the service, check in Task Manager, you will see YOURAPP.exe inthere, and if you stop the service then YOURAPP.exe will disappear.
The long version
Details on this are at http://support.microsoft.com/kb/137890
this question has been asked before but there is no conclusive answer.
I've written a Windows service in Delphi, which needs to generate a beep under certain condition. This works fine on XP, however fails in Windows 7 or 2008.
Note:
Beep can work if i create a console program instead of a service - using PC speakers.
Beep cannot work in a service even if i enable "allow service to interact with desktop" or even assign administrator rights to the service.
My question: Is there a way I can call beep API such that it works in a service? Thanks.
You can't do this in Vista and up. Services run in a different session and so don't have access to the speaker.
Update: Someone found a way here. it involves IOCTL, and is available to drivers and services.
Original answer:
The only way I know of to interact with the user would be to have your Service communicate with a small user-agent process which would be added to HKEY_LOCAL_MACHINE\CurrentUser\Run to autorun.
This is the usual pattern in vista and win7 where no user interaction is possible directly from the service:
MyLittleService.exe has no access to the user. But it can communicate via a named pipe with a tray icon utility.
MyLittleTrayIcon.exe communicates to the service, and can also be told to signal the user with message boxes, beep via whatever method (windows sound effects probably would be better than trying to access the PC speaker which is not guaranteed to exist on every PC anymore), etc, and maybe even can be used to control the service (restart it, reload the configuration etc).
We have a WCF service that generates an Excel file off of a template and feeds it back to the client in a byte array. For some reason, we are getting an error when we try to do this:
sheet.PageSetup.CenterHeader = sheet.PageSetup.CenterHeader.Replace("[customerName]", customerName).Replace("[dateTime]", date.ToShortDateString());
When it hits this line, we get this error message:
No printers are installed. To install a printer:
In Microsoft Windows 2000, click Start, point to Settings, and then click Printers. Double-click Add Printer.
In Microsoft Windows XP, click Start, and then click Printers and Faxes. Under Printer Tasks, click Add a printer.
Follow the instructions in the wizard.
The service runs under the LocalSystem account. When we first deployed this service, it was to an x64 machine and had the same issue. Our dev environment is x86 so we moved the service to another server that was x86 and it worked fine for a while. It recently stopped working and is now giving us this error message again. I am pretty sure it was becuase of a mass windows update that was done on the app server recently.
Funny thing is, I tried changing the service to "allow interaction with the desktop" and it didn't work, but when our sysadmin did that same thing, it worked for one file generation but is not working now.
There are printers installed on the machine, both on domain accounts and local accounts. I've also tried running the service under a different account, but then I wasn't able to connect to the service due to some SSPI error. We tried using the Network Service account but then the app couldn't see the service at all. We've restarted the service after each change also to no avail.
What I do know about the "PageSetup" part of the sheet object is that it needs to have a printer installed to access it at all, even if you aren't printing. I was unable to figure out a way to trick the machine into thinking the LocalSystem account has a printer installed.
We figured out the problem, I had my config file still pointed at the x64 server :(
As to why it won't work on x64 (to my knowledge) - since office 2003 is x86, it needs an x86 print spooler in order to work correctly. I don't know of any way to get an x86 print spooler on an x64 OS so we just stuck it on the x86 server.
I have created the necessary manifests for my COM server DLL and a client application to work registration-free in Windows XP. I've tested all kinds of combinations (with and without a registration) and in all cases the client application sees the side-by-side version of the library if the manifests are present, and the registered one if not (or a COM error if there is no registration at all). I've tested on my Windows XP development machine, and given the files (DLL, client EXE and one manifest for each) to co-workers, who've also run everything successfully on their own Windows XP machines. The manifests are external XML files, not embedded resources. So far, so good.
However, when I copy the files to a Windows Server 2003 machine, it doesn't work. I get a silent failure, but an application error in the Application Event Log (see below). If I unregister the DLL and remove the manifests, I get a similar error (silent at the command prompt, but an application error in the event log). Obviously there is some problem finding the registration. I have reproduced this on every Windows Server 2003 machine I can access at our company. According to the Microsoft documentation on side-by-side/registration-free COM, it's supposed to work on Windows XP and later, and Windows Server 2003 and later.
To be clear, the same client runs perfectly on those same Windows Server 2003 machines against a registered (i.e., using regsvr32) version of the same COM DLL, under the same login credentials I'm trying to use for registration-free COM. In other words, there are no intrinsic issues masquerading as registration-free COM problems - this client and server operate fine when the server is registered globally in the registry.
Anybody have any ideas of how to investigate further? I'm not an expert on Windows Server, but is there perhaps some policy setting that would need to be changed to enable this support? If I can locate the necessary change, our tech support/infrastructure people will probably have no probably doing it, but I can't rely on them to research the issue too as they are swamped.
In case it matters (I don't think it should, but you never know) the DLL is written in Delphi 2007, while the client is written in Visual C++.
Event Type: Information
Event Source: Application Error
Event Category: (100)
Event ID: 1004
Date: 5/2/2009
Time: 8:07:45 AM
User: N/A
Computer: ***server name****
Description:
Reporting queued error: faulting application ***program name***.exe, version 0.0.0.0, faulting module ***program name***.exe, version 0.0.0.0, fault address 0x0002ac9e.
For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.
One thing to look for is that whether the exe has an internal manifest. In XP, the exe manifest search order is external then internal. In Server 2003 and later, the order is internal then external.
With a COM server created in Delphi 7, I have seen similar problems if the COM server was unregistered and the client application started under a restricted user account, because Delphi's COM implementation always tried to update the registration information, even when the DLL's RegisterServer function was not explicitly called.
To see whether this is a problem, attempt to run the client application on an account with unrestricted administrative privileges.
MSDN mentions, that under Windows 2003, problems with registration free COM servers should be detailed in a specific section of the system event log:
When troubleshooting registration-free
COM issues, the Event Viewer on
Windows Server 2003 is your friend.
When Windows XP or Windows Server 2003
detects a configuration error it will
typically show an error message box
titled for the application you have
launched and containing the message
"This application has failed to start
because the application configuration
is incorrect. Reinstalling the
application may fix this problem." I
advise that whenever you see this
message you reproduce the problem on
Windows Server 2003, consult the
System Event Log and look for events
from the SideBySide source. The reason
I don't suggest that you look at the
Windows XP Event Log in these cases is
that it will invariably contain a
message such as "Generate Activation
Context failed for [path][application
filename].Manifest. Reference error
message: The operation completed
successfully," which doesn't help
identify the problem.
http://msdn.microsoft.com/en-us/library/ms973913.aspx#rfacomwalk_topic6
Also, if possible, tell us the file names and contents of the manifest files you use.