Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET String [] operator returns different stuff from ToString()

Tags:

.net

I have a .NET Custom Action (DTF) executing from InstallShield.

In the .NET CA, I'm pulling an MSI property whose value is "[CommonAppDataFolder]abc\def.txt".

The property is accessed as follows:

string val = session["MY_PROPERTY"]; // Microsoft.Deployment.WindowsInstaller.Session

When I print this variable out to a log file, I get: C:\ProgramData\abc\def.txt. This is what I expect.

However, when I use the [] operator to look character-by-character, I get characters from the unsubstituted value: [CommonAppDataFolder]... for example, val[0] is '[' instead of 'C'.

How in the world is this possible?

Also, the ==, string.compare(), !=, etc. are all not giving expected results (I'd imagine these use the [] operator underneath the hood).

EDIT:

This is how I'm logging: session.Log("File name: {0}", val);

This is how I'm printing character-by-character:

for (int i = 0; i < val.Length; i++) 
{ 
    session.Log(val[i].ToString());
}
like image 540
jglouie Avatar asked Jun 26 '26 19:06

jglouie


1 Answers

The string val does still contain the unsubstituted version so the for loop works fine.
The Log() method in the session uses 'val' as a formatstring (and not as a literal) which replaces any placeholders with the actual values before writing the result.

If you download the debug symbols (output is probably not legal to post here) you can see this happening.

In short Log() calls Message() and that calls MsiProcessMessage() in that msdn page it refers to MsiFormatRecord(). At the end of that document it explains the substitutions that take place automatically. Most notably for this case:

  • If a substring of the form [propertyname] is encountered, it is replaced by the value of the property.
  • If a substring of the form [%environmentvariable] is found, the value of the environment variable is substituted.

Try the following code to get your expected results

string formattedVal = session.Format(val)
for (int i = 0; i < formattedVal.Length; i++)  
{  
    session.Log(formattedVal[i].ToString()); 
} 
like image 177
Eddy Avatar answered Jun 30 '26 18:06

Eddy



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!