Setup Project Custom Action in C++ "[TARGETDIR]" - visual-c++

I am trying to copy file into the setup target directory.
I am using this:
TCHAR destPath[ MAX_PATH ] = &L"[TARGETDIR]";
wcscat_s(destPath, L"LiveFo#nextjmp.com\\Capture.png");
CopyFile(L"C:\\Users\\waldek\\Desktop\\Capture.png", destPath, 0);
if I use this:
CopyFile(L"C:\\Users\\waldek\\Desktop\\Capture.png", L"C:\\Program Files (x86)\\Microsoft\\Setup1\\LiveFo#nextjmp.com\\Capture.png", 0);
it works, which is basically what destPath should evaluate to, I can see that it evaluates when I use PMSIHANDLE, it alerts the correct path...
How do I force CopyFile to evalue "[TARGETDIR]";

WCHAR vbuff [MAX_PATH] = {0};
DWORD vlen = MAX_PATH;
UINT gp = MsiGetPropertyW(hInstall, L"CustomActionData", vbuff, &vlen);
in the Install Custom Action in property CustomactionData, I just put [TARGETDIR]
vbuff is the target directory
then of course the concatenation and the FileCopy executed as expected...
this worked for me... but I still would like to know why, it didn't in the original question I posted, the strangest thing was that the PMSIHANDLE wrote out the correct path, but I guess there "translation" step was missing in passing it in the FileCopy function...
I am sure I am missing some theory on this.

Assuming this is part of a custom action, you can use MsiFormatRecord. Error handling omitted, it would look something like this:
PMSIHANDLE hRec = MsiCreateRecord(1);
MsiRecordSetString(hRec, 0, _T("[TARGETDIR]LiveFo#nextjmp.com"));
TCHAR szPath[MAX_PATH] = {0};
DWORD cchPath = MAX_PATH;
MsiFormatRecord(hInstall, hRec, szPath, &cchPath);

Related

Samba(v 4.10.16) win10 can't open the files(like .xlsx .pptx) that has set extended attribute by setxattr() in centos7

Please forgive my broken English
I try to use setxattr() to sets the value of the extended attribute for some file, the code is like that:
int set_scl(string file_name, char scl)
{
char scl_data[16];
scl_data[0] = scl;
ssize_t size = 1;
size = setxattr(file_name.c_str(), "user.DosStream.easescl", scl_data, size, 0);
if (size == -1)
{
perror("set scl:");
return -1;
}
return 0;
}
But once I do this to a file (e.g 1234.xlsx) and then I can't open it however I can still see it. The Excel's error message is:
Can't find \\192.168.2.163\wy\1234.xlsx.
By the way in smb.cnf I have already set vfs objects = acl_xattr streams_xattr like https://www.samba.org/samba/docs/current/man-html/vfs_streams_xattr.8.html
When I use Process Monitor to trace it, I find one event's path is \\192.168.2.163\wy\1234.xlsx:easescl, the operation is 'CreateFile' and the result is 'NAME NOT FOUND'
What should I do to solve this?
I find two ways so far,
1)add "streams_xattr:store_stream_type = no" to smb.conf
2)add ":$DATA" to my code like that
size = setxattr(file_name.c_str(), "user.DosStream.easescl:$DATA", scl_data, size, 0);
Both of them are worked,and now i can open the file
However,the value about xattr i set before will be changed once i modify the file and save it, i can't find way to solve it .....

X++ SysExcelWorkbook.saveAs - change encoding

