Windows Xp Service Pack 3 32-bit

0 views
Skip to first unread message

Vickiana Sconyers

unread,
Aug 4, 2024, 11:57:06 AM8/4/24
to icemdeadsemb
I have a windows service. In the Properties I have the platform target set as X64. In my csproj file I have changed all instances of prefer32bit to false. I am installing the service with installutil.exe when I install and run my service it runs as 32 bit. I am currently building in debug mode. What am I missing here?
I had this issue when a previous version of the service had been 32 bit. I knew the currently installed one wasn't (checked CORFLAGS), but the process associated with the service was being created as 32 bit anyway, and for the life of me I couldn't work out why.
To get around this problem, please run installutil.exe outside of the appropriate Framework/Framework64 directory. If you have a snap-in built for ILONLY (ILONLY indicates that the executable contains pure IL code and can run either as 32-bit or as a 64-bit process), but want to register it under the wow64 hive, use installutil.exe that is available in the directory %windir%\microsoft.net\framework\v2.n.n.n. For the 64-bit hive registration, run installutil.exe from the directory %windir%\microsoft.net\framework64\v2.n.n.n.
We do have third party tools as well as reference a c++ managed assembly. These may or may not be built for any CPU. In fact i know that the c++ managed assembly is only built for x86. However, the odd things is that if I specifically specify x64 the process will start up and work in x64. If the framework were to attempt to load the c++ managed assembly it would fail. I don't mind this, because in the code, we do not load the 32bit managed ++ assembly if we're running in 64 bit mode. Could it be that the build figures that since there is a 32 bit assembly in here it should mark the launching process (in this case a windows service assembly) as x86?
In case anybody runs across the same thing I did: I had created two new config settings (copied from the Debug config). For some reason "Prefer32Bit" flag was set to true, even though the checkbox was greyed out and unchecked in the project config page.
Though I didn't find such utility in .Net v4 folder, the setting applies to Net4 AnyCPU assemblies as well. This flag is saved in DWORD registry value Enable64Bit under the key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework
I often use a starter application, where I explicitly compile the .exe as x64 or x86 and ship x86 and x86 versions of the .msi. This is probably the easiest route - The performance gain is generally worth the overhead of managing additional files.
I built theapplication and it runs fine in the Visual Studio web server, but itdidn't work in IIS -- it seemed that the threads I launched to processthe engine events would die after a short while. I rewrote theapplication to put the TS Engine into a Windows Service. This worksfine in WinXP (32-bit). The service works in Visual Studio'sWfcSvcHost (a test client) on Windows 2K3 (64-bit), but doesn't workwhen installed as a Windows Service in 2K3 (64-bit). The TestStandengine code just hangs at the constructor for the TS Engine ... itdoesn't crash, no exceptions are thrown, and if I stop it with thedebugger, the thread is in the constructor.
I'm not sure about the service problem, but if it's possible to create your own threads in IIS you might be able to workaround the problem you were seeing there by creating your own thread that then creates the teststand engine, that way you can control the lifetime of the thread.
Also, the TestStand engine expects the thread that creates it to be the one that will process window messages for dispatching UIMessages, so for things to work correctly you will need a message loop running in that thread at some point after creating the engine.
How does one control the lifetime of threads in IIS? When I tried in IIS my threads were dying unpredictably and I decided that maybe this was a normal behaviour for a web server .. who would normally want processes to outlive the duration of a request? (I say ironically, because I do!)
With regards to your second comment, I discovered this also. Though what I find weird is that the engine only seems to run during my calls to execution.WaitForEnd(...) ... I couldn't find any other method that tells the engine to do work. So I wind up calling WaitForEnd(....) on executions I know to be already complete (when I have no active executions) in order to "run" the engine. Is there so other method I'm missing?
I don't really know anything about IIS so I'm not really sure what is best, but if you keep running code in a IIS thread and never return from it until your application is done then the thread will likely be around at least as long as your code is running. The code you should be running is likely a message loop, which is related to the other issue you are asking about, about the engine running.
The other issue you are asking about, about the engine running, is that you need to have a message loop in your main thread (the one that creates the engine) in order for the UIMessages to be processed (i.e. for the engine to run). Typically, programs which display windows have code which does this for you whenever your application is idle. If your program does not really have a UI, then you might need to implement the message loop yourself. In C a Windows message loop looks something like the following:
Ideally, the thread that creates the engine should be doing Window message processing whenever it is idle until the application exits (Typically until a WM_QUIT message is sent at which point GetMessage will return FALSE thus exiting the loop, or you can create your own mechanism for telling the main thread when to exit the loop).
Thanks. Though of course this doesn't solve my win2k3x64 problem, it does make my message pumping much cleaner. I used your advice to generate the code below. It isn't a loop itself, but I already had a loop -- just no mechanism to pump windows messages. Now I do! (Thanks again!)
Glad the message processing information was useful. I think to fix the issues you have with doing things from a server you need to create and own the thread that you create the teststand engine in and have a message processing loop in that thread (it will also be the thread than the UIMessage event callback is called in). That thread should just never return until you are done with the teststand engine (you can use some sort of inter-thread communication to tell it when to exit). I'm really not sure what you are currently doing though. Perhaps if you explain it in more detail, like what threads exist, how your code is being run, how the engine is being shared between threads, etc. I might be able to suggest a better solution.
My problem is WCF in Windows Service on Win 2K3-64... my thread just disappears into the constructor for the Engine ... never comes back. If I hadn't seen so many cases where it does work (on 2K3-64) I'd just let it go.
One thing that might be a factor is that on newer versions of Windows (at least on Vista so maybe they also do this on Windows server) it is no longer possible to run a service as interactive (i.e. an interactive service is one that displays windows). I think they do this for security reasons. Perhaps a messagebox is being displayed, but can't be shown because it is in the process of the service?
Thank you for this great help. I first searched google for currentworkingdirectory, path, application directory, etc. and didn't get much help. I'm including those search terms here so others can land here as well.
If you want to get the executing directory, you can still use : string currentDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase);
I use the Phil's method to set it back to the process.
Just wanted to personally thank you for this information. I was incurring the dreaded Error: 1054 due to my application calling settings out of a conf file. Little did I realize, my application was trying to fetch this file from within the system32 folder, not the folder local to the service executable itself! At any rate, this simple one-liner addressed my startup issue, thank you kindly!
On a related note, for a ASP.net web API (at least in 4.7.2, which is where I ran into this) the default current directory when debugging is C:\Program Files\IIS Express, this solution seems to help in the web world as well as the windows service world.
We've written quite a few of those Delphi 32-bits services ourselves, and the only thing that actually helps us "debug" the services running on servers (64-bit included) without the source code is Sysinternal's (now Microsoft Technet) Process Monitor.
In your specific case, I'd download Process Monitor (it's a simple executable) and run it and then set it up to filter only your service's .exe application. Look around for it's docs, but this is actually a very simple filter.
Keep Process Monitor running (filtered) on both machines while you start the service. Compare results from Process Monitor. I bet you have something like a missing registry key, or a missing directory or permission which causes the Delphi app to raise and Exception. This should be easy to spot on Process Monitor. Even more if you have a working machine to compare to.
I had the same problem, but Ricardo Pardini's hint with Process Monitor was the solution, I found out that the service (even at the time of just installing it) was looking for a dbExpress DLL which was not in the application directory nor in the search path. Copying the DLLs into the same folder resolved the problem.
If it's just a POS (Plain Old Service ;) ) you can follow the instructions here to manually install it as a service. That way you will get around a failing install routine if the application itself works.
It's probably trying to read something from the 64 bit version of windows rather than the 32 bit version of windows. Make sure that you have the 32 bit sql server client installed and functioning properly. Other than that post the appcrash which should tell you which DLL to put in wow32.
3a8082e126
Reply all
Reply to author
Forward
0 new messages