Unable to get CeRapiInit or CeRapiInitEx to work

I am writing an MSI installer in C# application that installs multiple CAB files to a Windows Mobile device.  It does this by checking for various registry keys in the device, and then uses ActiveSync to install the needed CAB files one at a time.  This is all done in a DLL file with CustomInstaller.BeforeInstall.

I have the code for this completed, and I am trying to test it out.  I didn't make it very far!  When I make a call to CeRapiInit() it always fails.  The MSDN help says it should return S_OK (0) for success, E_FAIL (0x80004005) for a failure, E_INVALIDARG (0x80070057) for invalid arguments, or CERAPI_E_ALREADYINITIALIZED (0x8004101) if it is already initialized.  I got the values for these constants from a Google search.

I am always getting the value 2148007941 (0x80080005) back from this call.  What does this value mean?  What could be wrong?  When I check CeGetLastError and CeRapiGetError both return 0.  Also, Marshal.GetLastWin32Error() returns 183, however it does this BEFORE the CeRapiInit call also, so I don't think I'm actually getting an error there.

// Declaration is the following
public static extern uint CeRapiInit();

// It's being called in a procedure as:
uint iResult = CeRapiInit();

After trying this, I gave the CeRapiInitEx() method a try.  This gave the same result.

Also, when using Vista or Windows 7, and the Windows Mobile Device Center, this works fine.  This only fails on Windows XP or older using ActiveSync.  Other applications are able to use RAPI such as CeRegEdit.  I have reinstalled ActiveSync without success.

Lastly, this MUST work on Windows Mobile 4, 5, and 6.  I don't believe I can declare an IRapiSession interface.

Any help would be much appreciated!  
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

as you can see in Error Lookup, 0x80080005 means "Server execution failed"

check ActiveSync logs - they are located in %TEMP% folder with names like WCE*.* - they may tell you something

lastly, try running SDK samples (in C++, but I reckon you can run it under debugger, even if you don't know C++ :) ) - look for RAPI under Samples folder.
yadapaulAuthor Commented:
Thanks for the reply.  The WCE files listed in %TEMP% do not get updated when I run the MSI file.  There are a few 10053 and 10054 errors, but they are from a different timestamp.

I looked at the RAPI samples in C++ and I don't see any difference between their code and mine.  I ran the darn thing and CeRapiInit works.

I hate to try and do this in c++ as I'm not familiar with it at all.  Any idea's why c# may be different?

Is this your question?

Do everything exactly as it is explained here:

You know that not all device supports RAPI.

Here you will find C# and VB code:

I worked with RAPI only from C++. I hope it does not matter for this question.

CompTIA Cloud+

The CompTIA Cloud+ Basic training course will teach you about cloud concepts and models, data storage, networking, and network infrastructure.

It is C++, but, maybe, will help you
ok, what do CeGetLastError() and CeRapiGetError() return?
yadapaulAuthor Commented:
Yes, the link is my question.  I tried on a few Google groups and MSDN boards as well.  I have already followed the KB article.  The code there is in c++ which I am not using.

I do know that the device supports RAPI because I can use my exact code on Windows Vista and Windows 7 with Mobile Device Center installed, and it works.  This only fails on ActiveSync with WinXP.

I used the code in your third link and the WaitForSingleObject returns WAIT_FAILED.  The GetLastWin32Error returns 6 at this point.  I am currently trying to see that this means.  If this leads me to my solution I'll mark this answer.  Otherwise, do you know of anything else I can try?
out of interest, have you tried OpenNetCF COmmunication package?
Now you gave more information.
If your app works on Vista, you need to check the ActiveSync on XP. Firstly, what is version? Latest?
I hope your device is connected to this PC and you can browse for files.
If the answer for all these question is Yes, your application simply cannot find the system dll. Copy the app to folder with ActiveSync dlls and launch from there - just for test.
yadapaulAuthor Commented:
alexey: Both CeGetLastError() and CeRapiGetError() return 0.  This is in the first post.  I will look at OpenNetCF.  My company won't puchase anything ever, so hopefully there's a free version =).

