Prev: CF 1 / C# how to invoke with arguments?
Next: My way
From: Chan on 27 Nov 2009 12:55 I had tried as you post but I get an error ?HRESULT: 08007007E at statement FindFirstDevice. I am using Visual Studio 2005 and my code is as the following: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices; namespace WindowsApplication1 { public partial class Form1 : Form { bool CAMexist = false; public struct DEVMGR_DEVICE_INFORMATION { public uint dwSize; public IntPtr hDevice; public IntPtr hParentDevice; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)] public string szLegacyName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string szDeviceKey; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string szDeviceName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string szBusName; } public enum DeviceSearchType : int { DeviceSearchByLegacyName = 0, DeviceSearchByDeviceName = 1, DeviceSearchByBusName = 2, DeviceSearchByGuid = 3, DeviceSearchByParent = 4 } public static readonly Guid GuidCamera = new Guid("CB998A05-122C-4166-846A-933E4D7E3C86"); [DllImport("coredll.dll")] public static extern IntPtr FindFirstDevice( [In] DeviceSearchType searchType, //[In] int searchType, [In] IntPtr searchParam, [In, Out] ref DEVMGR_DEVICE_INFORMATION pdi); [DllImport("coredll.dll")] public static extern int FindClose([In] IntPtr hFindFile); public Form1() { InitializeComponent(); } private void timer1_Tick(object sender, EventArgs e) { IntPtr handle = IntPtr.Zero; DeviceSearchType searchType = DeviceSearchType.DeviceSearchByGuid; IntPtr searchParam = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Guid))); Marshal.StructureToPtr(GuidCamera, searchParam, false); DEVMGR_DEVICE_INFORMATION di = new DEVMGR_DEVICE_INFORMATION(); di.dwSize = (uint)Marshal.SizeOf(typeof(DEVMGR_DEVICE_INFORMATION)); handle = FindFirstDevice(searchType, searchParam, ref di); if (CAMexist == true) { CAMtextBox.Text = "Camera exist"; } else { CAMtextBox.Text = "Camera not exist"; } } } } After compile, I run it under debug mode. Then the error occurs at statement FindFirstDevice with HRESULT: 0x8007007E. What should I do to fix it? I am just a novice in Visual Studio and the project is very tight in time. I need your help. Thank you. Jarvius wrote: Greetz,I desperately needed some sample C# code using FindFirstDevice, and so 07-Aug-09 Greetz, I desperately needed some sample C# code using FindFirstDevice, and so I started from the code posted here, which has finally been a valuable help for my current project. :) Nevertheless, I had to make some changes, and though I am not allowed to post full code, I guess commenting how to make it work will harm no one... ;) 1. First of all, FindFirstDevice will be of no use unless you use FindNextDevice as well, as you will get a list of devices, not just one - it looks like you are stuck on wildcards. :-P Notice that FindNextDevice will use the handle returned by FindFirstDevice as its first argument, which should not be INVALID_HANDLE_VALUE (-1), and will return True if there are more items to be looked for, so it could be used as a stop condition for your search loop besides comparing the values (szLegacyName) in your pdi - you will have to check both the first pdi returned by FindFirstDevice as well as the new ones that you will get when calling FindNextDevice. 2. If you are serching for COM#:, do not use DeviceSearchByDeviceName, but DeviceSearchByLegacyName instead. Subsequently, pdi.szLegacyName should be the member to go for. I would strongly recommend you setting breakpoints so that you gt to read the full pdi values and see what you can really expect out of it. 3. Remove the IntPtr searchParam = Marshal.AllocHGlobal(searchParamString.Length); line, which is of no use... The line IntPtr searchParam = Marshal.StringToBSTR(searchParamString); already allocates the required memory. Also, remember to be nice and call Marshal.FreeBSTR after FindFirstDevice, so that the unmanaged memory reserved for your string gets deallocated - usual suspect of memory leaks in .Net apps? 4. Finally, and most important point of it all, FindFirstDevice will fail *unless you set pdi.dwSize to its right value*, which you should do right after doing pdi = new ... - pdi.dwSize = (uint)Marshal.SizeOf(pdi); will do. I hope it helps anyone who has to go through unmanaged (and poorly documented) code in C# as I have had to these days. Posted via DevelopmentNow.com Groups http://www.developmentnow.com/g/ Previous Posts In This Thread: On Monday, 18 June, 2007 9:46 MaskPro wrote: FindFirstDevice and C# Greetings, I am not sure how I would use "FindFirstDevice" while programming in C#. I am sure I use [DllImport("<some dll")], but I am not sure which one to use? Has anyone tried using this before while in programming in C#? Thanks in advance for any suggestions. On Monday, 18 June, 2007 10:09 wrote: Seems pretty strightforward to marshal, but the larger question is what Seems pretty strightforward to marshal, but the larger question is what problem are you trying to solve? There may be a better, faster, already-done way to get the info you want. -- Chris Tacke, Embedded MVP OpenNETCF Consulting Managed Code in an Embedded World www.OpenNETCF.com "BartMan" <MaskProg(a)community.nospam> wrote in message news:B5FD406E-E501-4367-B628-14C34F3F6B6F(a)microsoft.com... On Monday, 18 June, 2007 10:22 MaskPro wrote: Greetings,Thanks for your reply. Greetings, Thanks for your reply. I need to get a handle to a device, so I can monitor the plug of play of it using RegisterDeviceNotification via the "WM_DEVICECHANGE" message. I have done this before in C++ under the windows platform, but I had to use "SetupDiEnumDeviceInfo", and "SetupDiEnumDeviceInfo". Which is not supported under the windows ce enviornment. So basically what I need is a handle to the device to pass to "RegisterDeviceNotification". I already have the wm_device change working in ce 2003 (pocket pc) under c#, but now I need a way to register the device. I do not see any docs any where which tell you what dll to import via marshalling. On Monday, 18 June, 2007 11:26 MaskPro wrote: This code is not working correctly because it can't find the method This code is not working correctly because it can't find the method "FindFirstDevice", but this is what i have now. code snippet: [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct DEVMGR_DEVICE_INFORMATION { public UInt32 dwSize; public IntPtr hDevice; public IntPtr hParentDevice; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)] public string szLegacyName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string szDeviceKey; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string szDeviceName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string szBusName; } public enum DeviceSearchType : int { DeviceSearchByLegacyName = 0, DeviceSearchByDeviceName = 1, DeviceSearchByBusName = 2, DeviceSearchByGuid = 3, DeviceSearchByParent = 4 } [DllImport("coredll.dll", SetLastError = true)] public static extern IntPtr FindFirstDevice(DeviceSearchType searchType, IntPtr searchParam, ref DEVMGR_DEVICE_INFORMATION pdi); In my c# class I try to test it. void testCode() { try { DeviceSearchType searchType = DeviceSearchType.DeviceSearchByDeviceName; DEVMGR_DEVICE_INFORMATION pdi = new DEVMGR_DEVICE_INFORMATION(); string searchParamString = "COM*"; IntPtr searchParam = Marshal.AllocHGlobal(searchParamString.Length); IntPtr searchParam = Marshal.StringToBSTR(searchParamString); IntPtr deviceHandle = FindFirstDevice(searchType,searchParam, ref pdi); } catch (Exception err) { } } I get the exception "Can't find an Entry Point 'FindFirstDevice' in a PInvoke DLL 'coredll.dll'." The "FindFirstDevice" is not found in the "coredll.dll", so I am not sure on how to proceed since I do not know which dll to use. On Monday, 18 June, 2007 11:29 Paul G. Tobey [eMVP] wrote: Are you sure that the device supports notifications? Are you sure that the device supports notifications? Or I guess I should ask, what, specifically are you trying to detect? As to the actual question, in most cases, base OS functions will always be in coredll.dll. Paul T. "BartMan" <MaskProg(a)community.nospam> wrote in message news:82A9E839-50E6-43F7-B36E-99B1ECF24214(a)microsoft.com... On Monday, 18 June, 2007 11:33 Paul G. Tobey [eMVP] wrote: It's in coredll.dll, if it's in your OS at all. it is in coredll.dll, if it is in your OS at all. Back up and tell us what you are trying to monitor for, what version of Windows CE, what device, etc. Paul T. On Monday, 18 June, 2007 11:41 MaskPro wrote: It is a rs-232 device which connects to the pocket pc device via the cf card. It is a rs-232 device which connects to the pocket pc device via the cf card. It is basically a cf card with a rs-232 cable attached to it. Currently when I pull the card out it does post a WM_DEVICECHANGE message, but doesn't give me the device information. Which is why I would like to register the device, so I can tell if a removed device is indeed this card with the rs-232 attached to it. I did try this, and it says that the FindFirstDevice entry point cannot be found. I did post this code in another post, but it is included in this example: code snippet: [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct DEVMGR_DEVICE_INFORMATION { public UInt32 dwSize; public IntPtr hDevice; public IntPtr hParentDevice; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)] public string szLegacyName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string szDeviceKey; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string szDeviceName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string szBusName; } public enum DeviceSearchType : int { DeviceSearchByLegacyName = 0, DeviceSearchByDeviceName = 1, DeviceSearchByBusName = 2, DeviceSearchByGuid = 3, DeviceSearchByParent = 4 } [DllImport("coredll.dll", SetLastError = true)] public static extern IntPtr FindFirstDevice(DeviceSearchType searchType, IntPtr searchParam, ref DEVMGR_DEVICE_INFORMATION pdi); In my c# class I try to test it. void testCode() { try { DeviceSearchType searchType = DeviceSearchType.DeviceSearchByDeviceName; DEVMGR_DEVICE_INFORMATION pdi = new DEVMGR_DEVICE_INFORMATION(); string searchParamString = "COM*"; IntPtr searchParam = Marshal.AllocHGlobal(searchParamString.Length); IntPtr searchParam = Marshal.StringToBSTR(searchParamString); IntPtr deviceHandle = FindFirstDevice(searchType,searchParam, ref pdi); } catch (Exception err) { } } I get the exception "Can't find an Entry Point 'FindFirstDevice' in a PInvoke DLL 'coredll.dll'." The "FindFirstDevice" is not found in the "coredll.dll", so I am not sure on how to proceed since I do not know which dll to use. On Monday, 18 June, 2007 12:00 MaskPro wrote: Re: FindFirstDevice and C# CPU and Version: Dell Axim X50v with Windows Mobile 2003 Second Edition. (4.21.1088) Device I am trying to monitor: The Device is a CF card with a rs-232 connection attached to it. It uses a 3rd party software package which is installed via a CAB file. Purpose: I am trying to track a basic plug-n-play removal and addition of the cf card for this device. I can get the device removal, and addition of it via the WM_DEVICECHANGE. I just want more detailed information about the device that is removed. On Monday, 18 June, 2007 12:44 Paul G. Tobey [eMVP] wrote: Ah! Ah! As far as I can tell, that API is unsupported in Pocket PC 2003. It's not declared in the Pocket PC native SDK, for example. It seems to me that you should be able to get adequate information from the WM_DEVICECHANGE. You're looking at wParam and lParam to see that it's a device removal complete event and that the name of the device being removed is COMn: or something? And that's not enough? Paul T. "BartMan" <MaskProg(a)community.nospam> wrote in message news:14D44D89-257A-4DDB-96CA-12BD1D769450(a)microsoft.com... On Monday, 18 June, 2007 13:34 MaskPro wrote: That makes sense about why I can't get access to it. That makes sense about why I can't get access to it. I didn't notice that in the msdn docs, good find! :) Yes, that would be enough. I can't seem to get the name from the lparam, or wparam. Do you have a recommendation about how I can parse that from the values? On Monday, 18 June, 2007 13:43 Paul G. Tobey [eMVP] wrote: MSDN has good documentation on the parameters that come with that message. MSDN has good documentation on the parameters that come with that message. That's how I found out that it seems like it should be good enough. Here's some of the C I used: ----- void DeviceChange( HWND hWnd, DWORD typ, void *param ) { switch( typ ) { case DBT_DEVICEARRIVAL: RETAILMSG( 1, ( TEXT( "DBT_DEVICEARRIVAL\r\n" ) ) ); break; case DBT_DEVICEREMOVECOMPLETE: RETAILMSG( 1, ( TEXT( "DBT_DEVICEREMOVECOMPLETE\r\n" ) ) ); { DEV_BROADCAST_HDR *hdr = (DEV_BROADCAST_HDR *)param; switch( hdr->dbch_devicetype ) { case DBT_DEVTYP_DEVICEINTERFACE: RETAILMSG( 1, ( TEXT( "DBT_DEVTYP_DEVICEINTERFACE\r\n" ) ) ); break; case DBT_DEVTYP_OEM: RETAILMSG( 1, ( TEXT( "DBT_DEVTYP_OEM\r\n" ) ) ); break; case DBT_DEVTYP_PORT: RETAILMSG( 1, ( TEXT( "DBT_DEVTYP_PORT\r\n" ) ) ); { DEV_BROADCAST_PORT *port = (DEV_BROADCAST_PORT *)hdr; RETAILMSG( 1, ( TEXT( "Device = %s\r\n" ), port->dbcp_name ) ); } break; } } break; } } ----- I don't have a serial card to try, but network cards return DBG_DEVTYP_PORT and the docs seem to indicate that the same would be true of serial ports. Paul T. "BartMan" <MaskProg(a)community.nospam> wrote in message news:61EA35B5-345B-4A45-A87D-CD72B37DB958(a)microsoft.com... On Monday, 18 June, 2007 14:02 MaskPro wrote: Thanks! That is exactly what I needed! Thanks! That is exactly what I needed! It does return the port name for my serial card as you mentioned. Thank you for all of your help!! :) On Friday, 7 August, 2009 7:33 Jarvius wrote: Greetz,I desperately needed some sample C# code using FindFirstDevice, and so Greetz, I desperately needed some sample C# code using FindFirstDevice, and so I started from the code posted here, which has finally been a valuable help for my current project. :) Nevertheless, I had to make some changes, and though I am not allowed to post full code, I guess commenting how to make it work will harm no one... ;) 1. First of all, FindFirstDevice will be of no use unless you use FindNextDevice as well, as you will get a list of devices, not just one - it looks like you are stuck on wildcards. :-P Notice that FindNextDevice will use the handle returned by FindFirstDevice as its first argument, which should not be INVALID_HANDLE_VALUE (-1), and will return True if there are more items to be looked for, so it could be used as a stop condition for your search loop besides comparing the values (szLegacyName) in your pdi - you will have to check both the first pdi returned by FindFirstDevice as well as the new ones that you will get when calling FindNextDevice. 2. If you are serching for COM#:, do not use DeviceSearchByDeviceName, but DeviceSearchByLegacyName instead. Subsequently, pdi.szLegacyName should be the member to go for. I would strongly recommend you setting breakpoints so that you gt to read the full pdi values and see what you can really expect out of it. 3. Remove the IntPtr searchParam = Marshal.AllocHGlobal(searchParamString.Length); line, which is of no use... The line IntPtr searchParam = Marshal.StringToBSTR(searchParamString); already allocates the required memory. Also, remember to be nice and call Marshal.FreeBSTR after FindFirstDevice, so that the unmanaged memory reserved for your string gets deallocated - usual suspect of memory leaks in .Net apps? 4. Finally, and most important point of it all, FindFirstDevice will fail *unless you set pdi.dwSize to its right value*, which you should do right after doing pdi = new ... - pdi.dwSize = (uint)Marshal.SizeOf(pdi); will do. I hope it helps anyone who has to go through unmanaged (and poorly documented) code in C# as I have had to these days. Posted via DevelopmentNow.com Groups http://www.developmentnow.com/g/ EggHeadCafe - Software Developer Portal of Choice Spambot Killer ASP.NET Mailto: Hyperlink Control http://www.eggheadcafe.com/tutorials/aspnet/9817ba6f-ba00-4523-9097-f0235cdcb480/spambot-killer-aspnet-ma.aspx
|
Pages: 1 Prev: CF 1 / C# how to invoke with arguments? Next: My way |