How do I place it like shared/folder1/newtext.txt on NAS? - xamarin

I would like to read/write files to/from NAS in Xamarin.Android.
https://github.com/TalAloni/SMBLibrary/blob/master/ClientExamples.md
I used SMBLibrary here and was able to implement the functionality I wanted to do itself, but was unable to place the files as shown in the title.
The current configuration is like shared/newtext.txt, but I would like to make it like shared/folder1/newtext.txt.
It was not possible to write "shared¥¥folder" in the shareName argument of client.TreeConnect().
CreateFile() also did not work even if I wrote "folder1¥newtext.txt" in the path argument.
Translated with www.DeepL.com/Translator (free version)
var client = new SMB2Client();
bool isConnected = client.Connect(IPAddress.Parse(IPADDRESS), SMBTransportType.DirectTCPTransport);
if (isConnected)
{
NTStatus status = client.Login(String.Empty, ID, PASSWORD);
ISMBFileStore fileStore = client.TreeConnect(TANAFOLDER, out status);
object fileHandle;
FileStatus fileStatus;
string filePath = filename;
if (fileStore is SMB2Client)
{
filePath = #"\\" + filePath;
}
status = fileStore.CreateFile(out fileHandle, out fileStatus, filePath, AccessMask.GENERIC_READ | AccessMask.SYNCHRONIZE, FileAttributes.Normal, ShareAccess.Read, CreateDisposition.FILE_OPEN, CreateOptions.FILE_NON_DIRECTORY_FILE | CreateOptions.FILE_SYNCHRONOUS_IO_ALERT, null);'

Related

Would it be possible to open a file on an external device without copying it in INetCache?

I'm writing a small image viewer application, which use the Shell API to access to the files.
I noticed that, every time I access an image on an external device, like my connected phone, the file is copied in a local cache, named INetCache.
Below is an example of an image path on my external device:
This PC\Apple iPhone\Internal Storage\DCIM\202005__\IMG_2768.HEIC
and the same image path from the PIDL received by the Shell when I try to open it:
C:\Users\Admin\AppData\Local\Microsoft\Windows\INetCache\IE\MD7CNXNX\IMG_2768[1].HEIC
As you can see, the file was copied in the INetCache, and even duplicated. Would it be possible to open the file from my external device without copying it in the INetCache? And if yes, how may I achieve that (if possible using the Shell API)?
UPDATE on 11.08.2022
Below is the code I use to get the PIDL from an IDataObject I receive after a drag&drop operation, which contains the file to open:
std::wstring GetPIDLFromDataObject(IDataObject* pDataObject)
{
std::wstring line = L"PIDL result:\r\n";
if (!pDataObject)
return line;
CComPtr<IShellItemArray> pShellItemArray;
if (FAILED(::SHCreateShellItemArrayFromDataObject(pDataObject, IID_PPV_ARGS(&pShellItemArray))))
return line;
CComPtr<IEnumShellItems> pShellItemEnum;
pShellItemArray->EnumItems(&pShellItemEnum);
if (!pShellItemEnum)
return line;
for (CComPtr<IShellItem> pShellItem; pShellItemEnum->Next(1, &pShellItem, nullptr) == S_OK; pShellItem.Release())
{
CComHeapPtr<wchar_t> spszName;
if (SUCCEEDED(pShellItem->GetDisplayName(SIGDN_DESKTOPABSOLUTEPARSING, &spszName)))
{
line += spszName;
line += L"\r\n";
}
CComHeapPtr<ITEMIDLIST_ABSOLUTE> pIDL;
if (SUCCEEDED(CComQIPtr<IPersistIDList>(pShellItem)->GetIDList(&pIDL)))
{
UINT cb = ::ILGetSize(pIDL);
BYTE* pb = reinterpret_cast<BYTE*>(static_cast<PIDLIST_ABSOLUTE>(pIDL));
for (UINT i = 0; i < cb; i++)
{
WCHAR hexArray[4];
::StringCchPrintf(hexArray, ARRAYSIZE(hexArray), L" % 02X ", pb[i]);
line += hexArray;
}
line += L"\r\n";
}
}
return line;
}

How to read file remotely?

I have such a method for reading file by path
void test_read_file(std::string const & fileName)
{
std::ifstream file(fileName);
if (!file.is_open())
{
std::cout << "LoadFromFile FAILED to load: " << fileName << std::endl; <--- this line
}
...
}
And this method works well if I pass as a path C:\\..., but if I pass something like this \\\\my_remote_drive\\my_user\\.... it does not work and I came to line that I marked above.
It looks like a lack of permission or something like this...
What am I doing wrong?
You need to make a connection to a network resource first, with WNetAddConnection2A(Similar APIs are NetUseAdd, NPAddConnection, etc.) and this function could also redirect a local device to the network resource.
lpRemoteName:
An example for a share might be the following: \192.168.1.1\share
NETRESOURCE nr = {0};
nr.dwType = RESOURCETYPE_ANY;
nr.lpLocalName = NULL; //does not assign a drive.
nr.lpRemoteName = "\\192.168.1.1\\share";
DWORD ret = WNetAddConnection2 (&nr, NULL, NULL, CONNECT_TEMPORARY);
To assigning a Drive to a Share:
You could refer to Assigning a Drive to a Share

print pdf directly to printer windows

I have a windows app that prints pdfs directly to a printer. Everything is working but for some reason for each pdf to print I see the pdf reader Nitro Pro pop up in the background then close.
Is there a way to keep the window from poping up. It does not seem to effect the over application but just kind of annoying.
private void PrintDocument(string printer, string fileName)
{
ProcessStartInfo info = new ProcessStartInfo
{
Arguments = "\"" + printer + "\"",
Verb = "PrintTo",
FileName = fileName,
CreateNoWindow = true,
WindowStyle = ProcessWindowStyle.Hidden,
UseShellExecute = true
};
Process p = new Process { StartInfo = info };
p.Start();
p.WaitForExit(5000);
if (p.HasExited == false)
{
p.Kill();
}
}
This is not possible.
Windows can't print a file directly, it relies on a program to do so. It will use whatever application has configured itself to handle the PrintTo verb for the particular file extension. In your case it appears the application is Nitro Pro.
It's possible that you can find and install an application that can print the file without opening a window to do so, but that's beyond the scope of StackOverflow.

Is there anyway to make SOMETHING automatically add selected file extension to filename, when OPENFILENAME struct and GetSaveFileName() are used?

I have this function:
void PickupFileAndSave(std::vector<unsigned char> file_data, int *error_code, char *file_mask = "All files (*.*)\0*.*\0\0")
{
OPENFILENAMEA ofn; // common dialog box structure
char szFile[MAX_PATH]; // buffer for file name
char initial_dir[MAX_PATH] = { 0 };
GetStartupPath(initial_dir);
// Initialize OPENFILENAME
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = GetActiveWindow();
ofn.lpstrFile = szFile;
// Set lpstrFile[0] to '\0' so that GetOpenFileName does not
// use the contents of szFile to initialize itself.
ofn.lpstrFile[0] = '\0';
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFilter = file_mask;
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = initial_dir;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_EXPLORER;
if (!GetSaveFileNameA(&ofn))
{
*error_code = GetLastError();
return;
}
char err_msg[1024] = { 0 };
std::string file_name = ofn.lpstrFile; //this stores path to file without extension
file_name.append(".");
file_name.append(ofn.lpstrDefExt); //this is NULL and fails to copy too
WriteAllBytes(file_name.c_str(), &file_data[0], file_data.size(), &err_msg[0]);
if (strlen(err_msg) > 0)
{
*error_code = GetLastError();
return;
}
}
I call it that way:
int write_error = 0;
PickupFileAndSave(compressed, &write_error, "RLE compressed files (*.rle)\0*.rle\0\0");
When I choose file it shows in the filter needed extension, but do not add it to lpstrFile.
Any ideas why and how to fix it?
You did not assign lpstrDefExt so the system will not add the extension in case you omit it. So you simply need to initialise the field before you show the dialog:
lpstrDefExt = "rle";
The documentation explains this:
lpstrDefExt
The default extension. GetOpenFileName and GetSaveFileName append this extension to the file name if the user fails to type an extension. This string can be any length, but only the first three characters are appended. The string should not contain a period (.). If this member is NULL and the user fails to type an extension, no extension is appended.
It's not clear from the code in the question but you want to handle the case where there are multiple filters and you wish to append the extension of the selected filter.
The system won't do that for you so you will have to. Read nFilterIndex after you have shown the dialog. That tells you which filter the user selected. Then parse the filter string to obtain the chosen extension, and append it to the filename if it has no extension.

How to run FFMPEG at my web host server

I want to perform some video process at my web host server. I don't think the web host server will allow me to execute an exe file for security reasons.
Should I use SharpFFMpeg?
I have downloaded SharpFFMpeg. But it's lacking a proper documentation.
Can someone give one example how to perform a conversion from one video format to another?
I have written my execution program, but the compiler says it cannot file the file specified. What's wrong with it?
string command = #"D:\Recorded TV\ffmpeg.exe -i ""Australia's Toughest Police_QUEST_2013_04_17_21_57_00.wtv"" -s 800x400 throughCS.mp4";
try
{
ProcessStartInfo psi = new ProcessStartInfo("\"" + command + "\"");
psi.RedirectStandardOutput = true;
psi.UseShellExecute = false;
psi.CreateNoWindow = true;
Process proc = new Process();
proc.StartInfo = psi;
proc.Start();
string result = proc.StandardOutput.ReadToEnd();
tb1.Text = result;
Debug.WriteLine(result);
}

Resources