It looks like your confusion comes from misunderstanding what varbinary is. varbinary is a string of bytes, not chars. It is not even really a string, it is an array of bytes.
varbinary can be represented as a string of hexadecimal values and varbinary constants in T-SQL code are represented as hexadecimal strings. Two hexadecimal characters per byte.
The SUBSTRING function in T-SQL can work with strings (varchar) and with bytes (varbinary).
Syntax
SUBSTRING ( expression ,start , length )
The values for start and length must be specified in number of
characters for ntext, char, or varchar data types and bytes for text,
image, binary, or varbinary data types.
So, the following T-SQL trigger code
declare @ctxt varbinary(128)
select @ctxt=context_info from master.dbo.sysprocesses where spid = @@spid
set @session=substring(@ctxt,1,4)
takes first 4 bytes (not chars) from the @ctxt array of bytes and assigns them to the @session variable. What type is @session? Most likely it is int.
Run this sample code in SSMS and you'll see the hexadecimal representation of some integers:
DECLARE @T TABLE (I int);
INSERT INTO @T VALUES
(0),
(1),
(3),
(19),
(255),
(256),
(512),
(768),
(4098),
(65535),
(65536),
(131072),
(1234567890),
(-1),
(-65535);
SELECT
I, CONVERT(varbinary(120), I) AS BinI
FROM @T;
Result
+------------+------------+
| I | BinI |
+------------+------------+
| 0 | 0x00000000 |
| 1 | 0x00000001 |
| 3 | 0x00000003 |
| 19 | 0x00000013 |
| 255 | 0x000000FF |
| 256 | 0x00000100 |
| 512 | 0x00000200 |
| 768 | 0x00000300 |
| 4098 | 0x00001002 |
| 65535 | 0x0000FFFF |
| 65536 | 0x00010000 |
| 131072 | 0x00020000 |
| 1234567890 | 0x499602D2 |
| -1 | 0xFFFFFFFF |
| -65535 | 0xFFFF0001 |
+------------+------------+
Your C# code in the question doesn't make much sense. Wrapping both strInt + strUser into CONVERT(varbinary(120), N'" + strContextValue + "') doesn't make sense.
The C# code should construct the binary array. The T-SQL trigger code expects that first 4 bytes of this array is @session, next 4 bytes is @contextid. bytes, not characters.
So, if you want to pass, say, 131072 decimal as @session, 1234567890 decimal as @contextid, plus myself$ string as extra info you should run the following T-SQL code:
declare @context_info varbinary(128); -- note 128 length here
set @context_info = 0x00020000;
-- note, there are no quotes around the constants, they are numbers, not strings
set @context_info = @context_info + 0x499602D2;
set @context_info = @context_info + CONVERT(varbinary(120), N'myself$');
-- note 120 length here, first 8 bytes are used by two integers
set context_info @context_info;
Run this code in SSMS, but replace of the last line with SELECT @context_info; to see what it does. You'll get the following result:
+------------------------------------------------+
| (No column name) |
+------------------------------------------------+
| 0x00020000499602D26D007900730065006C0066002400 |
+------------------------------------------------+
You can see the binary representation of two integers plus binary representation of the unicode text string.
In C# you construct this code by concatenating hexadecimal representation of integers.
Note, that you should not enclose 0x00020000 and 0x499602D2 into quotes or CONVERT(varbinary, ...). You should enclose only the myself$ string into the CONVERT(varbinary, ...).
The C# code should look something like this:
string strUser = "myself$";
int iSession = 131072;
int iContextID = 1234567890;
StringBuilder sb = new StringBuilder();
sb.Append("declare @context_info varbinary(120);");
sb.Append("set @context_info = 0x");
sb.Append(iSession.ToString("X8"));
sb.Append(";");
sb.Append("set @context_info = @context_info + 0x");
sb.Append(iContextID.ToString("X8"));
sb.Append(";");
sb.Append("set @context_info = @context_info + CONVERT(varbinary(120), N'");
sb.Append(strUser);
sb.Append("');");
sb.Append("set context_info @context_info;");
string strContext = sb.ToSTring();
SqlCommand scContext = new SqlCommand(strContext, conn, tran);
scContext.ExecuteNonQuery();
See also C# convert integer to hex and back again