Xamarin.iOS: Saving files to windows shared folder - ios

I have an iOS app written using Xamarin. Is there a way to save some file (in my case Image) to a shared folder on Windows PC? iOS device and PC are in the same WiFi network, so I can get access to PC machine by IP address. But how can I save a file to that shared folder?
If that is possible I would be grateful for some code example.

Are you try SharpCifs.Std?
NuGet Package is here.
drives SMB on Xamarin.iOS, like this.
var file = new SmbFile("smb://UserName:Password#ServerName/ShareName/Folder/NewFileName.txt"));
file.CreateNewFile();
var writeStream = file.GetOutputStream();
writeStream.Write(Encoding.UTF8.GetBytes("Hello!"));

In my Xamarin application (on iPad Pro 12.9") I kind of worked around this problem by activating FTP on my Windows10 machine (see Google how to do this) and then uploaded the image to the Windows folder via FTP:
private void UploadImage(UIImage image, string fileName)
{
try
{
string ftpPath = "ftp://192.168.47.79/"; // IP of my Windows10 pc
string ftpTargetFilePath = $"{ftpPath}{fileName}";
var credentials = new NetworkCredential("ftpuser", "ftp");
FtpWebRequest request = (FtpWebRequest) WebRequest.Create(ftpTargetFilePath);
request.Credentials = credentials;
request.Method = WebRequestMethods.Ftp.UploadFile;
request.UsePassive = false; // in my case I needed passive mode to be deactivated
using (Stream imageStream = image.AsPNG().AsStream())
{
using (Stream ftpStream = request.GetRequestStream())
{
imageStream.CopyTo(ftpStream);
}
}
}
catch (Exception ex)
{
Debug.WriteLine($"Uploading Image: Failed! ({ex.Message})");
}
}

Related

Xamarin.Android : System.UnauthorizedAccessException: Access to the path is denied

I am targeting Android API 30. My app was storing log file and taking database backup in location "/storage/emulated/0/SpecialDir/". Now I am facing access denied issue while my app was workinng fine previously.
I got an overview about scoped storage and came to know that we have some managed locaitons where we can store our data accordingly. i.e Audio, Video, Images, and Download
My question is What is the solution for existing apps that was previously saving files on "/storage/emulated/0/SpecialDir/".
Can anyone please guide me what should i do.
string dir = Path.Combine(Android.OS.Environment.ExternalStorageDirectory.ToString(), "LogFolder");
if (Directory.Exists(dir))
{
return Path.Combine(dir, "MyLogFile.txt");
}
try
{
string newDirectory = Directory.CreateDirectory(dir).FullName;
path = Path.Combine(newDirectory, "MyLogFile.txt");
System.IO.File.WriteAllText(path, "This is some testing log.");
}
catch (Exception ex)
{
string msg = ex.Message;
}
The above code is used to make 'LogFolder' if not exist and 'MyLogFile' as well. What changes do i needed to make it compatiable to Android 10. Thankyou
In Android 10, Google has introduced a new feature for external Storage. Its name is Scoped Storage. Google officially translates it as partitioned Storage, or Scoped Storage.The intent is to limit what programs can do with public directories in external storage. Partitioned storage has no effect on either the internal storage private directory or the external storage private directory.In short, in Android 10, there is no change to private directory reads and writes, and you can still use the File set without any permissions. For reading and writing to public directories, you must use the API provided by MediaStore or the SAF (storage access framework), which means you can no longer use the File set to manipulate public directories at will.
If you set targetSdkVersion above 29,you could try to add below codes into your AndroidManifest.Then you could access the File as before.
<manifest ... >
<application android:requestLegacyExternalStorage="true" ... >
...
</application>
</manifest>
Update (you could try this for public external storage ):
var path = Android.OS.Environment.GetExternalStoragePublicDirectory("LogFolder").AbsolutePath;
Java.IO.File file = new Java.IO.File(path);
if (!file.Exists())
{
file.Mkdirs();
}
try
{
FileWriter fw = new FileWriter(path + Java.IO.File.Separator + "MyLogFile.txt");
fw.Write("This is some testing log.");
fw.Close();
}
catch (Exception ex)
{
string msg = ex.Message;
}
Update for Android 11:
add MANAGE_EXTERNAL_STORAGE permission in your AndroidManifest.
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
in your activity:
if (Environment.IsExternalStorageManager)
{
var path = Android.OS.Environment.GetExternalStoragePublicDirectory("LogFolder").AbsolutePath;
Java.IO.File file = new Java.IO.File(path);
if (!file.Exists())
{
file.Mkdirs();
}
try
{
FileWriter fw = new FileWriter(path + Java.IO.File.Separator + "MyLogFile.txt");
fw.Write("This is some testing log.");
fw.Close();
}
catch (Exception ex)
{
string msg = ex.Message;
}
}
else
{
StartActivityForResult(new Intent(Settings.ActionManageAllFilesAccessPermission), 0);
}

How to save the file to a specific folder (Network Drive or local folder) on a client machine?

I have an asp.net web app which is published as an Azure cloud service.The application downloads the files from the server and saves it locally on the client machine.However,It does not seem to work when published as a cloud service.It works fine when published locally using IIS.
The code below is the where the file gets saved.
foreach (var item in userids)
{
//item.contractorpath= user filepath(client machine path eg, C:\test\)
string filePath =
Path.Combine(Server.MapPath("~/Content/Downloads"),
SessionInfo.CompanyId.ToString(), "Bill",
item.ContractorId.ToString());
if (Directory.Exists(filePath))
{
//System.IO.Directory.CreateDirectory(filePath);
DirectoryInfo di = new DirectoryInfo(filePath);
FileInfo[] TXTFiles = di.GetFiles("*.pdf");
if (TXTFiles.Length > 0)
{
foreach (FileInfo file in TXTFiles)
{
string fileName = file.Name;
if (!Directory.Exists(item.FolderPath))
{
System.IO.Directory.CreateDirectory(item.FolderPath);
}
using (WebClient webClient = new WebClient())
{
webClient.DownloadFile(Path.Combine(filePath, file.Name), Path.Combine(item.FolderPath, file.Name));
System.IO.File.Delete(Path.Combine(filePath, file.Name));
}
}
}
}
}

Messages not rendered when a pst is created from email messages located in another machine on a same network

I am creating a pst from message files which are located in another machine on a same network. But when I loaded the pst, messages are not rendered. I have added a screenshot. And code is below:
Issue do not occur when message files are imported from my local machine.
private static void GeneratePST(string [] messageFiles, string outputPstPath)
{
RDOSession pstSession = null;
RDOPstStore store = null;
RDOFolder folder = null;
RDOMail rdo_Mail = null;
RDOItems items = null;
try
{
pstSession = new RDOSession();
store = pstSession.LogonPstStore(outputPstPath, 1, Path.GetFileNameWithoutExtension(outputPstPath));
folder = store.IPMRootFolder;
folder = folder.Folders.Add("Loose Messages");
foreach (string messages in messageFiles)
{
items = folder.Items;
rdo_Mail = items.Add("IPM.NOTE");
rdo_Mail.Import(messages, rdoSaveAsType.olMSG);
rdo_Mail.Save();
}
}
catch (Exception ex)
{
//log exception
}
finally
{
Marshal.ReleaseComObject(rdo_Mail);
Marshal.ReleaseComObject(folder);
Marshal.ReleaseComObject(store);
Marshal.ReleaseComObject(items);
pstSession.Logoff();
Marshal.ReleaseComObject(pstSession);
GC.Collect();
}
}
I have also impersonated the network machine before importing message file. But still the issue persist.
The problem only exists for files in another machine. Messages are rendered for msg file located in my machine. Also, I noticed issue is only with message files. Eml file are rendered. So, it might not be the issue of impersonation.
Any help please.
Microsoft does not support accessing PST files on network drives. They must be on a local machine.
Also, there is no reason to continuously retrieve the RDOItems object - you never release on the old value, so those objects stay alive until your app exits. Ditto for the rdo_Mail object:
folder = folder.Folders.Add("Loose Messages");
items = folder.Items;
foreach (string messages in messageFiles)
{
if (rdo_Mail != null) Marshal.ReleaseComObject(rdo_Mail);
rdo_Mail = items.Add("IPM.NOTE");
rdo_Mail.Import(messages, rdoSaveAsType.olMSG);
rdo_Mail.Save();
}

How to connect localhost of windows to iphone simulator in mac

I have xamarin.forms application for iOS and local database is created in sql server 2012 on windows 10,now i am trying to connect the localhost to the of windows to the iphone simulator.
i tried :
Connecting through IP address of the windows Pc.
Connected mac and windows under same wifi.
Disabled firewall.
none of them worked.
The code i am trying to connect is:
private string Uri = "http://192.168.0.16:62271/";//Windows Ip address:localhost port number
private string GetDishesUrl = "api/DishDetails/GetDishDetails?id=5";
try
{
var httpClient = new HttpClient();
httpClient.BaseAddress = new Uri(Uri);
var response = await httpClient.GetAsync(new Uri(Uri + GetDishesUrl));
var stringAsync = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
var responseJson = stringAsync;
return JsonConvert.DeserializeObject<List<DishDetails>>(responseJson);
}
}
catch(Exception ex)
{
return null;
}
when i disabled firewall and trying to connect to mac then i am getting responseas null and also the exception also as null and in safari while giving Ip address along with GetDishesUrl getting as Bad Request-Invalid Hostname,How to acheive this local host connection?
I already placed this this but i did not get it to be worked.

