Computer A (client) x86
Computer B (server) x64
The x86 client app copies an x64 executable image to C:\Windows\System32 on
the x64 remote machine. The x86 client then calls CreateService() to create
a service on the x64 remote machine. The client then tells the service to
The problem is that the service gets created with a registry value called
When the client issues the start command, the service won't start saying
"File not Found". I assume it's looking in SysWOW64?
There's a similar question here:
How can I solve this?
The reason I want this, is because we have thousands of computers, some are
x86 and some are x64. Client apps MUST be x86 so they can run on either
architecture, but servers and services should be able to target the correct
architecture and run native.
> The problem is that the service gets created with a registry value called
> When the client issues the start command, the service won't start saying
> "File not Found". I assume it's looking in SysWOW64?
Furher testing. If I delete the WOW64 registry value, the service can now
start and stop
Obviously having to delete a registry value every time my app runs would not
be an elegant solution.
I can reproduce the problem. You are right that it is the x86 version of
CreateService and the wow64 redirection that is in play. I'm looking for
other workarounds of the issue and will get back to you as soon as
Jialiang Ge (jia...@online.microsoft.com, remove 'online.')
Microsoft Online Community Support
Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
This posting is provided "AS IS" with no warranties, and confers no rights.
Thank you for testing and confirming this problem. I look forward to how I
can solve it.
""Jialiang Ge [MSFT]"" <jia...@online.microsoft.com> wrote in message
It requires that CreateService is run in the x64 process to properly
install a x64 service. It might be easiest to copy an x64 bootstrapper EXE
over to the remote machine and have it do all the work using psexec
If you have any questions or concerns about this solution, please feel free
to tell me.
> It requires that CreateService is run in the x64 process to properly
> install a x64 service.
But CreateService() has an option for remote machines which means it could
be x86 client and x64 server. It is not properly addressing the need. I
think we need a CreateServiceEx() that can set flags for x86 / x64. This
kind of problem will discourage people moving to x64.
> It might be easiest to copy an x64 bootstrapper EXE
> over to the remote machine and have it do all the work using psexec
I'm trying to avoid PsExec, but anyway I think it works the same way, it
creates a service on the remote machine, but probably runs it as WOW64.
If I delete the WOW64 registry key from the service, it seems to work, but
is this safe?
Thanks for the help with this.
Speaking honestly, creating services remotely is just not that common of an
>If I delete the WOW64 registry key from the service, it seems to work, but
>is this safe?
Think about it intuitively. Once you delete that entry, the registry key
looks exactly like a service created natively. How could there possibly be
any difference in execution?
Tim Roberts, ti...@probo.com
Providenza & Boekelheide, Inc.
> Speaking honestly, creating services remotely is just not that common of an
The point is, the Windows API has a CreateService() function - it seems
this function has not been updated correctly to target x64 platforms.
There are probably _many_ API calls that are not used very much, it
doesn't mean it's OK to leave them broken.
>> If I delete the WOW64 registry key from the service, it seems to work, but
>> is this safe?
> Think about it intuitively. Once you delete that entry, the registry key
> looks exactly like a service created natively. How could there possibly be
> any difference in execution?
This is also my understanding of it, but I wanted to make sure; for
example it could leave me with an "unsupported" configuration. Obviously
I want all my code to be fully supported.
Gerry Hickman (London UK)
>This is also my understanding of it, but I wanted to make sure; for
>example it could leave me with an "unsupported" configuration.
> Obviously I want all my code to be fully supported.
I will help to confirm it with the product group.
>I'm trying to avoid PsExec, but anyway I think it works the same way, it
>creates a service on the remote machine, but probably runs it as WOW64.
Based on my tests of psexec:
Client pc: x86
Server pc: x64
When I run "psexec \\server-pc target.exe" from the client pc, the
installed psexesvc service runs in 32bit. This corresponds to the finding
in this thread. It's very likely that psexec uses the same code logic as
yours to install the psexesvc service on the remote computer. Next, the
psexesvc service starts the target exe. The target exe can always be
started in the right bitness, i.e. if the exe is 64bit, the exe will be run
in 64bit, otherwise, it's run in Wow64. You can imagine the target exe as
our 64bit bootstrapper exe. The bootstrapper runs in 64bit, thus it can
further install your 64bit service rightly.
Let's imagine we are writing the "next generation" version of PsExec. We
want it to be able to start it's remote service in the correct bitness.
We can't use an x64 bootstapper exe until we've started the x86 remote
service for the first time - catch 22!
The big issue here is that any v6.1 SDK API call that targets a remote
system should take it's bitness into account. I don't believe
CreateService() does this.
Yes, I could start the remote service as x86 and then launch an x64 bit
process, but this is stone age, that's why I was looking for a better
solution. I'm trying to move everything to x64 except very minimal
clients that must run x-platform.
It's a bit strange anyway, that it sets this WOW64 registry key, it
assumes the service we are about to start is x86.
If we look at COM/DCOM and WMI, Microsoft did a lot of work to ensure
clients and servers can be of different bitness. We even have flags to
over-ride the default behavior, it seems the WinAPI is not so clever.
Anyway, I guess it's never going to be fixed so I'll have to think of
something else. It will be interesting to see how PsExec develops in
regard to this. Part of the reason I started this project, was that I
believe PsExec has drifted into no man's land. I posted many bug
reports, but it wasn't going anywhere...
With more tests, I realize that the WOW64=1 registry value is added only
when the client process is a wow64 process (x86 binary running on x64), not
if it is running in x86 machine. So an easy solution may be to compile the
client exe to target x64 platform instead of x86. Another solution is to,
in the client exe, detect whether it is running in wow64 using
IsWow64Process. If it is, start an x64 equivalent exe to install the
> With more tests, I realize that the WOW64=1 registry value is added only
> when the client process is a wow64 process (x86 binary running on x64), not
> if it is running in x86 machine.
Ah OK. That is interesting.
> So an easy solution may be to compile the
> client exe to target x64 platform instead of x86.
This won't work, because I need the client to be able to run on machines
with x86 and x64 o/s.
> Another solution is to,
> in the client exe, detect whether it is running in wow64 using
Yes, this might be needed anyway.
> If it is, start an x64 equivalent exe to install the
Do you mean on the client using CreateProcess() ?
Yes, this might work using a combination of IsWow64Process and starting
a new x64 process when we are running x64 client.
1. Launch x86 client EXE
2. Detect if we are running WOW64
3. If WOW64, launch new x64 client EXE (terminate old x86 client EXE)
4. Detect bitness of target o/s
5. Create service using correct image file for x86/x64
You have given me some good ideas! I'm testing a domain migration this
week, but I will test this when I next get some development time.