|
Hello,
I managed to use several network Windows API inside C# code with DllImport (such as GetAdaptersInfo) but the GetIfTable seems to be a little bit different.
My problem is that i need to obtain the data in the MIB_IFROW structure and it gets filled with zeros instead of the corect information.
Here is the source code of a simple console application where the problem occurs:
<br />
using System;<br />
using System.Runtime.InteropServices;<br />
using System.Runtime;<br />
<br />
namespace ConsoleApplication1<br />
{<br />
public class Win32Import<br />
{<br />
public static uint ERROR_NOT_SUPPORTED = 50;<br />
<br />
public const int MAXLEN_IFDESCR = 256;<br />
public const int MAXLEN_PHYSADDR = 8;<br />
<br />
public const int MAX_INTERFACE_NAME_LEN = 256;<br />
<br />
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]<br />
public struct MIB_IFTABLE<br />
{<br />
public uint dwNumEntries;<br />
public MIB_IFROW table;<br />
};<br />
<br />
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]<br />
public struct MIB_IFROW<br />
{<br />
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_INTERFACE_NAME_LEN)]<br />
public string wszName;<br />
<br />
public uint dwIndex;<br />
public uint dwType;<br />
public uint dwMtu;<br />
public uint dwSpeed;<br />
public uint dwPhysAddrLen;<br />
<br />
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MAXLEN_PHYSADDR)]<br />
public byte[] bPhysAddr;<br />
<br />
public uint dwAdminStatus;<br />
public uint dwOperStatus;<br />
public uint dwLastChange;<br />
public uint dwInOctets;<br />
public uint dwInUcastPkts;<br />
public uint dwInNUcastPkts;<br />
public uint dwInDiscards;<br />
public uint dwInErrors;<br />
public uint dwInUnknownProtos;<br />
public uint dwOutOctets;<br />
public uint dwOutUcastPkts;<br />
public uint dwOutNUcastPkts;<br />
public uint dwOutDiscards;<br />
public uint dwOutErrors;<br />
public uint dwOutQLen;<br />
public uint dwDescrLen;<br />
<br />
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MAXLEN_IFDESCR)]<br />
public byte[] bDescr;<br />
};<br />
<br />
<br />
[DllImport("kernel32.dll", EntryPoint = "CopyMemory")] public extern static void<br />
CopyMemory_Int(<br />
ref uint Destination,<br />
ref byte Source,<br />
int Length<br />
);<br />
<br />
[DllImport("kernel32.dll", EntryPoint = "CopyMemory")] public extern static void<br />
CopyMemory_MibIfrow(<br />
ref MIB_IFROW Destination,<br />
ref byte Source,<br />
int Length<br />
);<br />
<br />
[DllImport("iphlpapi.dll")] public extern static uint<br />
GetIfTable(<br />
byte[] pIfTable,<br />
ref uint pdwSize,<br />
bool bOrder<br />
);<br />
}<br />
<br />
<br />
class Class1<br />
{<br />
[STAThread]<br />
static void Main(string[] args)<br />
{<br />
uint nBufLen = 0;<br />
uint nError;<br />
<br />
nError = Win32Import.GetIfTable(null, ref nBufLen, true);<br />
if (nError == Win32Import.ERROR_NOT_SUPPORTED)<br />
{<br />
return;<br />
}<br />
<br />
byte[] IfTableBuffer = new byte[nBufLen];<br />
nError = Win32Import.GetIfTable(IfTableBuffer, ref nBufLen, true);<br />
if (nError != 0)<br />
{<br />
return;<br />
}<br />
<br />
uint dwNumEntries = 0;<br />
int byteCount = 0;<br />
<br />
Win32Import.CopyMemory_Int(ref dwNumEntries, ref IfTableBuffer[byteCount], 4);<br />
byteCount += 4;<br />
<br />
Win32Import.MIB_IFROW pIfRow = new Win32Import.MIB_IFROW();<br />
Win32Import.CopyMemory_MibIfrow(<br />
ref pIfRow,<br />
ref IfTableBuffer[byteCount],<br />
Marshal.SizeOf(pIfRow)<br />
);<br />
byteCount += Marshal.SizeOf(pIfRow);<br />
}<br />
}<br />
}<br />
If you are familiar with these C# API calls and think you can help me , you're welcome. Many thanks!
|
|
|
|
|
First, use the out keyword instead of ref in the first parameter of GetIfTable to avoid having to instantiate the structure. Not a big deal, but it is the correct declaration.
Also, you're MIB_IFROW structure is incorrect. First, the first string member is a WCHAR - a wide character (2 bytes). Therefore, your CharSet in the StructLayoutAttribute should be set to CharSet.Unicode . The UnmanagedType.ByValTStr will then cause the marshaler to use what the CharSet in the StructLayoutAttribute declares, namely a Unicode string (an array of WCHAR s).
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
It works!
I didn't thought that this mistake would be the reason of the problems.
But it's logic as Unicode and ANSI characters don't have the same size.
Thank you very much!
|
|
|
|
|
I'm using a MonthCalendar control in a C# winforms application and have discovered that if you click the text above the calendar which displays the year, two scroll buttons appear to allow you to scroll through the years. The up button scrolls into the future and a new date is selected as each year is scrolled. The down button scrolls back in time, but instead of selecting a single new date, a date range is selected. Does anyone know of a method/property that can be adjusted to turn off this behaviour for the down scroll button? Thanks.
Chris Meech
We're more like a hobbiest in a Home Depot drooling at all the shiny power tools, rather than a craftsman that makes the chair to an exacting level of comfort by measuring the customer's butt. Marc Clifton
VB is like a toolbox, in the hands of a craftsman, you can end up with some amazing stuff, but without the skills to use it right you end up with Homer Simpson's attempt at building a barbeque or his attempt at a Spice rack. Michael P. Butler
|
|
|
|
|
If you don't want a range of dates to be selectable at all, set MonthCalendar.MaxSelectionCount to 1. If you only want a single date selected while changing dates, you could handle the MonthCalendar.DateChanged and select only the MonthCalendar.SelectionStart date.
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
Heath Stewart wrote:
set MonthCalendar.MaxSelectionCount to 1.
I have the property set to a value of 1 already. I expect that this is a subtle bug I've stumbled across. The odd part is that for two seemingly similar actions, year/scroll-up or year/scroll-down, the control behaves differently.
Chris Meech
We're more like a hobbiest in a Home Depot drooling at all the shiny power tools, rather than a craftsman that makes the chair to an exacting level of comfort by measuring the customer's butt. Marc Clifton
VB is like a toolbox, in the hands of a craftsman, you can end up with some amazing stuff, but without the skills to use it right you end up with Homer Simpson's attempt at building a barbeque or his attempt at a Spice rack. Michael P. Butler
|
|
|
|
|
Chris Meech wrote:
I have the property set to a value of 1 already. I expect that this is a subtle bug I've stumbled across.
Hmm, you might be right. You could take a look at the Month Calendar Common Control (http://msdn.microsoft.com/library/en-us/shellcc/platform/commctls/monthcal/reflist.asp[^]) that the MonthCalendar encapsulates. Perhaps there's something you can do by extending the MonthCalendar and overriding WndProc to handle notification messages, though I don't really see any off-hand that would help, unfortunately.
Have you tried the method of handling the DateChanged event and simply setting the SelectionEnd to SelectionStart ? It's a bad hack, but I don't see why it wouldn't work.
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
Heath Stewart wrote:
Have you tried the method of handling the DateChanged event and simply ...
I'll probably end up doing that, as this is purely a cosmetic kind of issue. I got bigger fish to fry at the moment as I try and get a WebService to connect and run queries from an Oracle database. But thanks for the suggestions.
Chris Meech
We're more like a hobbiest in a Home Depot drooling at all the shiny power tools, rather than a craftsman that makes the chair to an exacting level of comfort by measuring the customer's butt. Marc Clifton
VB is like a toolbox, in the hands of a craftsman, you can end up with some amazing stuff, but without the skills to use it right you end up with Homer Simpson's attempt at building a barbeque or his attempt at a Spice rack. Michael P. Butler
|
|
|
|
|
I am redesigning the UI for one of our data editors. I have an Infragistics ListBar main panel on the left(Dock=left), a slider (Dock=left), and a control area where the different edit controls are dynamically constructed(Dock=fill).
At design time I also added a second panel for groups. That panel and its' slider are Dock=left and marked Disabled, NOT Visible. I have one button on the main panel for opening the group selector whenever the editor wants to group items into a manageable group. I have tried numerous ways to make this group panel appear...all in vain. Here is my last attempt:
this.controlArea.Dock = DockStyle.None;
this.controlArea.Size = new Size(10, 10);
this.groupDisplay.Enabled=true;
this.groupDisplay.Visible = this.groupDisplay.Visible=false?true:false;
this.groupDisplay.Size = new Size(3, 453);
this.grpSplit.Enabled = true;
this.grpSplit.Visible= this.grpSplit.Visible=false?true:false;
this.controlArea.Dock = DockStyle.Fill;
this.Invalidate(true);
The panel does not become visible no matter what!!! Any suggestion would be appreciated.
Michael
_____________________________________________
Of all the senses I could possibly lose, It is most often the one called 'common' that gets lost.
|
|
|
|
|
You have a problem here:
this.groupDisplay.Visible = this.groupDisplay.Visible=false?true:false; You're setting Visible to false , not testing it. For that, use the == operator. In fact, just dump it all together and toggle the value with the following expression:
this.groupDisplay.Visible = !this.groupDisplay.Visible;
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
DOH!
Guess I shouldn't code with only 4 hours of sleep.
Thanks Heath
_____________________________________________
Of all the senses I could possibly lose, It is most often the one called 'common' that gets lost.
|
|
|
|
|
I would like to add "panels" to my application which behave like the Visual Studio .NET IDE "ToolBox", "Solution" and "Properties" "Panels". These panels have a tab when retracted, and when your cursor goes over them they expand out, and retract when your cursor moves off of them. Or you can click the pushPin and they remain expanded. Does any one know the control these are built on? Does anyone know of any source code examples?
|
|
|
|
|
There used to be the Magic Library which provided a free control that had that type of behaviour. However, they are now charging $300 for it!
Infragistics controls also provide the capability.
In both cases, they deployed a manager that handled all of the paint events and causing the sliding, tabs, etc. Then for magic you just add a form to the manager and in the Infragistics control you just right click a control and select Add to Tab.
So that gives you a general direction they took.
_____________________________________________
Of all the senses I could possibly lose, It is most often the one called 'common' that gets lost.
|
|
|
|
|
Hi,
I am showing a form creating user profile where it asks for passwords. When he searches for a user the password that is shown is MD5 encrypted, now if he clicks update the encrypted password is again encrypted as I don't know how to find if the password displayed is already a MD5 encrypted string or not.
Any suggestions !?!
Thanks,
Paul
|
|
|
|
|
You could either store a value that dictates whether the password is already hashed. For instance, some clients have a "Remember password" (or similar) option. This value would be stored in the registry or a file along with the hashed password. Check this value and, if set, don't hash the password again.
You could also determine if the length of the string is 32 characters in length, although this is not the best test since some users might have passwords that long (doubtful, but possible). You could, though, limit the password length to something less than 32 characters, so that if you get a "password" that is 32 characters long you know it is already hashed.
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
Hi there,
Is it possible to separate declarations and implementations in C#?
like for C++ I want to separate the declarations of the classes in a header and implementations in a cs file...
Thanks.
bouli.
|
|
|
|
|
No, its not possible to separate the declaration from the implementation. There is no need for that to happen as you don't need to #include headers anywhere. IMO that is one of the better features of C# over C++.
Out of curiosity why do you want to do this anyway?
--Colin Mackay--
EuroCPian Spring 2004 Get Together[^]
"You can have everything in life you want if you will just help enough other people get what they want." --Zig Ziglar
|
|
|
|
|
ok, thanks for the information,
as I have C++ & MFC backgrounds, I want to upgrade my knowledges to C#...
|
|
|
|
|
You should start with the C# Language Specifications at http://msdn.microsoft.com/library/en-us/cscon/html/vcoriCStartPage.asp[^]. Also understand that C# is just another language that targets the Common Language Runtime (CLR), the runtime part of the .NET Framework. All .NET compilers compile to similar IL. The only differences in the generated IL usually have to do with compiler optimizations, but some languages support features of the .NET Framework that others don't. For example, C# supports unsafe contexts (in order to use pointers for, say, quick string parsing) while VB.NET does not (yet). But this is not really a feature of C# per se, but a feature of the .NET Framework that C# supports.
Also understand that assemblies written in any source languages can be used by any other managed language.
Finally, there is also Managed C++ that can compile down to IL in an assembly. The major thing to realize here is that you can use mixed mode or pure managed code. Mixed mode includes native implementations that aren't managed by the CLR while pure managed code is.
It's call "managed" because the CLR managed the memory (though classes that encapsulate native resources like Windows should implement IDisposable and clean-up the native resources since they aren't managed by the CLR).
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
Hi,
Thanks for your reply.
I know that there is MC++ that can access to CLR, but I wanna learn C#. C# seems to be more convinent to access .NET features. I have to write an application that targets Excel 2003 in C#. I don't want to program Excel 2003 with C++, it would be too complex, while Excel 2003 is designed to be easily accessed via C# or VB .NET...
While learning C# which I discover since last monday, I need to get the equivalents between C++ and C# to go faster in my learning, for this, I translate some simple MFC applications in C#...
C# in itself is easy (it's very similar to C++), but it's the .NET framework that is not easy for a beginner in .NET. I have the same feelings with .NET that I had with MFC 10 years ago: " wow!"
best regards.
bouli.
|
|
|
|
|
I only mentioned that about MC++ to help you better understand the .NET Framework. I read that you wanted to learn C#.
You should also scan through the .NET Base Class Library reference in your help files (or on MSDN Online). Knowing what's there is good so that you can think of better solutions using what's provided. Also look through them any articles here on CodeProject for examples of programming with C#. There's also several examples in the .NET Framework SDK.
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
This site, some books and MSDN library are my starting point...
|
|
|
|
|
Colin Angus Mackay wrote:
No, its not possible to separate the declaration from the implementation. There is no need for that to happen as you don't need to #include headers anywhere. IMO that is one of the better features of C# over C++.
This is not inherently correct. While it maybe in the context of C++ (i.e.; no header files in C#), you can have a separate file that is part of the same namespace which simply defines interfaces. These interfaces can then be implemented throughout your application as a whole. This could be seen as a separation of declaration and implementation.
- Nick Parker My Blog
|
|
|
|
|
Nick Parker wrote:
This is not inherently correct. While it maybe in the context of C++ (i.e.; no header files in C#), you can have a separate file that is part of the same namespace which simply defines interfaces. These interfaces can then be implemented throughout your application as a whole. This could be seen as a separation of declaration and implementation.
That's Wright.
Thank You
Bo Hunter
|
|
|
|
|
Has anybody attempted the following? If not, once I've done it, I'll submit the article!
I want to set up a class that holds a collection of arrays and lets you set up calculations on the arrays that are then run as a block. The calling code would then look something like:
ArrayContainer ac = new ArrayContainer(0, 250);
ContainedArray array1 = ac.NewArray();
ContainedArray array2 = ac.NewArray();
ContainedArray array3 = ac.NewArray();
ac.DefineCalculations();
array1.CurrentRow = array2.CurrentRow + array3.LastRow;
array2.CurrentRow = array2.LastRow - 3;
array3.CurrentRow = array1.LastRow * 2;
ac.DoCalculations();
The last line makes it go through all 251 rows of the three arrays iteratively carrying out the calculations.
Many thanks
Bernard
|
|
|
|
|