Cannot Write On Micro SDCard On BlackBerry

I am trying to save some files on micro SDCard. To check the availability of SDCard, I am using the following method;
private boolean isSdCardReady() {
Enumeration e = FileSystemRegistry.listRoots();
while (e.hasMoreElements()) {
if (e.nextElement().toString().equalsIgnoreCase("sdcard/")) {
return true;
}
}
return false;
}
Even if this method returns true, when I try to save files, it gives exception net.rim.device.api.io.file.FileIOException: File system is not ready.
What does this means? If SDCard is not available, then why its listed in FileSystemRegistry.listRoots()?
How can I make sure that SDCard is available for writing?
My development environment:
BlackBerry JDE Eclipse Plugin 1.5.0
BlackBerry OS 4.5
BlackBerry Bold with a 3G card
Usually I had this error when I tried to access SD card on device restart. You have to postpone all operations in app until startup finished:
while (ApplicationManager.getApplicationManager().inStartup()) {
try {
Thread.sleep(500);
} catch (InterruptedException ignored) {
}
}
I remember one more possible cause mentioned here. You have to close all streams after using.
Solved the problem. I was looking for "sdcard" while rootsEnum.nextElement().toString(); returns "SDCard". Yeah, its case sensitive. Now, instead of using hard-coded "SDCard", I've changed the above method to the following;
private static String getSdCardRootDir() {
Enumeration rootsEnum = FileSystemRegistry.listRoots();
while (rootsEnum.hasMoreElements()) {
String rootDir = rootsEnum.nextElement().toString();
if (rootDir.equalsIgnoreCase("sdcard/")) {
return "file:///" + rootDir;
}
}
return null;
}
Using this, I got the root directory in its system defined case.

Resources