Convert string to IntPtr - sendmessage

sorry about my English is poor.
I convert string to IntPtr using
COPYDATASTRUCT cd = new COPYDATASTRUCT();
cd.dwData = 0;
cd.lpData = Marshal.StringToHGlobalAuto(Msg).ToInt32();
cd.cbData = Msg.Length;
Marshal.StringToHGlobalAuto(Msg);
and send it to another window using SendMessage method
When i receive it and read the IntPtr as string using
COPYDATASTRUCT CD = (COPYDATASTRUCT)Marshal.PtrToStructure(lParam, typeof(COPYDATASTRUCT));
byte[] B = new byte[CD.cbData];
IntPtr lpData = new IntPtr(CD.lpData);
string temp = Marshal.PtrToStringUni(lpData);
Marshal.Copy(lpData, B, 0, CD.cbData);
string strData = Encoding.Default.GetString(B);
i receive this data
M\0S\0G\0!\0#\01\0|\01\0|\0C\0:\0\\0U\0s\0e\0r\0s\0\\0f\0.\0a\0l\0s\0a\0
When i make strData.Replace("\0","")
i receive my message but it is truncated.
MSG!#1|1|C:\Users\f.alsa
original message is MSG!#1|1|C:\Users\f.alsayyed\Desktop\File.ktb

To me it looks like your replace function found a zero termination earlier then where string ends, as it seems your received data contains zero's inside the string too.

Related

Authenticate to Google Drive services account without json file in .net

I want to authenticate my vb.net Winform application to access my Google drive account. It works fine if I use a json file. But I want to avoid having a plain json file lying around the file system with my private keys in it. Especially when I am going to install the application on another machine.
So I tried to hardcode the credential parameters, with no luck so far. This is what I have tried:
Public Function Authenticate() As DriveService
Dim scope As String = DriveService.Scope.Drive
Dim credential As GoogleCredential
Dim params As New JsonCredentialParameters
With params
.Type = JsonCredentialParameters.ServiceAccountCredentialType
.ProjectId = "myprojid"
.PrivateKeyId = "mykeyid"
.PrivateKey = "-----BEGIN PRIVATE KEY-----\n myprivatekey =\n-----END PRIVATE KEY-----\n"
.ClientEmail = "myappname#myprojid.iam.gserviceaccount.com"
.ClientId = "12345"
End With
credential = GoogleCredential.FromJsonParameters(params).CreateScoped(scope)
Return New DriveService(New BaseClientService.Initializer() With {.HttpClientInitializer = credential, .ApplicationName = "GoogleDriveDownloader"})
End Function
and also this similar approach:
Public Function CreateServiceCredentials() As GoogleCredential
Dim parameters = New JsonCredentialParameters With {
.Type = JsonCredentialParameters.ServiceAccountCredentialType,
.ProjectId = "myprojid",
.PrivateKeyId = "mykeyid",
.PrivateKey = "-----BEGIN PRIVATE KEY-----\n myprivatekey =\n-----END PRIVATE KEY-----\n",
.ClientEmail = "myappname#myprojid.iam.gserviceaccount.com",
.ClientId = "12345"
}
Dim json As String = JsonConvert.SerializeObject(parameters)
Dim stream = New MemoryStream(System.Text.Encoding.UTF8.GetBytes(json))
Return GoogleCredential.FromStream(stream)
End Function
In both cases I get the error: ArgumentException: PKCS8 data must be contained within '-----BEGIN PRIVATE KEY-----' and '-----END PRIVATE KEY-----'. Arg_ParamName_Name
If I remove the trailing \n I get the error: FormatException: The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters.
What am I doing wrong?
I found it out myself, or let's call it a workaround for it:
I just took the whole text of the json file, put it into a winforms textbox and called:
credential = GoogleCredential.FromJson(txt_Credentials.Text).CreateScoped(scope)
Meh, it works ;-)

How to convert Varbinary Column to Base64 String to be saved as Json?