I'm trying to convert XLS to CSV using job in AX2012. I have some non-ASCII characters in my XLS and I need to find out how can I set SysExcelWorkbook.saveAs method to use specific encoding (eg. UTF-8).
static void ExcelToCsv(Args _args)
{
SysExcelApplication application;
SysExcelWorkbooks workbooks;
SysExcelWorkbook workbook;
FileName xlsFile, csvFile;
;
application = SysExcelApplication::construct();
application.displayAlerts(false);
workbooks = application.workbooks();
xlsFile = #"C:\test.xlsx";
csvFile = #"C:\result.csv";
workbooks.open(xlsFile);
workbook = workbooks.item(1);
workbook.saveAs(csvFile, 6);
// workbook.saveAs(resFile, 22);
// workbook.saveAs(resFile, 23);
// workbook.saveAs(resFile, 24);
application.quit();
}
The code above generates CSV, but all non-ASCII characters are not displaying property when opening in text editor. I expect that I will be able to choose encoding for my CSV file programmatically or use source (XSL) encoding. Is there a way to achieve this with X++?
I don't think you can do this without some workarounds as it appears to be an Excel limitation. It's do-able though if you really need it.
It uses the Excel COM object to do the work, and you can see the reference here, where I can't find any options to specify encoding:
https://learn.microsoft.com/en-us/office/vba/api/excel.workbook.saveas
Here is the same issue, albeit in Powershell instead of X++ with solution (I think) being to export to UnicodeText instead of CSV, then replacing \t with , in the output file.
It looks like you could output to UnicodeText by making the below change to your code, then you could just use some other string-replace to update the final file.
#Excel
// workbook.saveAs(csvFile, 6); // 6 == #xlCSV
workbook.saveAs(csvFile, #xlUnicodeText);
I'm not sure if this truly fixes your encoding issue without testing. I'd also want to double-check how single/double quotes are handled.

FolderBrowserDialog last Folder Name

I'm new to C++/CLI and have a Question about the FolderBrowserDialog function.
Using ->SelectedPath gives me "C:\Folder\Subfolder\Selected Folder"
How can I save JUST "Selected Folder" to a string?
FolderBrowserDialog^ DestinationFolderDialog;
DestinationFolderDialog = gcnew System::Windows::Forms::FolderBrowserDialog;
System::Windows::Forms::DialogResult result = DestinationFolderDialog->ShowDialog();
if (result == System::Windows::Forms::DialogResult::OK)
{
String^ path = DestinationFolderDialog->SelectedPath;
SetDestinationPath(path);
lblDestinationPath->Text = path;
}
The way I set my Destination Path
And now I want to work with it
String^ pathSource = GetSourcePath();
String^ pathDest = GetDestinationPath();
Im trying to generate Symlinks.
So im Selecting "Y:\Movies\Movie_a" as Source
And im Selecting "X:\" as Destination for my Symlink Folder
To Create it I need to add "Movie_a" to "X:\"
Can someone help me?
If what you want is to extract the last dir name from C:\Folder\Subfolder\Selected Folder then you can:
use Path.GetFileName method to acquire the last part from the path
call String.Split with the Path.PathSeparator and take the last array element
Updated in respect to #LucasTrzesniewski comment

StreamWriter trouble writing doubles to .txt file (C++)

I'm trying to write some double values to a text file the user creates via a SaveFileDialog, but everytime I do a streamWriterVariable->Write(someDoubleVariable), I instead see some kind of weird ASCII character in the text file where the double should be (music note, |, copyright symbol, etc). I'm opening the file with notepad if it's that of any significance. A basic outline of my code:
SaveFileDialog^ saveFileDialog1 = gcnew SaveFileDialog;
saveFileDialog1->Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
saveFileDialog1->Title = "Save File Here";
saveFileDialog1->RestoreDirectory = true;
if (saveFileDialog1->ShowDialog() == System::Windows::Forms::DialogResult::OK )
{
FileInfo ^fleTest = gcnew FileInfo(saveFileDialog1->FileName);
StreamWriter ^sWriter = fleTest->CreateText();
sWriter->AutoFlush = true;
double test = 5.635; //Some arbitrary double I made up for test purposes
sWriter->Write(test);
sWriter->Flush();
sWriter->Close();
}
Thanks for your help!
Have you tried to set the encoding explicitly?
StreamWriter^ sWriter = gcnew StreamWriter(saveFileDialog1->FileName, false, System::Text::Encoding::ASCII);
The code you've provided does exactly what you ask it to, that is to write a double to the file in the internal computer format. What you most likely want it to write out the textual representation of the double.
In other words you should try sWriter->Write(test.ToString()) or some variation over this, to get the textual version of your double. This also applies to bool and most other variable representation.

How to use TARGETDIR in visual c++?

Currently the path inside my code is hardcoded. I want to make it dynamic, base on the users selected installation path.
How can I use TARGETDIR inside my code here:
SHELLEXECUTEINFO info = {0};
info.cbSize = sizeof(SHELLEXECUTEINFO);
info.fMask = SEE_MASK_NOCLOSEPROCESS;
info.lpFile = _T("C:\\PROGRA~1\\APPY\\IECapt.exe");
info.lpParameters = full;
info.nShow = SW_HIDE;
TARGETDIR is the path to the directory where you .EXE file is linked. And it's only available at compile time. You want to get the installation directory, so TARGETDIR is not useful.
GetModuleFileName() gives you the path, where your .EXE has been loaded.
This is just a suggestion......
You can use one button and in the OnButonClick() function add the below codes with your other codes..........
CFileDialog m_IDFile(TRUE);
m_IDFile1.m_ofn.lpstrInitialDir=L"C:\\PROGRA~1\\APPY\\";
if(m_IDFile1.DoModal()==IDOK)
m_cFileName=m_IDFile1.GetPathName();
info.lpFile = _T(m_cFileName);

Resources