Related
Hi there.
I'm learning how to write programs for my mobile, and at the moment, I'm working on an app which will generate a playlist for TCPMP and then launch TCPMP.
I've got right to the last bit, but now I can't find out how to execute the app.
I'm assuming that you do something like
system.shell("\path\to\app.exe")
But I can't find the system.shell (or equiv.) to run.
Can anyone point me in the right direction?
Thanks
Jon "The Nice Guy"
JonTheNiceGuy: with such a question, you really need to specify language, development environment (ideally) and target OSi.
I'm a c++ man, for which I'd createprocess or shellexecute.
V
Oops! Stupid of me. VB.net
In the Compact Framework system.diagnostics.process allows you to start an application and provide arguments for it
I've just tried to add the following code (each without success)
Dim process as system.diagnostics.process
Dim process as New System.Diagnostics.Process
Is this right? All I seem to have under system.diagnostics is stuff to do with tracing and debugging, not to start new processes, and I there doesn't seem to be any references I can add for it either...
Rgds,
Jon
I do not believe you can use System.Diagnostics.Process to run processes if you are using Compact Net Framework 1.x, (you can in the full net framework). Not sure about 2.x as I have not migrated yet.
try (this is C#)
[DllImport("coredll.Dll",EntryPoint="CreateProcess")]
private static extern int CreateProcess(string strImageName, string strCmdLine, IntPtr pProcessAttributes, IntPtr pThreadAttributes , int bInheritsHandle, int wCreationFlags, IntPtr pEnvironment, IntPtr pCurrentDir, Byte[] bArray, ProcessInfo oProc);
......
......
then
ProcessInfo pi = new ProcessInfo();
CreateProcess("myprogname", "-myprogargs", IntPtr.Zero, IntPtr.Zero, 0, 0, IntPtr.Zero, IntPtr.Zero, new Byte[128], pi)
So... here's my code so far (stripped out non-essential bits). Clicking on a button on the form triggers the sub doLaunchPlayer().
Code:
Imports System.Runtime.InteropServices
Public Class Starter
Dim strOutFile As String = "\stream.m3u"
Private Sub doLaunchPlayer()
SpawnProcess(strOutFile, "")
End Sub
Private Declare Function CreateProcess Lib "coredll.Dll" (ByVal strImageName As String, ByVal strCmdLine As String, ByVal pProcessAttributes As IntPtr, ByVal pThreadAttributes As IntPtr, ByVal bInheritsHandle As Integer, ByVal dwCreationFlags As Integer, ByVal pEnvironment As IntPtr, ByVal pCurrentDir As IntPtr, ByVal bArray() As [Byte], ByVal oProc As ProcessInfo) As Integer
Private Sub SpawnProcess(ByVal Application As String, ByVal Arguments As String)
Dim pi As New ProcessInfo
CreateProcess(Application, Arguments, IntPtr.Zero, IntPtr.Zero, 0, 0, IntPtr.Zero, IntPtr.Zero, New [Byte](128) {}, pi)
End Sub
End Class
Public Class ProcessInfo
Public Process As Integer
Public Thread As Integer
Public ProcessID As Integer
Public ThreadID As Integer
End Class
It's not running the associated application for a .m3u file. Changing to the following doesn't work either:
Code:
Private Sub doLaunchPlayer()
SpawnProcess("\Program Files\TCPMP\Player.exe", strOutFile)
End Sub
Any thoughts?
1) You should check the return code of CreateProcess.
2) Does VB need CreateProcess("\\Program Files\\TCMP\\...... ?
3) Try with a fullpath to Word or another integrated app, to check your code is correct.
I'd got the code wrong. Thanks for the pointer - I was looking in the wrong place for the exe!
Hi there,
OK, I took the hint about using shellexececuteex, but I can't find a code snippet which does the trick!
I found this link which gives some good code, but when I put it in my VB.NET app, it doesn't seem to like it.
At the line
Code:
DllImport("coredll") _
Private Shared Function ShellExecuteEx(ByVal ex As SHELLEXECUTEEX) As Integer
it says "Statement is not valid in namespace."
and
Code:
<DllImport("coredll")> _
Private Shared Function LocalAlloc(flags As Integer, size As Integer) As IntPtr()
says "Statement cannot appear within a method body. End of method assumed.
Can anyone point me in the right direction? Once I know what I'm doing (which may be a while!), I've got some funky stuff I want to do, but I need to figure out what I'm doing wrong first...
Thanks
Jon "The Nice Guy
Code:
Imports System.Runtime.InteropServices
Imports System.Text
Class SHELLEXECUTEEX
Public cbSize As Integer
Public fMask As Integer
Public hwnd As IntPtr
Public lpVerb As IntPtr
Public lpFile As IntPtr
Public lpParameters As IntPtr
Public lpDirectory As IntPtr
Public nShow As Integer
Public hInstApp As IntPtr
' Optional members
Public lpIDList As IntPtr
Public lpClass As IntPtr
Public hkeyClass As IntPtr
Public dwHotKey As UInt32
Public hIcon As IntPtr
Public hProcess As IntPtr
End Class 'SHELLEXECUTEEX
<DllImport("coredll")> _
Private Shared Function ShellExecuteEx(ByVal ex As SHELLEXECUTEEX) As Integer
<DllImport("coredll")> _
Private Shared Function LocalAlloc(flags As Integer, size As Integer) As IntPtr()
<DllImport("coredll")> Private Shared Sub LocalFree(ptr As IntPtr)
' Code starts here
Dim docname As String = "\windows\default.htm"
Dim nSize As Integer = docname.Length * 2 + 2
Dim pData As IntPtr = LocalAlloc(&H40, nSize)
Marshal.Copy(Encoding.Unicode.GetBytes(docname), 0, pData, nSize - 2)
Dim see As New SHELLEXECUTEEX
see.cbSize = 60
see.dwHotKey = 0
see.fMask = 0
see.hIcon = IntPtr.Zero
see.hInstApp = IntPtr.Zero
see.hProcess = IntPtr.Zero
see.lpClass = IntPtr.Zero
see.lpDirectory = IntPtr.Zero
see.lpIDList = IntPtr.Zero
see.lpParameters = IntPtr.Zero
see.lpVerb = IntPtr.Zero
see.nShow = 0
see.lpFile = pData
ShellExecuteEx(see)
LocalFree(pData)
If you want to start an executable, take a look at the following example which uses createprocess in VB using API
http://samples.gotdotnet.com/quickstart/CompactFramework/doc/waitforsingleobject.aspx
And some other interesting information using ShellExecute and Process.Start
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=404967&SiteID=1
Eelco
I need to execute a m3u file, or (in another case) a cab file.
I can't help you with the .NET stuff, but if you are trying to install cabs programatically you should read up on wceload.exe and it's parameters.
Unfortunately this will still require the use of CreateProcess (something that is very easy in native code, but apparently not so in .NET) but you will have control over several things like messages asking were to install and progress bar being shown.
http://msdn.microsoft.com/library/d...n-us/wcepbguide5/html/wce50lrfWceloadTool.asp
Bump
Just to let you all know, I got around needing the .cab file thang by installing the MrClean AUK2 ROM. I still want to be able to launch files with any extension though.
Jon
Use the registry to find out what program should launch for that extension and then launch that program with the file name as a parameter.
Which is what I was after in this thread where people told me to use ShellExecuteEX! LOL
If you can tell me how to get the application handler from the registry based on a file extension, then I'll write it into my app, otherwise, I'll need to use the ShellExecuteEX to launch the file, and let Windows handle the extension.
Hi,
i try to access ril functions from VB.NET
but get an NotSupportetException if i call RIL_Initialize.
Need help please:
Code:
Private Shared hRil As Long = 0
Public Delegate Function dRilResultCallback(ByVal dwCode As Long, ByVal hrCmdID As Int32, ByVal lpData As Byte(), ByVal cdData As Long, ByVal dwParam As Long) As Long
Public Delegate Function dRilNotifyCallback(ByVal dwCode As Long, ByVal lpData() As Byte, ByVal cdData As LocalDataStoreSlot, ByVal dwParam As Long) As Long
<DllImport("Ril.dll")> _
Private Shared Function RIL_Initialize( _
ByVal Index As Int32, _
ByVal pResult As dRilResultCallback, _
ByVal pNotify As dRilNotifyCallback, _
ByVal NotifyClass As Byte, _
ByVal Params As Byte, _
ByRef hResult As Long _
) As Long
End Function
Private Shared Function RilResultCallback(ByVal dwCode As Long, ByVal hrCmdID As Int32, ByVal lpData As Byte(), ByVal cdData As Long, ByVal dwParam As Long) As Long
End Function
Private Shared Function RilNotifyCallback(ByVal dwCode As Long, ByVal lpData() As Byte, ByVal cdData As LocalDataStoreSlot, ByVal dwParam As Long) As Long
End Function
Public Shared Function InitRil() As Boolean
Dim nRetVal As Long = 0
If (hRil = 0) Then
Try
Dim cbResult As dRilResultCallback = AddressOf RilResultCallback
Dim cbNotify As dRilNotifyCallback = AddressOf RilNotifyCallback
nRetVal = RIL_Initialize(1, cbResult, cbNotify, 0, 0, hRil)
Catch ex As Exception
MsgBox("Execption: " & ex.Message, MsgBoxStyle.Critical)
End Try
End If
i have found 1000 samples in C++ but i to really hard to translate it in VB.
I am not familiar with VB.NET, but few suggestions:
1. If you debug the program with emulator, make sure you choose the EMU image with virtual RIL support.
2. If you debug the prog with WM5 device, make sure you have priviledge signed your prog.
3. In C++, I use &g_hRil instead of g_hRil in the last para of Ril_Initial function, any idea?
4. Pay more attention to the CALLBACK functions, Result callback and Notify callback.
ahe said:
2. If you debug the prog with WM5 device, make sure you have priviledge signed your prog.
Click to expand...
Click to collapse
I test this way. Perhaps if i use certificates it works.
Then simply signed it with WM5 SDK test priviledged cert.
Ok, my certification is installed and isgned the app.
But same error.
It looks like an error in declaraion....
BongoUser said:
Ok, my certification is installed and isgned the app.
But same error.
It looks like an error in declaraion....
Click to expand...
Click to collapse
The RIL declarations are not correct
Code:
[FONT=Verdana, Arial, Helvetica][SIZE=2][COLOR=#333333]typedef void (CALLBACK *RILRESULTCALLBACK)(
DWORD dwCode, // @parm result code
HRESULT hrCmdID, // @parm ID returned by the command that originated this response
const void* lpData, // @parm data associated with the notification
DWORD cbData, // @parm size of the strcuture pointed to lpData
DWORD dwParam // @parm parameter passed to <f RIL_Initialize>
);
typedef void (CALLBACK *RILNOTIFYCALLBACK)(
DWORD dwCode, // @parm notification code
const void* lpData, // @parm data associated with the notification
DWORD cbData, // @parm size of the strcuture pointed to lpData
DWORD dwParam // @parm parameter passed to <f RIL_Initialize>
);
[/COLOR][/SIZE][/FONT]
[FONT=Verdana, Arial, Helvetica]
[/FONT] lpData is long in the C declaration, then try to cast it later, not in the declaration directly.
[FONT=Verdana, Arial, Helvetica]Change your Byte() in the callback to IntPtr. And use Marshal.PtrToStruct to put it in one of the RIL structs to get the data.[/FONT]
Then in order to simplify your job, why don't you write a library in C/C++ that you call in your VB.net appl. in place of trying to port the code directly and reinvent the wheel.
ps.: as I said .NET is crap, just use a real programming language.
Cheers,
.Fred
Is anyone currently using the GPS Intermediate Driver parsed API in VB?
I'm looking to get started but needing a bit of a kick-start. I've found the API to be used and it seems simple enough with only 4 functions but I don't see an example of anyone using it in VB, anywhere...
From the example in C++ from the SDK the DLL has the following functions but I don't know how to convert to VB, can anyone give a hand?
#region PInvokes to gpsapi.dll
[DllImport("gpsapi.dll")]
static extern IntPtr GPSOpenDevice(IntPtr hNewLocationData, IntPtr hDeviceStateChange, string szDeviceName, int dwFlags);
[DllImport("gpsapi.dll")]
static extern int GPSCloseDevice(IntPtr hGPSDevice);
[DllImport("gpsapi.dll")]
static extern int GPSGetPosition(IntPtr hGPSDevice, IntPtr pGPSPosition, int dwMaximumAge, int dwFlags);
[DllImport("gpsapi.dll")]
static extern int GPSGetDeviceState(IntPtr pGPSDevice);
#endregion
Thanks,
can you post the c++ code here. we can try and rebuild the data structures for vb which would allow you to execute the dll functions. (I would od it but I'm at work, not access)
How much of the code are you interested in?
In case anyone is interested I was able to find an unwilling soul to convert the first signature.
Here is the signature in C#:
[DllImport("gpsapi.dll")]static extern IntPtr GPSOpenDevice( IntPtr hNewLocationData, IntPtr hDeviceStateChange, string szDeviceName, int dwFlags);In VB, it looks like this:
In VB:
<DllImport("gpsapi.dll")> _Function Shared GPSOpenDevice( _ ByVal hNewLocationData As IntPtr, _ ByVal hDeviceStateChange As IntPtr, _ ByVal szDeviceName As String, _ ByVal dwFlags As Integer) As IntPtrEnd Function
hopefully some others can help come up with some simple VB source for using the GPS device....
I believe this is from a class module:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
using System;
using System.Runtime.InteropServices;
using System.Collections;
using System.Text;
namespace Microsoft.WindowsMobile.Samples.Location
{
public delegate void LocationChangedEventHandler(object sender, LocationChangedEventArgs args);
public delegate void DeviceStateChangedEventHandler(object sender, DeviceStateChangedEventArgs args);
/// <summary>
/// Summary description for GPS.
/// </summary>
public class Gps
{
// handle to the gps device
IntPtr gpsHandle = IntPtr.Zero;
// handle to the native event that is signalled when the GPS
// devices gets a new location
IntPtr newLocationHandle = IntPtr.Zero;
// handle to the native event that is signalled when the GPS
// device state changes
IntPtr deviceStateChangedHandle = IntPtr.Zero;
// handle to the native event that we use to stop our event
// thread
IntPtr stopHandle = IntPtr.Zero;
// holds our event thread instance
System.Threading.Thread gpsEventThread = null;
event LocationChangedEventHandler locationChanged;
/// <summary>
/// Event that is raised when the GPS locaction data changes
/// </summary>
public event LocationChangedEventHandler LocationChanged
{
add
{
locationChanged += value;
// create our event thread only if the user decides to listen
CreateGpsEventThread();
}
remove
{
locationChanged -= value;
}
}
event DeviceStateChangedEventHandler deviceStateChanged;
/// <summary>
/// Event that is raised when the GPS device state changes
/// </summary>
public event DeviceStateChangedEventHandler DeviceStateChanged
{
add
{
deviceStateChanged += value;
// create our event thread only if the user decides to listen
CreateGpsEventThread();
}
remove
{
deviceStateChanged -= value;
}
}
/// <summary>
/// True: The GPS device has been opened. False: It has not been opened
/// </summary>
public bool Opened
{
get { return gpsHandle != IntPtr.Zero; }
}
public Gps()
{
}
~Gps()
{
// make sure that the GPS was closed.
Close();
}
/// <summary>
/// Opens the GPS device and prepares to receive data from it.
/// </summary>
public void Open()
{
if (!Opened)
{
// create handles for GPS events
newLocationHandle = CreateEvent(IntPtr.Zero, 0, 0, null);
deviceStateChangedHandle = CreateEvent(IntPtr.Zero, 0, 0, null);
stopHandle = CreateEvent(IntPtr.Zero, 0, 0, null);
gpsHandle = GPSOpenDevice(newLocationHandle, deviceStateChangedHandle, null, 0);
// if events were hooked up before the device was opened, we'll need
// to create the gps event thread.
if (locationChanged != null || deviceStateChanged != null)
{
CreateGpsEventThread();
}
}
}
/// <summary>
/// Closes the gps device.
/// </summary>
public void Close()
{
if (gpsHandle != IntPtr.Zero)
{
GPSCloseDevice(gpsHandle);
gpsHandle = IntPtr.Zero;
}
// Set our native stop event so we can exit our event thread.
if (stopHandle != IntPtr.Zero)
{
EventModify(stopHandle, eventSet);
}
// block until our event thread is finished before
// we close our native event handles
lock (this)
{
if (newLocationHandle != IntPtr.Zero)
{
CloseHandle(newLocationHandle);
newLocationHandle = IntPtr.Zero;
}
if (deviceStateChangedHandle != IntPtr.Zero)
{
CloseHandle(deviceStateChangedHandle);
deviceStateChangedHandle = IntPtr.Zero;
}
if (stopHandle != IntPtr.Zero)
{
CloseHandle(stopHandle);
stopHandle = IntPtr.Zero;
}
}
}
/// <summary>
/// Get the position reported by the GPS receiver
/// </summary>
/// <returns>GpsPosition class with all the position details</returns>
public GpsPosition GetPosition()
{
return GetPosition(TimeSpan.Zero);
}
/// <summary>
/// Get the position reported by the GPS receiver that is no older than
/// the maxAge passed in
/// </summary>
/// <param name="maxAge">Max age of the gps position data that you want back.
/// If there is no data within the required age, null is returned.
/// if maxAge == TimeSpan.Zero, then the age of the data is ignored</param>
/// <returns>GpsPosition class with all the position details</returns>
public GpsPosition GetPosition(TimeSpan maxAge)
{
GpsPosition gpsPosition = null;
if (Opened)
{
// allocate the necessary memory on the native side. We have a class (GpsPosition) that
// has the same memory layout as its native counterpart
IntPtr ptr = Utils.LocalAlloc(Marshal.SizeOf(typeof(GpsPosition)));
// fill in the required fields
gpsPosition = new GpsPosition();
gpsPosition.dwVersion = 1;
gpsPosition.dwSize = Marshal.SizeOf(typeof(GpsPosition));
// Marshal our data to the native pointer we allocated.
Marshal.StructureToPtr(gpsPosition, ptr, false);
// call native method passing in our native buffer
int result = GPSGetPosition(gpsHandle, ptr, 500000, 0);
if (result == 0)
{
// native call succeeded, marshal native data to our managed data
gpsPosition = (GpsPosition)Marshal.PtrToStructure(ptr, typeof(GpsPosition));
if (maxAge != TimeSpan.Zero)
{
// check to see if the data is recent enough.
if (!gpsPosition.TimeValid || DateTime.Now - maxAge > gpsPosition.Time)
{
gpsPosition = null;
}
}
}
// free our native memory
Utils.LocalFree(ptr);
}
return gpsPosition;
}
Sorry had to post the remaining source in another thread:
/// <summary>
/// Queries the device state.
/// </summary>
/// <returns>Device state information</returns>
public GpsDeviceState GetDeviceState()
{
GpsDeviceState device = null;
// allocate a buffer on the native side. Since the
IntPtr pGpsDevice = Utils.LocalAlloc(GpsDeviceState.GpsDeviceStructureSize);
// GPS_DEVICE structure has arrays of characters, it's easier to just
// write directly into memory rather than create a managed structure with
// the same layout.
Marshal.WriteInt32(pGpsDevice, 1); // write out GPS version of 1
Marshal.WriteInt32(pGpsDevice, 4, GpsDeviceState.GpsDeviceStructureSize); // write out dwSize of structure
int result = GPSGetDeviceState(pGpsDevice);
if (result == 0)
{
// instantiate the GpsDeviceState class passing in the native pointer
device = new GpsDeviceState(pGpsDevice);
}
// free our native memory
Utils.LocalFree(pGpsDevice);
return device;
}
/// <summary>
/// Creates our event thread that will receive native events
/// </summary>
private void CreateGpsEventThread()
{
// we only want to create the thread if we don't have one created already
// and we have opened the gps device
if (gpsEventThread == null && gpsHandle != IntPtr.Zero)
{
// Create and start thread to listen for GPS events
gpsEventThread = new System.Threading.Thread(new System.Threading.ThreadStart(WaitForGpsEvents));
gpsEventThread.Start();
}
}
/// <summary>
/// Method used to listen for native events from the GPS.
/// </summary>
private void WaitForGpsEvents()
{
lock (this)
{
bool listening = true;
// allocate 3 handles worth of memory to pass to WaitForMultipleObjects
IntPtr handles = Utils.LocalAlloc(12);
// write the three handles we are listening for.
Marshal.WriteInt32(handles, 0, stopHandle.ToInt32());
Marshal.WriteInt32(handles, 4, deviceStateChangedHandle.ToInt32());
Marshal.WriteInt32(handles, 8, newLocationHandle.ToInt32());
while (listening)
{
int obj = WaitForMultipleObjects(3, handles, 0, -1);
if (obj != waitFailed)
{
switch (obj)
{
case 0:
// we've been signalled to stop
listening = false;
break;
case 1:
// device state has changed
if (deviceStateChanged != null)
{
deviceStateChanged(this, new DeviceStateChangedEventArgs(GetDeviceState()));
}
break;
case 2:
// location has changed
if (locationChanged != null)
{
locationChanged(this, new LocationChangedEventArgs(GetPosition()));
}
break;
}
}
}
// free the memory we allocated for the native handles
Utils.LocalFree(handles);
// clear our gpsEventThread so that we can recreate this thread again
// if the events are hooked up again.
gpsEventThread = null;
}
}
#region PInvokes to gpsapi.dll
[DllImport("gpsapi.dll")]
static extern IntPtr GPSOpenDevice(IntPtr hNewLocationData, IntPtr hDeviceStateChange, string szDeviceName, int dwFlags);
[DllImport("gpsapi.dll")]
static extern int GPSCloseDevice(IntPtr hGPSDevice);
[DllImport("gpsapi.dll")]
static extern int GPSGetPosition(IntPtr hGPSDevice, IntPtr pGPSPosition, int dwMaximumAge, int dwFlags);
[DllImport("gpsapi.dll")]
static extern int GPSGetDeviceState(IntPtr pGPSDevice);
#endregion
#region PInvokes to coredll.dll
[DllImport("coredll.dll")]
static extern IntPtr CreateEvent(IntPtr lpEventAttributes, int bManualReset, int bInitialState, StringBuilder lpName);
[DllImport("coredll.dll")]
static extern int CloseHandle(IntPtr hObject);
const int waitFailed = -1;
[DllImport("coredll.dll")]
static extern int WaitForMultipleObjects(int nCount, IntPtr lpHandles, int fWaitAll, int dwMilliseconds);
const int eventSet = 3;
[DllImport("coredll.dll")]
static extern int EventModify(IntPtr hHandle, int dwFunc);
#endregion
}
}
Well I've made a little progress but once again I'm stumped since I don't program in C..
Currently I'm able to open and close the GPS device on my phone but in order to retrieve information I believe I need a stuct converted to VB. I'm not familiar with struct so I'm hoping someone can explain it to me and or maybe help convert it.
These are the functions that have been converted to VB from C:
'Put this at the top of your module.
'Required in all cases when calling API functions
Imports System.Runtime.InteropServices
'Required in this example and any API function which
'use a string buffer. Provides the StringBuilder class
Imports System.Text
Public Class Form1
<DllImport("gpsapi.dll", EntryPoint:="GPSOpenDevice", SetLastError:=True, CharSet:=CharSet.Unicode, CallingConvention:=CallingConvention.Winapi)> _
Public Shared Function GPSOpenDevice(ByVal hNewLocationData As IntPtr, ByVal hDeviceStateChange As IntPtr, ByVal szDeviceName As String, ByVal dwFlags As Integer) As IntPtr
End Function
<DllImport("gpsapi.dll", EntryPoint:="GPSCloseDevice", SetLastError:=True, CharSet:=CharSet.Unicode, CallingConvention:=CallingConvention.Winapi)> _
Public Shared Function GPSCloseDevice(ByVal hGPSDevice As IntPtr) As Integer
End Function
<DllImport("gpsapi.dll", EntryPoint:="GPSGetPosition", SetLastError:=True, CharSet:=CharSet.Unicode, CallingConvention:=CallingConvention.Winapi)> _
Public Shared Function GPSGetPosition(ByVal hGPSDevice As IntPtr, ByVal pGPSPosition As IntPtr, ByVal dwMaximumAge As Integer, ByVal dwFlags As Integer) As Integer
End Function
<DllImport("gpsapi.dll", EntryPoint:="GPSGetDeviceState", SetLastError:=True, CharSet:=CharSet.Unicode, CallingConvention:=CallingConvention.Winapi)> _
Public Shared Function GPSGetDeviceState(ByVal pGPSDevice As IntPtr) As Integer
End Function
Click to expand...
Click to collapse
and this is the struct I need help with:
typedef struct _GPS_POSITION {
DWORD dwVersion;
DWORD dwSize;
DWORD dwValidFields;
DWORD dwFlags;
SYSTEMTIME stUTCTime;
double dblLatitude;
double dblLongitude;
float flSpeed;
float flHeading;
double dblMagneticVariation;
float flAltitudeWRTSeaLevel;
float flAltitudeWRTEllipsoid;
GPS_FIX_QUALITY FixQuality;
GPS_FIX_TYPE FixType;
GPS_FIX_SELECTION SelectionType;
float flPositionDilutionOfPrecision;
float flHorizontalDilutionOfPrecision;
float flVerticalDilutionOfPrecision;
DWORD dwSatelliteCount;
DWORD rgdwSatellitesUsedPRNs[GPS_MAX_SATELLITES];
DWORD dwSatellitesInView;
DWORD rgdwSatellitesInViewPRNs[GPS_MAX_SATELLITES];
DWORD rgdwSatellitesInViewElevation[GPS_MAX_SATELLITES];
DWORD rgdwSatellitesInViewAzimuth[GPS_MAX_SATELLITES];
DWORD rgdwSatellitesInViewSignalToNoiseRatio[GPS_MAX_SATELLITES];
} GPS_POSITION, *PGPS_POSITION;
Click to expand...
Click to collapse
I think the struct works like some type of callback which even that I'm not familiar with but as you try and retrieve information from the function 'GPSGetPosition' it uses the struct to do the work? just a guess...
Anyway I'm hoping someone can help me out as I feel I'm close but unless I can pull GPS data at still at ground zero...
TW,
Simple solution: Compile C# (this is NOT C+++) code to dll library. Then reference library from VB.NET solution.
C# and VB.NET are compiled both to IL.
Here is the needed code and declarations in C#.
<Your path>'Windows Mobile 6 SDK\Samples\PocketPC\CS\GPS\GpsPosition.cs"
Since I'm a bit green - are there some examples of doing this somewhere that I can take a look at?
"C# and VB.NET are compiled both to IL."
I don't follow what your saying here? what does IL stand for?
Thanks,
My friend,
why sample?
IL = Intermediate Language - VB.NET and C# are compiled to intermediatate language.
.Net Framework is languaage independent - You can compile C# code to dll and then reference (add reference) this dll in VB.NET project and use types form C# dll directly.
Thanks, I certainly appreciate your patience...
OK, I'll remember to use VB.NET as opposed to .NET in the future since there is a difference that I was unaware of, thanks for that.
Since I want to run this application on my phone I assume I need to create a new project in VB.Net - WM6 class library. Can I simply copy over the references and source form the original SDK and then build the .dll from there or am I over simplifying?
After building the .dll, in the application I want to create I make the reference to the new .dll, got it, when I want to reference the struct of the 'GPSGetPosition' function how would I do that?
TW,
[EDIT]
Doing more reading and learning a bit.
I think using a dll is the way to go and I believe there is a dll included in the sample. That brings me back to the Q of implementation. I've added a reference to the dll but since I'm only using the functions built within the dll how should I pass the GPS_POSITION struct listed above? does that still need to be converted to VB.Net then passed?
Semi manual marshhalling of structure to pointer:
Dim pointerM As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(myStruct))
Marshal.StructureToPtr(myStruct, pointerM, False)
Marshal.FreeHGlobal(pnt)
Click to expand...
Click to collapse
Since the above doesn't seem to pass anything to the struct is this used for sizing the struct to be passed?
OK.
Here is the compiled dll.
Add reference from vb.net project to dll.
Then (conceptual code in the pretty poor verbose VB.NET syntax )
Dim gps As new Gps()
AddHandler gps.DeviceStateChanged , DeviceStateChanged
AddHandler gps.LocationChanged, LocationChanged
gps.Open();
Public Sub LocationChanged(sender As object, args as LocationChangedEventArgs)
'Do something
args.Position.LatitudeInDegreesMinutesSeconds
args.position.LongitudeInDegreesMinutesSeconds
End Sub
Public Sub DeviceStateChanged(object sender, DeviceStateChangedEventArgs args)
'Do something
//GPS driver state
args.DeviceState;
End Sub
End of work with gps:
gps.Close()
//edit: Remove zip extension from gps.dll.zip - gps.dll is a valid name of assembly
RStein,
Thanks for your help. I managed to get it going with your assistance, it's much appreciated.
The .dll you compiled is not complete and errors though..
Dlli is a complete - from gps managed sample.
What's the error You're talking about?
As I said in other zda thread - intermediate driver doesn't work correctly on some Devices/ROM because of the error in the Microsoft/OEM implementaton (Htc Artemis).. http://groups.google.com/group/microsoft.public.pocketpc.developer/msg/2cedd69b906d4b7e
And finaly - GPS intermediate must be of course active in the control panel.
This is the error generated:
System.MissingMethodException was unhandled
Message: File or assembly name 'Microsoft.WindowsMobile.Samples.Location, Version=1.0.2985.26108, Culture=neutral, PublicKeyToken=null', or one of its dependencies, was not found.
System.TypeLoadException was unhandled
Message: An unhandled exception of type 'System.TypeLoadException' occurred in Unknown Module.
Click to expand...
Click to collapse
Thx,
Please rename gps.dll to Microsoft.WindowsMobile.Samples.Location.dll
And here is the project in VB - functional
I'm using VB.Net for Windows Mobile 5, but still not working
I want to use the GPS Intermediate Driver because I want to let the GPS to be used for other apps, such as the Google Maps for WM and other.
I did the following code, but I still not getting the right result... I did a program using the Serial connection, but Google Maps and other cannot use the GPS at the same time.
So... what am I doing wrong?
Here my code, any clues?
REM Declare Function GPSOpenDevice Lib "gpsapi.dll" (ByVal hNewLocationData As IntPtr, ByVal hDeviceStateChange As IntPtr, ByVal szDeviceName As String, ByVal dwFlags As Integer) As IntPtr
<DllImport("gpsapi.dll", EntryPoint:="GPSOpenDevice", SetLastError:=True, CharSet:=CharSet.Unicode, CallingConvention:=CallingConvention.Winapi)> _
Public Shared Function GPSOpenDevice(ByVal hNewLocationData As IntPtr, ByVal hDeviceStateChange As IntPtr, ByVal szDeviceName As String, ByVal dwFlags As Integer) As IntPtr
End Function
REM Declare Function GPSCloseDevice Lib "gpsapi.dll" (ByVal hGPSDevice As IntPtr) As Integer
<DllImport("gpsapi.dll", EntryPoint:="GPSCloseDevice", SetLastError:=True, CharSet:=CharSet.Unicode, CallingConvention:=CallingConvention.Winapi)> _
Public Shared Function GPSCloseDevice(ByVal hGPSDevice As IntPtr) As Integer
End Function
REM Declare Function GPSGetDeviceState Lib "gpsapi.dll" (ByVal pGPSDevice As IntPtr) As Integer
<DllImport("gpsapi.dll", EntryPoint:="GPSGetDeviceState", SetLastError:=True, CharSet:=CharSet.Unicode, CallingConvention:=CallingConvention.Winapi)> _
Public Shared Function GPSGetDeviceState(ByVal pGPSDevice As IntPtr) As Integer
End Function
REM Declare Function GPSGetPosition Lib "gpsapi.dll" (ByVal hGPSDevice As IntPtr, ByVal pGPSPosition As IntPtr, ByVal dwMaximumAge As Integer, ByVal dwFlags As Integer) As Integer
<DllImport("gpsapi.dll", EntryPoint:="GPSGetPosition", SetLastError:=True, CharSet:=CharSet.Unicode, CallingConvention:=CallingConvention.Winapi)> _
Public Shared Function GPSGetPosition(ByVal hGPSDevice As IntPtr, ByVal pGPSPosition As GPS_POSITION, ByVal dwMaximumAge As Integer, ByVal dwFlags As Integer) As Integer
End Function
Const dwSize As Long = 0
Const dwVersion As Long = 1
Const dwFlags As Long = 0
Const dwValidFields As Long = 0
Const GPS_MAX_SATELLITES As Long = 12
<StructLayout(LayoutKind.Sequential)> Public Structure GPS_POSITION
Dim dwVersion As Long
Dim dwSize As Long
Dim dwValidFields As Long
Dim dwFlags As Long
'Dim stUTCTime As systemtime
Dim dblLatitude As Double
Dim dblLongitude As Double
Dim flSpeed As Double
Dim flHeading As Double
Dim dblMagneticVariation As Double
Dim flAltitudeWRTSeaLevel As Single
Dim flAltitudeWRTEllipsoid As Single
'GPS_FIX_QUALITY FixQuality;
'GPS_FIX_TYPE FixType;
'GPS_FIX_SELECTION SelectionType;
Dim flPositionDilutionOfPrecision As Single
Dim flHorizontalDilutionOfPrecision As Single
Dim flVerticalDilutionOfPrecision As Single
Dim dwSatelliteCount As Long
Dim rgdwSatellitesUsedPRNs() As Long
Dim dwSatellitesInView As Long
Dim rgdwSatellitesInViewPRNs() As Long
Dim rgdwSatellitesInViewElevation() As Long
Dim rgdwSatellitesInViewAzimuth() As Long
Dim rgdwSatellitesInViewSignalToNoiseRatio() As Long
End Structure
Enum GPS_FIX_QUALITY
GPS_FIX_QUALITY_UNKNOWN
GPS_FIX_QUALITY_GPS
GPS_FIX_QUALITY_DGPS
End Enum
Enum GPS_FIX_TYPE
GPS_FIX_UNKNOWN
GPS_FIX_2D
GPS_FIX_3D
End Enum
Enum GPS_FIX_SELECTION
GPS_FIX_SELECTION_UNKNOWN
GPS_FIX_SELECTION_AUTO
GPS_FIX_SELECTION_MANUAL
End Enum
<StructLayout(LayoutKind.Sequential)> Public Structure SYSTEMTIME
Public wYear As Short
Public wMonth As Short
Public wDayOfWeek As Short
Public wDay As Short
Public wHour As Short
Public wMinute As Short
Public wSecond As Short
Public wMilliseconds As Short
End Structure
Dim gpsHandle As IntPtr = IntPtr.Zero
Public Function OpenGPSDevice() As Boolean
Try
gpsHandle = GPSOpenDevice(Nothing, Nothing, Nothing, 0)
OpenGPSDevice = (gpsHandle <> 0)
MsgBox("Device is open")
Catch ex As Exception
MsgBox("Error opening GPSDevice")
End Try
End Function
Public Function CloseGPSDevice() As Boolean
Try
If gpsHandle = 0 Then Exit Function
GPSCloseDevice(gpsHandle)
gpsHandle = IntPtr.Zero
MsgBox("Device is closed")
Catch ex As Exception
MsgBox("Error closing GPSDevice")
End Try
End Function
Private Sub bmtGPS_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bmtGPS.Click
Dim i As Long
Dim gpsPOS As New GPS_POSITION
Try
'gpsPOS.dwVersion = "GPS_VERSION_1"
'gpsPOS.dwSize = 512
i = GPSGetPosition(gpsHandle, gpsPOS, 500000, 0)
txtTeste.Text &= i
txtTeste.Text &= vbCrLf & "Latitude=" & gpsPOS.dblLatitude
txtTeste.Text &= vbCrLf & "Longitude=" & gpsPOS.dblLongitude
txtTeste.Text &= vbCrLf & "SatelliteCount=" & gpsPOS.dwSatelliteCount
txtTeste.Text &= vbCrLf & "SatellitesInView=" & gpsPOS.dwSatellitesInView
txtTeste.Text &= vbCrLf & "Heading=" & gpsPOS.flHeading
txtTeste.Text &= vbCrLf & "Speed=" & gpsPOS.flSpeed
txtTeste.Text &= vbCrLf & "Flags=" & gpsPOS.dwFlags
Catch ex As Exception
MsgBox("Error getting position")
End Try
End Sub
Private Sub bmtGPSOn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bmtGPSOn.Click
OpenGPSDevice()
End Sub
Private Sub bmtGPSOff_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bmtGPSOff.Click
CloseGPSDevice()
End Sub
Thank your for the GPS Vb.Net Sample
Hi René,
Your sample help me a lot, but I still have some issues and I hope you can give me more clues.
During my tests... everything works fine, but when I tried to use some of the date from LocationChanged, it do not return data. The GPS icon is GREEN, so, it's looks like everything is fine... the Google Maps works with my apps to, but all return ""
frmPrincipal.lblLatitude.Text = e.Position.Longitude.ToString()
frmPrincipal.lblLongitude.Text = e.Position.Longitude.ToString()
frmPrincipal.lblAltitude.Text = e.Position.SeaLevelAltitude.ToString()
Other thing... why at DeviceStateChanged the only way to get data if with a INVOKE like you did?
Invoke(New UpdateDataHandler(AddressOf AddItem), e.DeviceState.FriendlyName)
And final...
As I can see... the LocationChanged, is not so acured... because it was been called every second or less... it's normal?
Best,
Ruben
RStein said:
And here is the project in VB - functional
Click to expand...
Click to collapse
Getting a error with GPS
I'm getting the following error. I get this random, as I read, the GPS API uses a file to get it's info, so... I thing could be it.
gps.GetPosition.SatellitesInViewCount.ToString Run-time exception thrown : System.IO.IOException - The process can not access the file '\Test.txt' because it is being used by another process.
With the Debug, I have the following info:
gps.GetDeviceState.FriendlyName ""
gps.GetDeviceState.DeviceState On {1}
gps.GetDeviceState.ServiceState On {1}
gps.Opened True
And the error showed it self, when I use any of the follow properties:
gps.GetPosition.LatitudeValid
gps.GetPosition.SatelliteCount
gps.GetPosition.Latitude
I saw at my PDA root folder a Test.txt and also I read that file could configured with.
http://msdn.microsoft.com/en-us/library/ms889970.aspx
Some one have any clues?
I'll continue to dig... if I post here if I get more info.
I'm using a Windows Mobile 5 the HP 6945.
With this DLL work on all device????
I made an application named "Where is" and i use the Serial Port to check the info from GPS but in some device i cant get the data and i dont know why.
With this DLL i can resolve all problems?
I work with vb.net.
Wait an answer please.
Bye
Here are a few useful tricks using p/invoke that some developers may find usefull and some were hard to find on the net so I created my own Wrappers with a little research.
The following code is a Helper Class to apply the WM6.5 visual styles to some controls using .net framework. This Wrapper lets you apply the visual style to the Tab Control, Apply Background Image to ListView, Enable Double Buffering for ListView, Show Grid Lines in ListView and Enable Visual Style for ListView. To call these functions you just simply put the control in the brackets you wish to apply the visual style to. For Example: EnableListViewStyle(lvMyListview)
Code:
Public Class VisualStyleHelper
Public Const GWL_STYLE As Integer = -16
Public Const GW_CHILD As Int32 = 5
Public Const LVS_EX_THEME As Integer = &H2000000
Public Const LVM_SETEXTENDEDLISTVIEWSTYLE As Integer = &H1000 + 54
Public Const LVM_GETEXTENDEDLISTVIEWSTYLE As Integer = &H1000 + 55
Public Const LVS_EX_GRIDLINES As Integer = &H1
Public Const LVS_EX_DOUBLEBUFFER As Integer = &H10000
Public Const LVBKIF_SOURCE_HBITMAP As Integer = &H1
Public Const LVM_SETBKIMAGE As Integer = (&H1000 + 138)
Private Declare Function SendMessage Lib "coredll" (ByVal hWnd As IntPtr, ByVal Msg As UInt32, ByVal wParam As UInt32, ByVal lParam As Integer) As IntPtr
Private Declare Function SendMessage Lib "coredll" (ByVal hWnd As IntPtr, ByVal Msg As UInt32, ByVal wParam As UInt32, ByRef img As LVBKIMAGE) As IntPtr
Public Structure LVBKIMAGE
Public ulFlags As Integer
Public hbm As IntPtr
Public pszImage As IntPtr
Public cchImageMax As Integer
Public xOffsetPercent As Integer
Public yOffsetPercent As Integer
End Structure
'Tab Control Helper
Public Shared Sub EnableTabStyle(ByVal tabControl As TabControl)
Dim hNativeTab As IntPtr = WindowHelper.GetWindow(tabControl.Handle, GW_CHILD)
Dim Style As Integer = WindowHelper.GetWindowLong(hNativeTab, GWL_STYLE)
Style = WindowHelper.SetWindowLong(hNativeTab, GWL_STYLE, Style Or &H4000)
End Sub
'ListView Control Helper
Public Shared Sub EnableListViewStyle(ByVal listView As ListView)
Dim currentStyle As Integer = SendMessage(listView.Handle, CUInt(LVM_GETEXTENDEDLISTVIEWSTYLE), 0, 0)
SendMessage(listView.Handle, CUInt(LVM_SETEXTENDEDLISTVIEWSTYLE), 0, currentStyle Or LVS_EX_THEME)
End Sub
'Set Background Image to ListView
Public Shared Sub SetBackgroundImage(ByVal listView As ListView, ByVal path As String)
Dim bitmap As New Bitmap(path)
Dim hBitmap As IntPtr = bitmap.GetHbitmap()
bitmap.Dispose()
Dim lvImage As New LVBKIMAGE()
lvImage.hbm = hBitmap
lvImage.ulFlags = LVBKIF_SOURCE_HBITMAP
SendMessage(listView.Handle, LVM_SETBKIMAGE, 0, lvImage)
End Sub
'Display GridLines in ListView
Public Shared Sub ShowGridLines(ByVal listView As ListView)
Dim currentStyle As Integer = SendMessage(listView.Handle, CUInt(LVM_GETEXTENDEDLISTVIEWSTYLE), 0, 0)
SendMessage(listView.Handle, CUInt(LVM_SETEXTENDEDLISTVIEWSTYLE), 0, currentStyle Or LVS_EX_GRIDLINES)
End Sub
'Reduces Flicker in ListView
Public Shared Sub EnableDoubleBuffering(ByVal listView As ListView)
Dim currentStyle As Integer = SendMessage(listView.Handle, CUInt(LVM_GETEXTENDEDLISTVIEWSTYLE), 0, 0)
SendMessage(listView.Handle, CUInt(LVM_SETEXTENDEDLISTVIEWSTYLE), 0, currentStyle Or LVS_EX_DOUBLEBUFFER)
End Sub
End Class
Here is a simple function to return the given bytes in Megabytes as a string:
Code:
Public Shared Function CBytesToMBytes(ByVal Bytes As Double) As String
Dim dblAns As Double
dblAns = (Bytes / 1024) / 1024
Return Format(dblAns, "###,###,##0.00 MB")
End Function
Here is a Class Wrapper I created which lets you use various methods to Soft Reset and even use HTCUtil.dll to Hard Reset your device:
Code:
Public Class DeviceBootHelperClass
Const EWX_REBOOT = 2
<DllImport("HtcUtil")> _
Public Shared Sub HTCUtilTurnOnFlightMode()
End Sub
<DllImport("HtcUtil")> _
Public Shared Sub HTCUtilSetClearStorageFlag()
End Sub
<DllImport("HtcUtil")> _
Public Shared Sub HTCUtilPowerOffReset()
End Sub
<DllImport("HtcUtil")> _
Public Shared Sub HTCUtilDeviceOff()
End Sub
<DllImport("HtcUtil")> _
Public Shared Sub HTCUtilEnterBootloaderMode()
End Sub
<DllImport("aygshell")> _
Private Shared Function ExitWindowsEx(ByVal dwFlags As Integer, ByVal dwReserved As Integer) As Boolean
End Function
<DllImport("coredll")> _
Private Shared Function KernelIoControl(ByVal dwIoControlCode As Integer, _
ByVal lpInBuf As IntPtr, ByVal nInBufSize As Integer, ByVal lpOutBuf As IntPtr, _
ByVal nOutBufSize As Integer, ByRef lpBytesReturned As Integer) As Integer
End Function
Public Shared Sub KernelIOControlSoftResetMethod()
Const IOCTL_HAL_REBOOT As Integer = &H101003C
Dim bytesReturned As Integer = 0
KernelIoControl(IOCTL_HAL_REBOOT, IntPtr.Zero, 0, IntPtr.Zero, 0, bytesReturned)
End Sub
Public Shared Sub HTCUtilSoftResetMethod()
Try
HTCUtilPowerOffReset()
Catch ex As Exception
End Try
End Sub
Public Shared Sub HTCUtilPowerOffMethod()
Try
HTCUtilDeviceOff()
Catch ex As Exception
End Try
End Sub
Public Shared Sub HTCUtilHardResetMethod()
Try
HTCUtilTurnOnFlightMode()
HTCUtilSetClearStorageFlag()
HTCUtilPowerOffReset()
End If
Catch ex As Exception
End Try
End Sub
Public Shared Sub ExitWindowsExSoftResetMethod()
Try
ExitWindowsEx(EWX_REBOOT, 0)
Catch ex As Exception
End Try
End Sub
Public Shared Sub EnterBootloaderMode()
Try
HTCUtilEnterBootloaderMode()
Catch ex As Exception
End Try
End Sub
End Class
If you like my work, then please feel free to buy me a beer!
Thanks, this will be very useful
orb3000 said:
Thanks, this will be very useful
Click to expand...
Click to collapse
Hi, I have also wrote my own Window API wrapper which allows for enabling and disabling windows, getting the full exe file path from a given window class, a simple class for restarting an application and more will be uploaded soon. All this is used in my Touch Tools 2.0 Suite!
Great to know!, looking forward for your release
Can you add
wifi on/off/toggle
bluetooth on/off/toggle
gprs on/off/toggle
VisualStyleHelper needs WindowHelper class, which is not included. Google search for WindowHelper shows C# class only, no VB code.
Here it is:
Code:
Public Class WindowHelper
Private Const GW_HWNDFIRST As UInteger = 0
Private Const GW_HWNDLAST As UInteger = 1
Private Const GW_HWNDNEXT As UInteger = 2
Private Const GW_HWNDPREV As UInteger = 3
Private Const GW_OWNER As UInteger = 4
Private Const GW_CHILD As UInteger = 5
<DllImport("coredll.dll")> _
Public Shared Function GetWindow(ByVal hWnd As IntPtr, ByVal uCmd As UInteger) As IntPtr
End Function
<DllImport("coredll.dll", SetLastError:=True)> _
Public Shared Function GetWindowText(ByVal hWnd As IntPtr, <Out()> ByVal lpString As StringBuilder, ByVal nMaxCount As Integer) As Integer
End Function
<DllImport("coredll.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Public Shared Function GetWindowTextLength(ByVal hWnd As IntPtr) As Integer
End Function
<DllImport("coredll.dll")> _
Public Shared Function GetParent(ByVal hWnd As IntPtr) As IntPtr
End Function
<DllImport("coredll.dll")> _
Public Shared Function GetWindowLong(ByVal hWnd As IntPtr, ByVal cmd As Integer) As Integer
End Function
<DllImport("coredll.dll")> _
Public Shared Function GetActiveWindow() As IntPtr
End Function
<DllImport("coredll.dll")> _
Public Shared Function SetWindowLong(ByVal hWnd As IntPtr, ByVal nIndex As Integer, ByVal newWndProc As IntPtr) As Integer
End Function
End Class
@Corias
Lol, how could I have missed including the Window Helper Class! I will prepare some files and include all my classes in them so it will give everyone better understanding.
BR
Gaz
Good. I tried to convert VC# Window helper, everything works except EnumChildWindows (VB reports missing type Window). Any ideas on it?
Awesome work, will try it when i finish the main skeleton of my little program. Will post soon.
... and thank you