On a SQL database I have a Varbinary column (Content) and I ran the query in Azure Data Studio:
SELECT Id, Name, Content
FROM Files
And the result is:
Id Name Content
1 File1 0xFFD8FFE000104A464946000102 ...
2 File2 0xFFD8FFE000104A464946000102 ...
I exported the result o JSON and tried to deserialise it using Asp.NET Core Json Deserialiser:
Byte[] json = await System.IO.File.ReadAllBytesAsync(path);
List<File> files = JsonSerializer.Deserialize<List<File>>(Encoding.UTF8.GetString(json));
Where File is the following class:
public class File {
public Int32 Id { get; set; }
public Byte[] Content { get; set; }
public String Name { get; set; }
}
But during deserialisation I got the error:
Cannot decode JSON text that is not encoded as valid Base64 to bytes.
I tried to change my SQL query to:
SELECT Id, Name, CAST(CAST('' as XML).value('xs:base64Binary(sql:column("Content"))', 'VARBINARY(MAX)') AS NVARCHAR(MAX)) as [Content]
FROM Files
But I got the same error during deserialisation.
How to convert the varbinary column to Base64 string to be saved as JSON?
Update
I tried to check if it is a Base64 string (to not rely only on the deserialiser) using:
Span<byte> buffer = new Span<byte>(new byte[content.Length]);
var isBase64 = Convert.TryFromBase64String(content, buffer , out int parsed);
But I always get false ...
SELECT Id, Name, CAST('' as XML).value('xs:base64Binary(sql:column("Content"))', 'NVARCHAR(MAX)') as [Content]
FROM Files
declare #binary varbinary(max) = cast(N'{"message":"OK"}' as varbinary(max))
select CAST('' as XML).value('xs:base64Binary(sql:variable("#binary"))', 'NVARCHAR(MAX)') -- ewAiAG0AZQBzAHMAYQBnAGUAIgA6ACIATwBLACIAfQA=
Console.WriteLine(System.Text.Encoding.Unicode.GetString(Convert.FromBase64String("ewAiAG0AZQBzAHMAYQBnAGUAIgA6ACIATwBLACIAfQA="))); --{"message":"OK"}
It is a known github issue here.
A valid base64-encoded string length is always a multiple of 4 (If there is not enough input-data, padding = will therefore get added).
Only one padding = character is accepted by the decoder in 2.1.(Asp.net core 3.0 is also accepted only one padding = after my testing).
To fix such case, be sure that Content in your json string should be a multiple of 4.

JSON deserialization error with Azure translation services

I am building a program in Visual Studio 2017 in Windows Forms - sorry but that's the only thing I know how to use - anyway, most everything for this is C#, so I've been having trouble getting help.
I have translated the Microsoft provided example for a C# program to connect to Azure Cognitive Translation services, signed up, got all my keys, etc.
When I run the code, I get the following error:
Newtonsoft.Json.JsonSerializationException:
'Cannot deserialize the
current JSON object (e.g. {"name":"value"}) into type
System.Collections.Generic.List1[System.Collections.Generic.Dictionary2[System.String,System.Collections.Generic.List1[System.Collections.Generic.Dictionary2[System.String,System.String]]]]'
because the type requires a JSON array (e.g. [1,2,3]) to deserialize
correctly.
To fix this error either change the JSON to a JSON array
(e.g. [1,2,3]) or change the deserialized type so that it is a normal
.NET type (e.g. not a primitive type like integer, not a collection
type like an array or List) that can be deserialized from a JSON
object. JsonObjectAttribute can also be added to the type to force it
to deserialize from a JSON object. Path 'error', line 1, position 9.'
I have tried too many things to list from many different sources. I do not know a whole lot about JSON and am asking for help with the code to solve the above issue.
Public Class DetectedLanguage
Public Property language As String
Public Property score As Double
End Class
Public Class Translation
Public Property text As String
Public Property two As String
End Class
Public Class Example
Public Property detectedLanguage As DetectedLanguage
Public Property translations As Translation()
End Class
Dim textToTranslate As String = root
Dim fromLanguage As String
Dim fromLanguageCode As String = cabbr
Dim toLanguageCode As String = "en"
Dim endpoint As String = String.Format(TEXT_TRANSLATION_API_ENDPOINT, "translate")
Dim uri As String = String.Format(endpoint & "&from={0}&to={1}", fromLanguageCode, toLanguageCode)
Dim body As System.Object() = New System.Object() {New With {Key .Text = textToTranslate}}
Dim requestBody = JsonConvert.SerializeObject(body)
Using client = New HttpClient()
Using request = New HttpRequestMessage()
request.Method = HttpMethod.Post
request.RequestUri = New Uri(uri)
request.Content = New StringContent(requestBody, Encoding.UTF8, "application/json")
request.Headers.Add("Ocp-Apim-Subscription-Key", COGNITIVE_SERVICES_KEY)
request.Headers.Add("Ocp-Apim-Subscription-Region", "westus")
request.Headers.Add("X-ClientTraceId", Guid.NewGuid().ToString())
Dim response = client.SendAsync(request).Result
Dim responseBody = response.Content.ReadAsStringAsync().Result
Dim result = JsonConvert.DeserializeObject(Of List(Of Dictionary(Of String, List(Of Dictionary(Of String, String)))))(responseBody)
Dim translation = result(0)("translations")(0)("text")
rtRoot.Text = translation
End Using
End Using
I have already used the jsonutil site to paste my JSON code in and get the classes.
Here is my JSON content:
[
{
"detectedLanguage":{
"language":"nl",
"score":1.0
},
"translations":[
{
"text":"bord vervangen en uitvoerig getest",
"to":"nl"
},
{
"text":"Board replaced and tested extensively",
"to":"en"
}
]
}
]
OK!!! after playing around with this - Jimi - your solution worked!!! thank you SO much! i had to remove the following to lines: request.Headers.Add("Ocp-Apim-Subscription-Region", "westus") request.Headers.Add("X-ClientTraceId", Guid.NewGuid().ToString())