pgnatyuk:  I do have the RAPI samples installed in c++ and they do work.  I'm just not able to get my own to work.

Here's exactly what is happening (line numbers added for reference):
   10   RAPIINIT rapiStructure = new RAPIINIT();
   20   rapiStructure.cbsize = 12;
   30   uint hResult = CeRapiInitEx(ref rapiStructure);
   40   int i = rapiStructure.heRapiInit.ToInt32();
   50    uint hWait = WaitForSingleObject((uint)i, 40000);

The structure is declared and the size is set.  I've also set the size to Marshal.SizeOf(rapiStructure).
After line 30, hResult = 0x80080005 and GetLastWin32Error = 183
After line 40, i = 0, and GetLastWin32Error = 1444
After line 50, hWait = WAIT_FAILURE and GetLastWin32Error = 6

CeRapiInitEx failed at first, so nothing works after it.
yadapaulAuthor Commented:
pgnatyuk:  This is not extra information, I had all of that in my original post.

ActiveSync is the latest version and has been reinstalled.  It's 4.5.0.  Yes, I can browse for files on it.  Other applications like CeRegApp work and talk to the device through ActiveSync.

I will copy the app files and post a result.
I remember such situation. I think, the problem was with the DLLs.
In the beginning of this article:

There is a simple program in the beginning. Can you check and say if it works on that computer?
yes, this is free AND has the whole source code :)

I guess you might have something wrongly defined in RAPIINIT struct, some alignment issues perhaps
CeGetLastError is 0, because the error is not with RAPI. The error is on your PC. So it makes sense to check GetLastError only.
This article contains C# code:

It helped me few months ago.
yadapaulAuthor Commented:
pgnatyuk: On the sample program above, I cannot use RAPI2.  Per MSDN Rapi2 is for use with Windows Mobile 5.0+.  My application needs to support version 4+.  However, like I mentioned above, I can run sample code in c++ and it does work.  I just didn't want to try and port everything to c++ (especially because I do not know it).

alexey: MSDN lists the structure as:
   typedef struct _RAPIINIT {
     DWORD cbSize;
     HANDLE heRapiInit;
     HRESULT hrRapiInit;

I have the following:
      public struct RAPIINIT
         public int cbsize;
         public uint heRapiInit;
         public uint hrRapiInit;

I have also tried IntPtr for heRapiInit because I saw it that way on one site.

I'll look at OpenNetCF as well.
OpenNETCF defines CeRapiInit as

[DllImport("rapi.dll", CharSet=CharSet.Unicode)]
internal static extern int CeRapiInit();

and it did work for me in few projects, XP et al.

your definition of RAPIINIT looks OK :)
yadapaulAuthor Commented:
OpenNetCF does not work either.  I built the DLL provided in your link and added it as a reference and to the using section of code.  Then I added the following lines:

   OpenNETCF.Desktop.Communication.RAPI rapi = new OpenNETCF.Desktop.Communication.RAPI();

The second line returns the exact same error I was gettin g with my code: 0x80080005.

I thought this might be my computer's problem, so I tried both methods on another XP machine and I got the same result on each.
You said that you have an example that works on these XP computers.
Try to modify their code. Check that it still works. Compare with your program. Take the code from this working sample as a base for your program.
yadapaulAuthor Commented:
The working example is a sample file in C++ that came with the Microsoft SDK.

My DLL is in C# so using that other example requires me to convert it to C++.  I will go that route if I have to, but in C# I have about 1000 lines of code and only one fails - the initialization call.  In C++ I have no clue, and porting all this code to that would take me a long time.

Again, I will go that route if nothing else works; I'm just hoping there's a solution in C#.
yadapaulAuthor Commented:

I pulled my code from the DLL file and created a new Windows Forms project.  It worked fine.  This explains why the C++ console application works.

It appears I cannot do this in a DLL file.  I don't know what the reason for this is.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Smartphone Programming

From novice to tech pro — start learning today.