I've tried to develop an NSIS Plugin in C++.
Here is my method to set informations from NSIS:
void __declspec(dllexport) SetCredentials(HWND hWndParent, int string_size, TCHAR *variables, stack_t **stacktop, extra_parameters *extra) {
EXDLL_INIT();
server = getuservariable(INST_0);
port = myatou(getuservariable(INST_1));
database = getuservariable(INST_2);
username = getuservariable(INST_3);
password = getuservariable(INST_4);
MessageBox(hWndParent, server, L"Info", MB_OK); // Here is the problem
setuservariable(INST_0, server);
}
Sample:
OutFile "Example.exe"
BrandingText " "
Section
MySQL::SetCredentials "localhost" 3306 "banananode" "root" ""
Pop $0
MessageBox MB_OK "Server: $0" ; Returns the server value...
SectionEnd
The Problem is, when i try to print out the server variable, chinese characters will be shown, not the correct text:
When i return the value with setuservariable(INST_0, server);, NSIS will be display it correctly:
Can you tell me, whats wrong?
I've tried to build the resulted .dll with pluginapi-x86-ansi.lib and pluginapi-x86-unicode.lib but the result is the same...
ANSI characters interpreted as Unicode (UTF-16LE) tends to look Chinese.
When you create a Unicode plug-in you need to:
Make sure UNICODE and _UNICODE is defined in your project/.C files.
Link with pluginapi-x86-unicode.lib
Add Unicode True to your .NSI
Place the plug-in in \NSIS\x86-unicode
In your case you most likely forgot about Unicode True. Returning the value works because you never actually changed the memory of server, it is still the same input string.
Related
I'm trying to install a kernel driver from an MFC application using CreateService function and I'm not sure that I fully understand how lpBinaryPathName parameter is supposed to be set up.
Quoting MSDN:
The fully qualified path to the service binary file. If the path
contains a space, it must be quoted so that it is correctly
interpreted. For example, "d:\my share\myservice.exe" should be
specified as "\"d:\my share\myservice.exe\"".
The path can also include arguments for an auto-start service. For
example, "d:\myshare\myservice.exe arg1 arg2". These arguments are
passed to the service entry point (typically the main function).
So I do this:
LPCTSTR pStrDriverFilePath; //Driver full path
LPCTSTR pStrDriverFileParams; //Parameters
hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
CString strDrvPath;
strDrvPath.Format(L"\"%s\"", pStrDriverFilePath);
if(pStrDriverFileParams &&
pStrDriverFileParams[0])
{
strDrvPath.AppendFormat(L" %s", pStrDriverFileParams);
}
CreateService(hSCManager, pStrDriverName, pStrDriverDispName,
SERVICE_START | DELETE | SERVICE_STOP | SERVICE_QUERY_STATUS,
dwDriverType, dwStartType, dwErrorCtrl,
strDrvPath,
NULL, NULL, NULL,
NULL, NULL);
But then when I try to start it:
StartService(hScDrvHandle, 0, NULL);
it fails with the error code 123, or ERROR_INVALID_NAME:
The filename, directory name, or volume label syntax is incorrect.
Edit: This is how it ends up looking in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\ key:
It only works if I remove double quotes (but only w/o a parameter.)
I'm creating a project with C++Builder XE7, in which a user can click on a button to open a web link, e.g. to open a support page, or to share his experience on a social media. For that, I use the ShellExecute() function, and it works well, except for one button.
When I click on this button, simply nothing happens. The ShellExecute() function returns without error (the returned value is 42), but my default browser does not open, and the web page isn't shown at all.
Here is my ShellExecute() implementation
const HINSTANCE result = ::ShellExecute(handle, "open", url.c_str(), NULL, NULL, SW_SHOWDEFAULT);
I also tried the ShellExecuteEx() function:
::SHELLEXECUTEINFO info;
std::memset(&info, 0, sizeof(info));
info.cbSize = sizeof(info);
info.hwnd = handle;
info.lpVerb = "open";
info.lpFile = url.c_str();
info.nShow = SW_SHOWDEFAULT;
if (!::ShellExecuteEx(&info))
The url parameter contains the website link I am trying to open. For security reasons, I cannot post it here as a sample, however I tested it in my browser (FireFox) and it works well. On the other hand, if I execute my code by just replacing the url content with Google's website, all works as expected.
The handle is just the Handle parameter of the parent frame.
I also tried to tweak the ShellExecute/Ex() parameters, like the hwnd and nShow fields, but no change.
Can anybody point me to what is wrong?
The url is formatted like this: http:// www.
mysite.xxx/selectPage.php?arg1=xxx&arg2=yyy&...&argX=a text containing
"quotes" and some %26amp%3b special chars!
In this example you have to URL-encode the double quotes and the spaces because these are not valid characters for the query part of an URL.
Fix it by replacing double quotes with %22 and spaces with %20. I suggest to use a function like UrlEscape() to properly encode the URL.
Although most browsers have an error tolerance for user input and will also accept an URL which does not have valid encoding, it's better to strictly follow the spec because you are not guaranteed that tolerance.
In addition, the double quotes will make problems when the URL is passed as a command-line argument to the command associated with the URL protocol. This is because double quotes are reserved characters for defining command-line parameters that contain spaces.
For instance, on my machine the http protocol is associated with the following command (see HKEY_CLASSES_ROOT\http\shell\open\command):
"C:\Program Files (x86)\Mozilla Firefox\firefox.exe" -osint -url "%1"
You can see that the double quotes are already used to enclose the last parameter, which obviously gets messed up if you have unencoded double quotes within the URL.
Example for correctly encoding an URL for use with ShellExecuteEx():
#include <windows.h>
#include <Shellapi.h>
int main()
{
::CoInitialize(nullptr);
SHELLEXECUTEINFOW info{ sizeof(info) };
info.fMask = SEE_MASK_NOASYNC; // because we exit process after ShellExecuteEx()
info.lpVerb = L"open";
info.lpFile = L"http://www.google.de/search?q=ShellExecuteEx%20URL%20%22double%20quotes%22";
info.nShow = SW_SHOWDEFAULT;
if( !::ShellExecuteExW( &info ) )
{
DWORD err = ::GetLastError();
printf("ShellExecuteEx failed with error %d\n", err );
}
::CoUninitialize();
}
I want to submit a form using the CHttpFile::SendRequest and save those data to a mysql database. The field inside the DB table collation is also set to utf8mb4_unicode_ci.
It works fine except the character encoding for the non-english chars. My app is under MFC and "character set" is no set which means ASCII. I tried to convert the chars to unicode without success.
CString strFormData;
strFormData = _T(SUBMIT_FORM) + _T(strSubmitValue) + _T(USERNAME_FIELD) + _T(m_strUsername) + _T(RESTORE_EMAIL_FIELD) + _T(m_strRestoreEmail) + _T(CAPTCHA_FIELD);
LPWSTR lpUnicodeFormData = A2W( strFormData );
strHeaders = _T("Content-Type: application/x-www-form-urlencoded;charset=UTF-8\r\n");
result = pFile->SendRequest(strHeaders, (LPVOID) (LPCTSTR) lpUnicodeFormData, wcslen(lpUnicodeFormData));
What am i doing wrong here ?
Inside PHP file where the html form exists, I added the code
mysqli_set_charset($con, "utf8");
This solved the problem.
thank you to all.
I have written a JNI code which calls a c native Dll. In my dll- functionX I have a messsagebox with utf8 characters shown below:
string aboutStr = " به این برنامه خوش آمدید";
string aboutCaption = "درباره";
MessageBox(NULL, (LPCTSTR)(aboutStr.c_str()), (LPCTSTR)(aboutCaption.c_str()), MB_OK | MB_ICONEXCLAMATION);
When in a java tester, via JNI I call functionX, the messagebox shows question mark instead of persian characters.
How can I solve this problem?
i have function that takes two parameters of type LPTSTR, and i am trying print both the values using sprintf like below and i am not able to print the exact values.
int __stdcall Logon(LPTSTR UserName, LPTSTR Password)
{
char Buffer[2048];
sprintf(Buffer,"UserName: %s\n m_Password: %s\n",UserName,Password);
FILE *Ls=fopen("lo.log",a);
fprintf(Ls,Buffer);
fclose(Ls);
}
Either fix "Use Unicode strings" in you project settings or use the
_stprintf(Buffer, _T("UserName: %S\n m_Password: %S\n"), UserName, Password);
and
#include <tchar.h>
If you use Unicode (and you do), use the '%S' format.
Assuming that UserName and Password are stored as wide strings (wchar_t) and you are trying to put them into a char[] buffer, then visual c++ uses %S to accomplish this.
sprintf(Buffer,"UserName: %S\n m_Password: %S\n",UserName,Password);