how to convert JSONOBJECT to JSONARRAY when values are coming in list format?

I'am getting jsonobject as [{"id":"[66]"}] how can i convert to jsonarray?
Here is my code:
public Object[] showCampaigns(#RequestParam("selectedAccId") String selectedAccId, HttpSession session, Model model) {
Object[] responseBody = new Object[1];
List<Long> accountIds=new ArrayList<>();
try {
JSONArray clientjson = new JSONArray(selectedAccId);
for (int i = 0; i < clientjson.length(); ++i) {
JSONObject rec = clientjson.getJSONObject(i);
long id = Long.parseLong(rec.getString("id"));
accountIds.add(id);
}
}
Error I'am gettinbg is:
Long.parseLong(rec.getString("id")) = >Exception occurred in target VM: For input string: "[66]"<
The value for the key id is, as a string, "[66]", which is not actually parsable as a long.
The problem is not necessarily with your code, but with the server from which this response comes, this is where is should be corrected.
If that is not possible:
You need to fetch this as a string, and parse it your own; here is a regex to strip any non digit.
...
// strip any non digit
String number = rec.getString("id").replaceAll("\\D+","");
// parse number only string
long id = Long.parseLong(number);
source of regex
you are trying to parse the String having '[66]' to Long.
You can only transform string which are having only digits to Long
long id = Long.parseLong(rec.getString("id"));
visualize this code as
long id = Long.parseLong("[66]");
Beacuse of this you are getting the issue.
Try to use something like this to remove all punctuation from string including opening and closing brackets.
String stringId= rec.getString("id").replaceAll("\\p{P}","");
long id = Long.parseLong(stringId);

SSIS: Redirecting error rows to file. File contains additional unexpected carriage return

I would like to redirect rows hat could not be loaded into a table to an error file.
I see that the red exception path has 3 Input columns coming in, the "Flat File Source Error Output Column" contains the original data in the file.
The problem is that when I open the file, there is an extra Carriage Return\Line Feed character after every row. I'd like to be able to manually fix the errors and reprocess them without having to delete all of the added CRLF chars. So I added a Script Component to shave of the characters being added.
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
string buffer = GetString(Row.FlatFileSourceErrorOutputColumn.GetBlobData(0, (int)(Row.FlatFileSourceErrorOutputColumn.Length)));
System.Windows.Forms.MessageBox.Show(buffer);
byte[] ThisBytes = GetBytes("Test");
Row.FlatFileSourceErrorOutputColumn.ResetBlobData();
Row.FlatFileSourceErrorOutputColumn.AddBlobData(ThisBytes);
}
static string GetString(byte[] bytes)
{
char[] chars = new char[bytes.Length / sizeof(char)];
System.Buffer.BlockCopy(bytes, 0, chars, 0, bytes.Length);
return new string(chars);
}
static byte[] GetBytes(string str)
{
byte[] bytes = new byte[str.Length * sizeof(char)];
System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
But my debug message box shows non displayable characters that appear as blocks.
When I try to force a literal "TEST" to the output file as a test to see if I could control what goes into the file, I get NULL (ASCII 0) characters after every letter.
Why is SSIS adding a CRLF when I just simply redirect the Output column to the file w/o using a Scripting block component to attempt to modify the data written? How can I get rid of the CRLF? Why am I unable to read the byte array in the data column and display it as a string? Why is the "TEST" literal having NULLS between every letter? Is my ByteArray conversion functions incorrect?
Got it.
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
string buffer = GetString(Row.FlatFileSourceErrorOutputColumn.GetBlobData(0, (int)(Row.FlatFileSourceErrorOutputColumn.Length - 2)));
System.Windows.Forms.MessageBox.Show(buffer);
byte[] ThisBytes = GetBytes(buffer);
Row.FlatFileSourceErrorOutputColumn.ResetBlobData();
Row.FlatFileSourceErrorOutputColumn.AddBlobData(ThisBytes);
}
static string GetString(byte[] bytes)
{
System.Text.Encoding enc = System.Text.Encoding.ASCII;
return enc.GetString(bytes);
}
static byte[] GetBytes(string str)
{
System.Text.Encoding enc = System.Text.Encoding.ASCII;
return enc.GetBytes(str);
}
I would still like to know why SSIS is adding the CRLF!