RAPI problems

  • Thread starter Jon Skeet [C# MVP]
  • Start date
J

Jon Skeet [C# MVP]

I'm trying a very simple program to test the OpenNETCF RAPI/registry
access. Here's the code:

using System;
using OpenNETCF.Desktop.Communication;

public class Test
{
static void Main()
{
using (RAPI rapi = new RAPI())
{
rapi.Connect();

RegistryKey reg = Registry.LocalMachine;

using (RegistryKey key = reg.OpenSubKey("Ident"))
{
string name = (string)key.GetValue("Name");
Console.WriteLine (name);
Console.WriteLine (name.Length);
}

rapi.Disconnect();
}
}
}

(I'm printing the length because I believe there's a bug in the
GetValue code - I suspect it'll return a string which includes a null
at the end.)


Unfortunately, I'm getting the following error:

Unhandled Exception: OpenNETCF.Desktop.Communication.RAPIException:
Unable to create ActiveSync object. Make sure ActiveSync is installed
The specified module could not be found.

Now ActiveSync is definitely installed and running.

A web search shows a couple of other people having the same problem,
but no answers. Any ideas, anyone?
 
J

Jon Skeet [C# MVP]

Jon Skeet said:
I'm trying a very simple program to test the OpenNETCF RAPI/registry
access. Here's the code:

<snip>

Fixed. You need [STAThread] to use RAPI, apparently.

Next problem I've got is that it's saying

<quote>
Unhandled Exception: OpenNETCF.Desktop.Communication.RAPIException: No
device present The specified module could not be found.
</quote>

However, I suspect that may be because I've got ActiveSync set up to
always attach as a guest, which for some reason means I can't even get
the normal ActiveSync window up. I'll try it after disabling that...
 
J

Jon Skeet [C# MVP]

Jon Skeet said:
Jon Skeet said:
I'm trying a very simple program to test the OpenNETCF RAPI/registry
access. Here's the code:

<snip>

Fixed. You need [STAThread] to use RAPI, apparently.

Next problem I've got is that it's saying

<quote>
Unhandled Exception: OpenNETCF.Desktop.Communication.RAPIException: No
device present The specified module could not be found.
</quote>

However, I suspect that may be because I've got ActiveSync set up to
always attach as a guest, which for some reason means I can't even get
the normal ActiveSync window up. I'll try it after disabling that...

Hmm... that wasn't the problem. There seems to be a significant bug in
RAPI.cs at the moment - at the start of Connect(bool), it checks
m_devicePresent, and throws an exception if it's false - but there's no
easy way (that I can see) of waiting until the device *is* present.

Just commenting out those lines, everything works (and the bug that I
suspected in the registry code is there).

I don't really like the idea of just commenting out the code for our
commercial app though - what's the status of the RAPI code? Is this a
known bug which is likely to be fixed in a more thorough way soon?

(Oh, and is there any reason why the finalizer does far more work than
Dispose in RAPI?)
 
C

Chris Tacke, eMVP

Jon,

First, thanks for the input - you've now probably tested it more than I
have, and I wrote it! :)

I've not had an [STAThread] problem, though I do know that the thread model
of ActiveSync itself changed in 3.7. Can you give me a bit more detail on
what you changed to fix it?

The registry stuff wasn't heavily tested - I just pulled the logic from the
device code, so if there were bugs there (and I beleieve there were), they
got copied. Again, send me the changes and I'll happily include them.

As for the Connect() method, that's how it was designed. Unless ActiveSync
has a connection (m_devicepresent == true), then CeRapiInit will hang or
fail. I'm up for architectural suggestions if you've got ideas on how to
better provide the behavior you're after. Am I right in thinking you want
to call Connect and then have it just block until the device is cradled?

As for the dtor v. Dispose, it's becasue originally the class didn't inherit
IDisposable and I just didn't move the code once it was. I agree that it
should be moved, though it shouldn't affect much as it is.


--
Chris Tacke, eMVP
Co-Founder and Advisory Board Member
www.OpenNETCF.org
---
Windows CE Product Manager
Applied Data Systems
www.applieddata.net


Jon Skeet said:
Jon Skeet said:
Jon Skeet said:
I'm trying a very simple program to test the OpenNETCF RAPI/registry
access. Here's the code:

<snip>

Fixed. You need [STAThread] to use RAPI, apparently.

Next problem I've got is that it's saying

<quote>
Unhandled Exception: OpenNETCF.Desktop.Communication.RAPIException: No
device present The specified module could not be found.
</quote>

However, I suspect that may be because I've got ActiveSync set up to
always attach as a guest, which for some reason means I can't even get
the normal ActiveSync window up. I'll try it after disabling that...

Hmm... that wasn't the problem. There seems to be a significant bug in
RAPI.cs at the moment - at the start of Connect(bool), it checks
m_devicePresent, and throws an exception if it's false - but there's no
easy way (that I can see) of waiting until the device *is* present.

Just commenting out those lines, everything works (and the bug that I
suspected in the registry code is there).

I don't really like the idea of just commenting out the code for our
commercial app though - what's the status of the RAPI code? Is this a
known bug which is likely to be fixed in a more thorough way soon?

(Oh, and is there any reason why the finalizer does far more work than
Dispose in RAPI?)
 
J

Jon Skeet [C# MVP]

Chris Tacke said:
First, thanks for the input - you've now probably tested it more than I
have, and I wrote it! :)

I've not had an [STAThread] problem, though I do know that the thread model
of ActiveSync itself changed in 3.7. Can you give me a bit more detail on
what you changed to fix it?

I just put [STAThread] at the top of my own code. No big deal - you
have to do that with plenty of other COM components. It was stupid of
me not to have it there to start with.
The registry stuff wasn't heavily tested - I just pulled the logic from the
device code, so if there were bugs there (and I beleieve there were), they
got copied. Again, send me the changes and I'll happily include them.

I think it's best just to copy the newer registry code from the device
- it seems to have those bugs sorted. It might also be a good idea to
rename the class to RapiRegistryKey or something similar, just to make
it clear what's being talked about and avoid collisions with
Microsoft.Win32.RegistryKey (which will often be used in the same
code).

Am I right in saying it should just be a case of copy the RAPI P/Invoke
declarations into the main framework's registry class, and then
renaming the class if you wish to? Let me know if it's more work than
that, and I'll see if I can help.
As for the Connect() method, that's how it was designed. Unless ActiveSync
has a connection (m_devicepresent == true), then CeRapiInit will hang or
fail. I'm up for architectural suggestions if you've got ideas on how to
better provide the behavior you're after. Am I right in thinking you want
to call Connect and then have it just block until the device is cradled?

Yup. Or at least, have something similar available. Of course, a
timeout would be nice, but I realise that's a lot more work :)

I was also somewhat concerned about thread-safety issues - you look
directly at various variables which are being manipulated in other
threads, without a lock in sight. It probably won't make any odds, but
I thought I'd raise it while we were talking about the whole issue.
It's probably the least important niggle I've got with it, and from
what I've seen it applies in quite a few places in the OpenNETCF
framework. Maybe sometime I should volunteer to overhaul the lot of it,
in terms of thread-safety...
As for the dtor v. Dispose, it's becasue originally the class didn't inherit
IDisposable and I just didn't move the code once it was. I agree that it
should be moved, though it shouldn't affect much as it is.

Righto.
 
J

Jon Skeet [C# MVP]

Jon Skeet said:
Yup. Or at least, have something similar available. Of course, a
timeout would be nice, but I realise that's a lot more work :)

Thinking about it, it needn't be that much work. If we basically kept
polling/sleeping to see whether or not the device was present, and
throw an exception if the device isn't present after we've polled/slept
for the time specified, it might be okay.

I know it's not generally a nice idea to poll, but it would be a simple
solution in this case, and the normal scaling worries don't really
apply when you're talking about RAPI in the first place, IMO.
 
P

Peter Foot [MVP]

Jon Skeet said:
I think it's best just to copy the newer registry code from the device
- it seems to have those bugs sorted. It might also be a good idea to
rename the class to RapiRegistryKey or something similar, just to make
it clear what's being talked about and avoid collisions with
Microsoft.Win32.RegistryKey (which will often be used in the same
code).

Am I right in saying it should just be a case of copy the RAPI P/Invoke
declarations into the main framework's registry class, and then
renaming the class if you wish to? Let me know if it's more work than
that, and I'll see if I can help.

We did a number of updates to the device side registry code prior to the SDF
release, unfortunately I didn't duplicate these changes across in the
Communication library. It should be fairly straight-forward to compare both
sets of code and copy across the changes. The logic should be exactly the
same, only the P/Invokes are platform specific. I agree on the naming issue
too, I'll copy across the code shortly and it'll appear in the next
source/binary drop.

Peter
 
D

Dick Grier

Hi Jon,
I know it's not generally a nice idea to poll, but it would be a simple
solution in this case
<<

I think polling is a "standard solution" to this sort of problem. I do it
all the time, with a variety of communications mechanisms. It often
(perhaps even, usually) is the only solution, not just a possible solution.

Dick

--
Richard Grier (Microsoft Visual Basic MVP)

See www.hardandsoftware.net for contact information.

Author of Visual Basic Programmer's Guide to Serial Communications, 3rd
Edition ISBN 1-890422-27-4 (391 pages) published February 2002.
 
C

Chris Tacke, eMVP

I'll get to work on all but the Registry stuff (looks like Peter's on that).
I'll add both a timeout and a cancel.

--
Chris Tacke, eMVP
Co-Founder and Advisory Board Member
www.OpenNETCF.org
---
Windows CE Product Manager
Applied Data Systems
www.applieddata.net
 
J

Jon Skeet [C# MVP]

Dick Grier said:
I know it's not generally a nice idea to poll, but it would be a simple
solution in this case
<<

I think polling is a "standard solution" to this sort of problem. I do it
all the time, with a variety of communications mechanisms. It often
(perhaps even, usually) is the only solution, not just a possible solution.

In this case there's a nicer solution, but it's a bit more complicated.
We're basically waiting for an event to occur - so we could wait on a
monitor (or ManualResetEvent or whatever) having subscribed to that
event. No polling required - just more code :(
 
J

Jon Skeet [C# MVP]

Chris Tacke said:
I'll get to work on all but the Registry stuff (looks like Peter's on that).
I'll add both a timeout and a cancel.

Star. Let me know if you want a hand with it at all. It's about time I
started contributing back :)
 
J

Jon Skeet [C# MVP]

Chris Tacke said:
Obviously it's not happening before next week, with the Summit and all.

Ah, lucky people who can go to the summit. Darn Microsoft for having
placed it right by Easter...
 
P

Paul G. Tobey [eMVP]

OK, Jon,

All of the questions for the next week are yours! ;-)

Paul T.
 
P

Paul [Paradise Solutions]

May I add a question to this thread?

Since switching from 2.4 to 2.6 of the communication DLL (also tested in
conjunction with the RAPI sample project), I've noticed that if you
remove the device from the cradle and then redock, RAPI.Connect() fails
because it thinks there is no device attached, with the resulting
exception info:


************** Exception Text **************
OpenNETCF.Desktop.Communication.RAPIException: No device present Control
ID not found.

at OpenNETCF.Desktop.Communication.RAPI.Connect(Boolean WaitForInit)
at OpenNETCF.Desktop.Communication.RAPI.Connect()
at RAPIVB.Form1.btnConnect_Click(Object sender, EventArgs e) in
C:\Documents and Settings\peden\My Documents\Visual Studio Projects\RAPI
Sample\Form1.vb:line 133
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons
button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32
msg, IntPtr wparam, IntPtr lparam)


************** Loaded Assemblies **************
mscorlib
Assembly Version: 1.0.5000.0
Win32 Version: 1.1.4322.573
CodeBase:
file:///c:/windows/microsoft.net/framework/v1.1.4322/mscorlib.dll
----------------------------------------
RAPIVB
Assembly Version: 1.0.1502.31682
Win32 Version: 1.0.1502.31682
CodeBase:
file:///C:/Documents%20and%20Settings/peden/My%20Documents/Visual%20Studio%20Projects/RAPI%20Sample/bin/RAPIVB.exe
----------------------------------------
System.Windows.Forms
Assembly Version: 1.0.5000.0
Win32 Version: 1.1.4322.573
CodeBase:
file:///c:/windows/assembly/gac/system.windows.forms/1.0.5000.0__b77a5c561934e089/system.windows.forms.dll
----------------------------------------
System
Assembly Version: 1.0.5000.0
Win32 Version: 1.1.4322.573
CodeBase:
file:///c:/windows/assembly/gac/system/1.0.5000.0__b77a5c561934e089/system.dll
----------------------------------------
OpenNETCF.Desktop.Communication
Assembly Version: 2.6.1544.25757
Win32 Version: 2.6.1544.25757
CodeBase:
file:///C:/Documents%20and%20Settings/peden/My%20Documents/Visual%20Studio%20Projects/RAPI%20Sample/bin/OpenNETCF.Desktop.Communication.DLL
----------------------------------------
System.Drawing
Assembly Version: 1.0.5000.0
Win32 Version: 1.1.4322.573
CodeBase:
file:///c:/windows/assembly/gac/system.drawing/1.0.5000.0__b03f5f7f11d50a3a/system.drawing.dll
----------------------------------------
System.Xml
Assembly Version: 1.0.5000.0
Win32 Version: 1.1.4322.573
CodeBase:
file:///c:/windows/assembly/gac/system.xml/1.0.5000.0__b77a5c561934e089/system.xml.dll
----------------------------------------
Microsoft.VisualBasic
Assembly Version: 7.0.5000.0
Win32 Version: 7.10.3052.4
CodeBase:
file:///c:/windows/assembly/gac/microsoft.visualbasic/7.0.5000.0__b03f5f7f11d50a3a/microsoft.visualbasic.dll
----------------------------------------


Having skimmed ofer the last few post in the RAPI issue mentioned here,
could you confirm if the two problems are linked?


Many thanks


Paul
 
P

Paul [Paradise Solutions]

Appologies... the events below are not in relation to RAPI.Connect(),
just undocking/redocking.

RAPI.Connect() does fail if you fire RAPI.Disconnect() and then
RAPI.Connect() again (without removing PDA from cradle)



Paul
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top