|
If you read the linked documentation in the Platform SDK PIDLs are discussed in great detail. The easiest way to get these is to navigate from the desktop to the shell namespace and/or folder to get the PIDL. You can do this easily by creating an RCW (runtime-callable wrapper) using either tlbimp.exe or adding a reference to your project using the COM tab for the "Microsoft Shell Controls and Automation" typelib.
See the Shell Objects for Scripting[^] for documentation. How you use the classes is essentially the same (though not 100%) because the automation objects provide functionality to automation clients like Windows Script, VB6, and RCWs.
It would be easier and require less dependency to P/Invoke SHParseDisplayName , but you really must read the documentation to understand what you're passing, since it requires that you also pass an IBindCtx (the interface is declared as System.Runtime.InteropServices.UCOMIBindCtx , but you must still get an instances by P/Invoking CreateBindCtx ).
Experience with shell programming and COM is extremely helpful, and there's a lot of information in the Platform SDK to give you hints on how to do this. Understanding COM interop is also important.
If you have specific questions, please ask. Do first read the documentation, however, since you need to understand the native code in order to know what and how to P/Invoke it correctly, like redefining your SHGetFileInfo signature to access either a string marshaled correct (see the Marshal class for help) or a PIDL, which is an ITEMIDLIST structure which you may or may not have to define depending on how you use it (you could just declare it as an IntPtr if you don't need to parse it yourself).
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
If thread A raises an event E and thread B has the handler, is there any different to use E(...) and E.BeginInvoke(...)? They are both asynchronous anyway, right?
|
|
|
|
|
No, they are not both asynchronous. If you simply invoke an event (a MulticastDelegate ) it is fired in the context of the calling (invoking) thread. If you use BeginInvoke a new thread from the thread pool is grabbed and used to execute the handler. If you want to execute the handler on the thread that instantiated the class (very important for Control classes in Windows Forms), then the object implementing the handler must implement ISynchronizeInvoke (or similar functionality - that that would be up to you) and you call its ISynchronizeInvoke.Invoke implementation.
Read Handling and Raising Events[^] and Threading[^] in the .NET Framework SDK for more information. You should also read the documentation[^] for the Control.Invoke method if you're dealing with threading in a Windows Forms application.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
I debugged the code step by step. What confused me is why when I invoked an event from a thread (NOT using begininvoke), the code immediately returned and continued to execute rest of code in the calling thread? Isn't it supposed to run the delegate func first and then return?
|
|
|
|
|
Did you have a break point in your event handler? If you're just stepping into code, IIRC, it won't trace into the delegates. Using Debug.WriteLine is another useful way to debug such issues and won't be compiled into release builds (so you don't have to remove it or use pre-proc conditions when compiling for release builds).
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
I used Debug.WriteLine. And that revealed the event.invoke is synchronous call. You are absolutely right. I guess step-by-step is not that trustworthy when dealing with events.
Thank you!
|
|
|
|
|
Hi,
I am trying to calling Visual C++ dll function in C#.
This is function I am trying to call from dll.
float CMD_RD(int port, int address, int *err_type, int *err_attr)
Here is my code.
public class OmegaBusWrap
{
[DllImport("C:\\work\\Eco-now\\Code\\OmegaBus\\OmegaLib\\cmd_dll.DLL",
EntryPoint="CMD_RD", SetLastError=true,
CharSet=CharSet.Auto, ExactSpelling=true,
CallingConvention=CallingConvention.StdCall)]
public static extern float CMD_RD(int port, int ddress,IntPtr
err_type, IntPtr err_attr);
}
Here I am calling this function in my code
IntPtr err_type = new IntPtr(0);
IntPtr err_att = new IntPtr(0);
float fvalue;
try
{
fvalue = OmegaBusWrap.CMD_RD(m_PortNo,1,err_type,err_att);
}
catch(Exception e)
{
Debug.WriteLine(e.ToString());
}
I got exception this exception
System.NullReferenceException: Object reference not set to an instance of an object.
at OmegaBusSerial.OmegaBusWrap.CMD_RD(Int32 port, Int32 address, IntPtr err_type, IntPtr err_attr)
What I am doing wrong, How can I solve this problem.
Thanks.
|
|
|
|
|
Never hard-code a path to a DLL in your DllImportAttribute . Add the DLL to your PATH environment variable or to the current application directory. By doing what you're doing you limit where your application can be installed. Users may not even map their C: drive in Windows NT. Utilize the features of the OS correctly.
An IntPtr doesn't necessary mean the same as an int* in native code. An IntPtr is also processor-dependent, being 32 bits on a 32-bit CPU and 64-bits on a 64-bit CPU.
Depending on whether or not your last two parameters are in/out or just out, use the keyword ref or out respectively.
If those are in/out - and they would appear to be judging by the exception - you are actually trying to pass the address of NULL. That's an access violation in native code, which yields a NullReferenceException in managed code. Why, because the address of NULL (or 0) is not a reference to anything.
So, it would appear the correct declaration of your function is:
[DllImportAttribute("cmd_dll.dll", ExactSpelling=true)]
static extern float CMD_RD(int port, int address, ref err_type, ref err_attr); The rest of the fields of DllImportAttribute aren't necessary. CharSet , for example, is only necessary when you take a string as a parameter. You only use SetLastError if your function actually uses the SetLastError native API, etc. Read the documentation for the DllImportAttribute for more details.
Also - never export a native function publicly. Encapsulate native functionality for 2 reasons: 1) to provide a level of abstraction so as to control the conditions and parameters of when a function can be called, and 2) because malicious code could use your method to execute arbitrary commands if your assembly asserts P/Invoke permissions.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
I'm just trying to flip an image with the built in rotate flip function. I've put it in a case switch which gets called then I push a radio buttion. The function is getting called but nothing is happening!
I push the nintey degrees flip radio button to set a class variable case to 0.
<br />
private void NinetyDegrees_CheckedChanged(object sender, System.EventArgs e)<br />
{<br />
this.m_iCase = 0;<br />
}
Then a push a button called transform image to call this switch.
private void TransformImage_Click(object sender, System.EventArgs e)<br />
{<br />
<br />
switch (this.m_iCase) <br />
{<br />
case 0 :<br />
MainPictureViewer.Image.RotateFlip(RotateFlipType.Rotate90FlipNone); <br />
break;<br />
case 1 :<br />
MainPictureViewer.Image.RotateFlip(RotateFlipType.Rotate180FlipNone);<br />
break;<br />
case 2 :<br />
MainPictureViewer.Image.RotateFlip(RotateFlipType.Rotate270FlipNone);<br />
break;<br />
<br />
}<br />
}<br />
Nothing happens...
|
|
|
|
|
MainPictureViewer.Refresh()
Charlie
if(!curlies){ return; }
|
|
|
|
|
|
I've got a bug report on a system that runs on multiple machines in the field, all but one in an obcsure location. This one, they had to reinstall W2K, then they reinstalled the software, and they get this error:
As best I can read it and I tried ringing the guy who wrote it but he is out of the office and can't remember exactly. It goes like this .
JUKEBOX.EXE_ENTRY POINT NOT FOUND
X The procedure entry point get raw input oem of list
could not be located in the dynamic link library
user 32.dll
The caveats are retained to show that I'm working off an email and it could be sketchy. The software uses MSDE, and imports stuff from various DLLs, for example to read joystick output ( but I'm sure there's other interop stuff as well ). It runs fine when they click OK after this error. Does anyone have any suggestions ? I cannot physically go to the machine to check it out.
Christian
I have several lifelong friends that are New Yorkers but I have always gravitated toward the weirdo's. - Richard Stringer
|
|
|
|
|
They got what error?
If the code is P/Invoking a function from user32.dll have they updated to the latest SP level for Win2K (sp4, IIRC)? It's unlikely that's the problem since it rarely changes (especially to the point of adding new entry points), but it's possible.
I should be able to help more if you post the exception that was thrown.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
The error message, as relayed over the phone and then sent to me via email is
JUKEBOX.EXE_ENTRY POINT NOT FOUND
X The procedure entry point get raw input oem of list
could not be located in the dynamic link library
user 32.dll
They won't have installed any service packs I reckon, so I'll get them to try that.
jukebox.exe is the program they are running, and it runs perfectly well, no reported errors, after this message. The joystick stuff is used to collect input from the coin mechanism, so if that wasn't working, I'd definately know about it.
Thanks for your help.
Christian
I have several lifelong friends that are New Yorkers but I have always gravitated toward the weirdo's. - Richard Stringer
|
|
|
|
|
Sorry. Since you inserted a paragraph between your colon and the actual error it didn't really make sense.
It's hard to know what the problem is. Unless they're trying to P/Invoke an exported function - rare for EXEs and it requires custom load code to resolve relative addresses - the only entry point that matters is the main function (which is vastly different under different circumstances). Since the program proceeds to run that is just weird. The format of the error is also odd.
Could it be that the EXE is trying to dynamically load a function via its proc address and is reporting back an error? If they can, have them take a look at the process list while this error is displayed to see if the executable is even running. If so, the problem is with the EXE itself.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
I wrote the exe, and I definately don't try to dynamically load functions via proc addresses.
So if they check the process list when the error message comes up, if the program is in the list, the trouble is in the exe, right ?
Thanks again
Christian
I have several lifelong friends that are New Yorkers but I have always gravitated toward the weirdo's. - Richard Stringer
|
|
|
|
|
Yes, that would (most likely) be correct. Does the EXE statically bind with anything else? It shouldn't start if it does and the library isn't found, but it obviously is.
Are you familiar at all with the code that invokes the EXE?
At any rate, upgrading to the latest SP4 is not only a likely solution to the problem, but it'd be absurd not to for security and stability reasons (and no matter who's marketing says what, every OS needs patching now and again, but I would only expect the usual bandwagon crap from the Lounge or /. so I digress...).
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
Yeah, either way I've recommended SP4 to them. I always patch, with the sole exception of XP SP2, which sadly kills our application on my notebook.
I'll recommend that and see how we go.
Christian
I have several lifelong friends that are New Yorkers but I have always gravitated toward the weirdo's. - Richard Stringer
|
|
|
|
|
How does your application die? IMO, fix the issue with XP SP2 but don't force your clients to stick with SP1. XP RTM support is ending soon, meaning they'll have to go with SP1 or 2. When SP3 comes out expect SP1 support to go the way of the dodo.
Is it because of the firewall? There are ways to add your application into the exception list programmatically. See Adding an Application (VBScript)[^] for an example, keeping in mind that the same automation objects script can use you can use through an RCW.
There's a few DCOM issues (i.e., fixes) that can cause problems, with workarounds posted online.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
No, our clients can use SP2, in fact everyone else here at work can, too. The firewall broke our app, but we figured out how to fix that. However, my notebook was the only machine on which, once we applied all the same fixes we applied elsewhere, and everyone here looked at it, the application continued not to work.
Maybe when SP3 comes out, I'll try again, and see if progressive fixes have solved my problem.
Christian
I have several lifelong friends that are New Yorkers but I have always gravitated toward the weirdo's. - Richard Stringer
|
|
|
|
|
Is there any .Net method that compares a mask to a file name and returns if they match ?
I'm aware of Directory.GetFiles(), I need to compare objects in memeory not on disk.
i.e. compare "This???Match.*" to "ThisIsAMatch.txt"
thanks
|
|
|
|
|
Regular Expressions.
Christian
I have several lifelong friends that are New Yorkers but I have always gravitated toward the weirdo's. - Richard Stringer
|
|
|
|
|
I am absolutely useless at Math, always have been, always will be. Despite this I continue to write software. I needed a way to reverse a decimal no matter it's original sign so that if it was positive it would become negative to the same absolute degree and vice versa. Zero remains zero.
To accomplish this I wrote this function:
<hr><br />
private decimal Reverse(decimal dIn)<br />
{<br />
if(System.Math.Sign(dIn)==0) return 0M;<br />
if(System.Math.Sign(dIn)==-1) return System.Math.Abs(dIn); <br />
return 0M-dIn;<br />
}<hr>
I couldn't find a built in function to do that, is this crazy or really the only way to do this?
|
|
|
|
|
how about return -dIn ? Surely - -1 = 1 ?
Christian
I have several lifelong friends that are New Yorkers but I have always gravitated toward the weirdo's. - Richard Stringer
P.S. The one vote was not me, you got my 5, partially because the 1 had no reason that I could see, and partially because the line 'despite this I continue to write software' made me smile.
|
|
|
|
|
I've long ago given up trying to understand the vagaries of the voting system, but it was probably a vote to have me stop writing software. I've always been privately amused at how little math you really need to know to write software, non-programmers think it's the be all and end all of computer programming, I just look it up, but I guess this was just something so simple that it isn't really documented anywhere. Anyway, never being afraid to look stupid I just thought I would ask here!
I didnt know you could just stick a negative sign in front of it like that, but if that's the case and zero doesn't throw an exception or anything then that rocks and you rock as well!
Thank you!
|
|
|
|
|