tags:

views:

399

answers:

5

I have the following string: \\\?\hid#vid_04d8pid_003f#62edf110800000#{4d1e55b2-f16f-11cf-88cb-001111000030} stored in a string variable (from a function call) called devPathName

and the following defined: const string myDevice = @"vid_04d8pid_003f";

but the following code always evaluates to false:

Boolean test = true;

test = devPathName.Contains(myDevice);

statusLabel.Text += "\n\tThe value of test: " + test.ToString();
+7  A: 

When I stick your code into C#, the compiler doesn't like the "\h" part of your long string. It says, "unrecognized escape sequence". Could that be your problem?

Oh, and if I put a "@" before the long string, the contains() method returns true.

HTH,

-Dan

DanM
I get these results too.
JeffH
+2  A: 

Assuming that you've already checked for letter "O" vs digit "0" and similar things, I'd suggest that the string you're seeing in the string variable devPathName is being encoded for display and isn't quite what you think it is.

For example, if the string contains the character \x000d (Control-M), the Visual Studio debugger will display this as \r when you inspect the value of the string.

Or, for another example, if the string contains the sequence 3504 (three-five-zero-four) but you instead search for 35O4 (three-five-oh-four) then you'll not find a match.

(Depending on your font, you may not be able to see differences between some characters. Compare "0O1lB8S5" with "0O1lB8S5" in different fonts to see what I mean.)

Bevan
Hhmmm.... do you mean I need to convert it using UnicodeEncoding? I actually retrieve that string from an IntPtr ( `devPathName = Marshal.PtrToStringAuto(pdevPathName);`) but could you please explain what you mean?Thanks
Dark Star1
@dark-star1 - updated my answer with a clarification, hope this is clearer.
Bevan
You and Pat seem to have hit the nail on the head. attempting to use the Path.* threw up exceptions showing that there's a '\r' and '\n' in there somewhere. I'm guessing this is at the beginning of the returned string. Is there a way to side step this or do I have to copy the string, modify and then test it for my substring?
Dark Star1
One good rule of thumb is to always sanity check input that comes from outside your application, whether directly entered by a user or not. As a first step, you could use Trim() to remove leading and training whitespace - but if it was my code, I'd go further to be rigourous.
Bevan
Dark Star1
Bevan
A: 

This returns true for me as well.


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            const string myDevice = @"vid_04d8pid_003f";
            string devPathName = @"\\\?\hid#vid_04d8pid_003f#62edf110800000#{4d1e55b2-f16f-11cf-88cb-001111000030}";
            Boolean test =devPathName.Contains(myDevice);
            MessageBox.Show("\n\tThe value of test: " + test.ToString());
        }
    }
}

I guess I would put a breakpoint in and make sure that devPathName isnt being changed on you and that the value is what you expect.

SwDevMan81
devPathName is returned thus: devPathName = Marshal.PtrToStringAuto(pdevPathName); and pdevPathName: pdevPathName = new IntPtr(deviceDetailDataBuffer.ToInt32() + 4); I have tried all the following: 1) Path.GetFullPath() => returns and exception saying there're control characters (\r\n), but removing the first 4 characters get's rid of this problem. 2) removing the 1st 8 characters such that the string starts with my required substring. Still returns false.
Dark Star1
What type is deviceDetailDataBuffer? Is it a decimal? Where does the value come from? You could create a function to check for only letters/digits and punctuation to remove any escape charactors. See Char.IsLetterOrDigit and Char.IsPunctuation.
SwDevMan81
deviceDetailDataBuffer is an IntPtr that is returned by a function, and the built in string.Replace() functions can apparently remove escape characters.
Dark Star1
You might want to try string path_name = Marshal.PtrToStringAuto(deviceDetailDataBuffer);
SwDevMan81
A: 

What's evaluating to false, your test variable or part of the display in statusLabel.text? Are you sure the display isn't something like this:

The value of test: false
The value of test: false
The value of test: false
The value of test: false
The value of test: true
The value of test: false

and maybe you're only looking at the first line of that string?

Windows programmer
A: 

You just need to escape the long string before parsing it via .Contains()

Put an at-symbol (@) at the start of the string, as demonstrated in several of the previous answers and it should evaluate perfectly.

When stepping into .Contains, the initial string, in your case

\\\?\hid#vid_04d8pid_003f#62edf110800000#{4d1e55b2-f16f-11cf-88cb-001111000030}"

contains none-escaped characters and causes .Contains to terminate before it completes the comparison.

Pat
unfortunately there's no way I can escape it that I know of as this string is supposed to be the path to a device returned from a setupapi* function. Do you know of a way/function that would llow me to filter out control characters such as '\r' and '\n'?
Dark Star1
I think your only option in that case is to save it as a local variable and do whatever you need to before you pass it to .ContainsIf the function you're passing it to doesn't have the ability to return it as a "safe" string.
Pat
Dark Star1
Bevan picked that one. // Credit where credit is due. ;-)Glad you found it and it's working for you.
Pat