コメント
No title
返信ありがとうございます。
今まで真摯にご対応ありがとうございました。
教えてくればかりになってしまい申し訳ありませんでした。
自分で考えていくことを欠けていました。
もう少し自分で調べて考えて解決していこうと思います。
Re: No title
(1)SMBの接続ができていないようです。
(2)ファイルパスがフルパスになっていません。
(1)に関しましては、ご覧になっているはずなのですが、、、
先回の記事をよくご確認ください。
ttps://itblogdsi.blog.fc2.com/blog-entry-83.html
(2)に関しましては「フルパス」についてもう少しお考えください。
保守契約をしているわけではありませんので、全ての質問に全ての正解をお教えすることはありませんので、もう少し貴殿の方で調べて考え上でご質問くださいね。
さらには、当ブログでは実際にアプリに実装している(稼働済みの)ソースのみ掲載しています。
そのことも前提にご質問ください。
No title
ファイルパスはC:\Users\PublicのPublicを詳細な共有に追加して
url:smb://username:passward@192.168.0.23/public/text.txt
ファイルパスはpublic/text.txt か public/ にしているのでフルパスではないと思います。
targetSdkVersionはAndroidManifest.xmlで確認すると
android:minSdkVersion="21" android:targetSdkVersion="27"
でした。
SDK platform 27をインストール済
実機はAndroid7.0 API24です
fileproviderをAndroidManifest.xmlに追加しました。
xmlフォルダにfile_paths.xmlを追加しました。
実際にtext.txtをフォルダに置いてダウンロードボタン実行で
[0:] Failed to connect: 0.0.0.0<00>/192.168.0.23
という出力
そのあと、アップロードボタン実行して
[0:] url:smb://username:passward@192.168.0.23/public/text.txt
[0:] text.txt (No such file or directory)
という出力です。
変わらない状況です。
試しにアンドロイドストアでX-ploreというエクスプローラアプリで上記のユー
ザー名、パスワード、IPでテストするとSMBv2接続はできpublicフォルダにアクセスできます。
宜しくお願い致します。
Re: No title
ファイルパスはフルパスになっていませんでしょうか。
また、targetSdkVersionはいくつでしょうか。
Android7.0以降の場合はFileProviderの設定がないとローカルのファイルは操作できません。当ブログにてご紹介していますのでご参考ください。
No title
今日もお手数かけます。
smbservice.cs張り直しビルド、実行できました。
ありがとうございます。
ただ、upload,downloadができません。
mainActivity.csにボタンを設置し、ボタンを押したらupload,downloadするように記載しました。
namespace App2.Droid
{
[Activity(Label = "samba", MainLauncher = true, Icon = "@mipmap/icon")]
public class MainActivity : Activity
{
protected override void OnCreate(Bundle Bundle)
{
base.OnCreate(Bundle);
SetContentView(Resource.Layout.Main);
Button button1 = FindViewById<Button>(Resource.Id.myButton);
Button button2 = FindViewById<Button>(Resource.Id.myButton2);
button1.Click += button1_onClick;
button2.Click += button2_onClick;
}
private void button1_onClick(object sender, EventArgs e)
{
SmbService smb1 = new SmbService();
smb1.Upload("text.txt", "Public/");
}
private void button2_onClick(object sender, EventArgs e)
{
SmbService smb1 = new SmbService();
smb1.Download("Public/", "text.txt");
}
}
}
下記のadminは実際は私のユーザー名、パスワードを記載。
[assembly: Xamarin.Forms.Dependency(typeof(App2.Droid.SmbService))]
namespace App2.Droid
{
public class SmbService : ISmbService
{
private string _userName = "admin";
private string _password = "admin1";
private string _ip = "192.168.0.23";
private string _url = "smb://192.168.0.23/";
public bool Upload(string filePath, string uploadFolderPath)
{
var task = new Task<bool>(() =>
{
try
{
//SMB接続
var url = @"smb://" + _userName.ToLower() + @":" + _password + @"@" + _ip + "/" + uploadFolderPath.Replace(_url, String.Empty).ToLower().Replace(@"\", @"/");
System.Diagnostics.Debug.WriteLine("url:" + url);
var fis = new FileInputStream(filePath);
SmbFileOutputStream fos = new SmbFileOutputStream(url);
byte[] buf = new byte[4096];
int len;
while ((len = fis.Read(buf)) > 0)
{
fos.Write(buf, 0, len);
}
//ファイルに書き込む
fos.Flush();
fos.Close();
fis.Close();
return true;
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message + System.Environment.NewLine + ex.StackTrace);
return false;
}
}
);
task.Start();
task.Wait();
return task.Result;
}
public bool Download(string filePath, string downloadPath)
{
var task = new Task<bool>(() =>
{
try
{
//SMB接続
var url = @"smb://" + _userName.ToLower() + @":" + _password + @"@" + _ip + "/" + filePath.Replace(_url, String.Empty).ToLower().Replace(@"\", @"/");
System.Diagnostics.Debug.WriteLine("url:" + url);
var fis = new SmbFileInputStream(url);
FileOutputStream fos = new FileOutputStream(downloadPath);
byte[] buf = new byte[4096];
int len;
while ((len = fis.Read(buf)) > 0)
{
fos.Write(buf, 0, len);
}
//ファイルに書き込む
fos.Flush();
fos.Close();
fis.Close();
return true;
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message + System.Environment.NewLine + ex.StackTrace);
return false;
}
}
);
task.Start();
task.Wait();
return task.Result;
}
}
}
デバッグでは
Loaded assembly: System.IO.dll [External]
[0:] url:smb://admin:admin1@192.168.0.23/public/
[0:] text.txt (No such file or directory)
at Java.Interop.JniEnvironment+InstanceMethods.CallNonvirtualVoidMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniObjectReference type, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args) [0x00089] in <034d4a9852dd45bea9353cc7776c99f0>:0
at Java.Interop.JniPeerMembers+JniInstanceMethods.FinishCreateInstance (System.String constructorSignature, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters) [0x0004f] in <034d4a9852dd45bea9353cc7776c99f0>:0
at Java.IO.FileInputStream..ctor (System.String name) [0x00072] in <a10f61e70eeb434e952fef884856c199>:0
at App2.Droid.SmbService+<>c__DisplayClass4_0.<Upload>b__0 () [0x000a0] in C:\Users\admin\source\repos\App2 - コピー\App2\App2.Android\SmbService.cs:32
--- End of managed Java.IO.FileNotFoundException stack trace ---
java.io.FileNotFoundException: text.txt (No such file or directory)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(FileInputStream.java:146)
at java.io.FileInputStream.<init>(FileInputStream.java:99)
11-17 10:41:07.761 I/Choreographer(29650): Skipped 38 frames! The application may be doing too much work on its main thread.
[0:] url:smb://admin:admin1@192.168.0.23/public/
Loaded assembly: System.Resources.ResourceManager.dll [External]
Loaded assembly: System.IO.FileSystem.dll [External]
Loaded assembly: System.Text.Encoding.dll [External]
Loaded assembly: System.Console.dll [External]
Loaded assembly: System.Net.Primitives.dll [External]
Loaded assembly: System.Net.Sockets.dll [External]
Loaded assembly: System.Net.NameResolution.dll [External]
Loaded assembly: System.Threading.Tasks.dll [External]
Thread started: #6
Thread started: <Thread Pool> #7
Thread started: <Thread Pool> #8
Thread started: <Thread Pool> #9
[0:] Failed to connect: 0.0.0.0<00>/192.168.0.23
at SharpCifs.Smb.SmbTransport.Connect () [0x00025] in <4e53c8091d154926b6776655288aad95>:0
at SharpCifs.Smb.SmbTree.TreeConnect (SharpCifs.Smb.ServerMessageBlock andx, SharpCifs.Smb.ServerMessageBlock andxResponse) [0x00162] in <4e53c8091d154926b6776655288aad95>:0
at SharpCifs.Smb.SmbFile.DoConnect () [0x000e7] in <4e53c8091d154926b6776655288aad95>:0
at SharpCifs.Smb.SmbFile.Connect () [0x0002c] in <4e53c8091d154926b6776655288aad95>:0
at SharpCifs.Smb.SmbFile.Connect0 () [0x00016] in <4e53c8091d154926b6776655288aad95>:0
at SharpCifs.Smb.SmbFile.Open0 (System.Int32 flags, System.Int32 access, System.Int32 attrs, System.Int32 options) [0x00000] in <4e53c8091d154926b6776655288aad95>:0
at SharpCifs.Smb.SmbFile.Open (System.Int32 flags, System.Int32 access, System.Int32 attrs, System.Int32 options) [0x00009] in <4e53c8091d154926b6776655288aad95>:0
at SharpCifs.Smb.SmbFileInputStream..ctor (SharpCifs.Smb.SmbFile file, System.Int32 openFlags) [0x00040] in <4e53c8091d154926b6776655288aad95>:0
at SharpCifs.Smb.SmbFileInputStream..ctor (SharpCifs.Smb.SmbFile file) [0x00000] in <4e53c8091d154926b6776655288aad95>:0
at SharpCifs.Smb.SmbFileInputStream..ctor (System.String url) [0x00007] in <4e53c8091d154926b6776655288aad95>:0
at App2.Droid.SmbService+<>c__DisplayClass5_0.<Download>b__0 () [0x000a0] in C:\Users\admin\source\repos\App2 - コピー\App2\App2.Android\SmbService.cs:68
11-17 10:41:10.629 I/Choreographer(29650): Skipped 108 frames! The application may be doing too much work on its main thread.
Thread finished: <Thread Pool> #8
text.txtというファイルをパブリックフォルダに置いてみてもダウンロードしません。アップロードもできません。どこを修正すればよいでしょうか。
長々とすみません。宜しくお願い致します。
Re: No title
ご連絡ありがとうございます。
私も常に時間が取れるわけではございませんので、時間のある限りお付き合いしたいと思いますが、返信が遅くなったとしてもお待ちいただきたく存じます。
本題ですが、言葉足らずで申し訳ございません。
アンダースコアから始まる変数は一般的にはプライベート変数です。
または「m」から始まるものも同様にプライベート変数と扱っていることが多いです。ただしコード規約によります。
private string _url = String.Emptry;
private string mUrl = String.Emptry;
これに対してプロパティとは
publi property string Url()
{
get
{
return _url;
}
set
{
_url = value;
}
}
のようになります。この辺りは本題とずれてきていますので、Googleで「オブジェクト指向 プロパティ」等で検索してお調べください。C#に限らずJavaでもVB.NETでも同様の記述をします。ゲッターセッターと言いまます。また、同様に「@」なども基本的なC#の構文になりますのでここでのご紹介は割愛いたします。
Common.GetDocumentPath() メソッド(プロパティに変更しても大丈夫です。)に関しましても内容は特に間違ったところはございませんが、何か問題になっているのでしょうか。以下のURLをご参考頂き実装いただければと思います。
ttps://itblogdsi.blog.fc2.com/blog-entry-86.html
また、話がSMBの話とはだいぶずれてきていますので、一度、LogUtilityもHostInfoも捨てて、SmbService.csを書き直してみませんか?
記事のソースを変更してみましたのでお手数ではございますが再度ご確認いただけますでしょうか。
No title
(1)HostInfo.csに上記のコードを追加しましたが、「_url」がエラーになるため「string _url」としました。この条件だと、全ての「_url」の文頭にstringをつけないとエラーがなる(つまり「_url」がそれぞれ別の変数扱い?)ため
No title
まずありがとうございます。
コメント枠の返信で何度も長文を書くと迷惑ではないかと思っていたので
そう言っていただけるととてもありがたいです。頑張ってみようと思います。
(1)HostInfo.csに上記のコードを追加しましたが、「_url」がエラーになるため「string _url」としました。
これだと、全ての「_url」にstringをつけないとエラーがならない(つまり「_url」がそれぞれ別の変数扱い?)ため
下記のコードにしました。
PCL HostInfo.cs
public string Url(string _url)
{
if (Device.RuntimePlatform == Device.iOS)
{
_url = "file://" + this.IP + "/";
}
else
{
_url = "smb://" + this.IP + "/";
}
return _url;
}
これだと引数がつくため、SmbService.csの
uploadFolderPath.Replace(_hostInfo.Url(), String.Empty)
のUrl()に引数がなくどうすればいいかわかりません。
(2)上記のコードをいれましたが、エラーは変わりません。
'Common' に 'FileService' の定義がありません
PCL LogUtility.cs
public static void OutPutError(string err)
{
//保存パスを形成する
//保存パス=ドキュメントパス&アプリ名_yyyyMMdd.log
if (String.IsNullOrEmpty(_savePath))
{
_savePath = Common.GetDocumentPath();
if (!_savePath.EndsWith("/"))
{
_savePath += "/";
}
_savePath += Common.FileService.GetPackageName() + "_";
App2.LogUtility.OutPutError("エラーです。");
}
…中略…
}
Common.csのcommonクラスにFileServiceプロパティ?(メソッド?)を追加しなきゃいけないと思いますが内容がわかりません。
PCL Common.cs
namespace App2
{
public static class Common
{
/// <summary>
/// ドキュメントディレクトリを取得する
/// </summary>
/// <returns></returns>
public static string GetDocumentPath()
{
string path = DependencyService.Get<IFileService>().GetDocumentPath();
if (String.IsNullOrEmpty(path))
{
path = DependencyService.Get<IFileService>().GetDownloadPath();
}
return path;
}
}
}
ちなみにSmbService.csのsmb接続のコードが書かれている @"smb://" の@はどういう意味ですか?ダブルクォーテーションの@なら文字列だとわかるんですが、@"" 外側にあるのはどういう役割ですか。
Re: No title
お手数をお掛けしており申し訳ございません。
この手の間違いは燈台下暗し的な要素がたくさんありますので、あきらめずに頑張りましょう。
私も勘違いをよくしており、VB.netでDirectCastではなく "(型名)"でキャストしようとしてよく赤色の波線が表示されたりしていますよ。(笑)
頂きましたソースを拝見しましたが、App2ソリューションの名称で名前空間を統一されているようですね。
以下の点をご確認いただくと良いかもしれません。
(1)Urlメソッド
public string Url() {}
→ご面倒であればプロパティに変更しても良いかもしれませんね。
私の場合はiOSとAndroidでURLの中身を変更しています。
if (Device.RuntimePlatform == Device.iOS) {
_url = "file://" + this.IP + "/";
}
else {
_url = "smb://" + this.IP + "/";
}
return _url;
(2)GetDocumentPath
_savePath += App2.Common.FileService.GetPackageName();
App2.LogUtility.OutPutError("エラーです。");
または
using App2;
using App2.Common;
_savePath += FileService.GetPackageName() + "_";
LogUtility.OutPutError("エラーです。");
最後に、何を勉強すべきかというご質問にお答えしますが、特に勉強はしなくても良いと思います。
(決して適当にはお答えしていませんよ。私が素人育ちで全く勉強していないおっさんだからです。とにかくTry&Google検索あるのみです。)
本件に関しましては、名前空間やオブジェクト指向についての理解があれば良いと思いますが、naoさんはおおよそ理解されているように思いますね。
ちなみに私がプログラミングについていつも重要視していることは以下の2点です。
・自分が正しいと思わない事。(自分を疑う事)
・ひとつのつまづきを解決するまでの根気。
これがあれば大丈夫です。最後まで頑張りましょう。
No title
いろいろ回答ありがとうございます。
私が素人なものでどういうふうに書けばいいか思いつきせん。
下記にコードの内容を書きました。的はずれかもしれませんが、
(1)はUrl()でエラーになりました。
(1)PCL HostInfo.cs
namespace App2
{
public class HostInfo
{
public string URL { get; set; }
public string IP { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public string Protocol { get; set; }
public Url()
{
}
}
}
(2)は石川様が仰られたようにCommonクラスをいれたことによってエラーが解消されましたが、Common.FileService.GetPackageName() のFileServiceがエラーになりました。Commonクラスに子クラスFileServiceを追加すればいいことはわかりますが、どういうふうに書くかわかりません。教えていただいた記事のコードを入れました。
(2)PCL Common.cs
namespace App2
{
public static class Common
{
/// <summary>
/// ドキュメントディレクトリを取得する
/// </summary>
/// <returns></returns>
public static string GetDocumentPath()
{
string path = DependencyService.Get<IFileService>().GetDocumentPath();
if (String.IsNullOrEmpty(path))
{
path = DependencyService.Get<IFileService>().GetDownloadPath();
}
return path;
}
}
}
PCL LogUtility.cs
using System;
using Xamarin.Forms;
namespace App2
{
public static class LogUtility
{
/// <summary>
/// 保存パス
/// </summary>
private static string _savePath = null;
/// <summary>
/// ログを出力する
/// </summary>
/// <param name="err">エラー内容</param>
public static void OutPutError(string err)
{
//保存パスを形成する
//保存パス=ドキュメントパス&アプリ名_yyyyMMdd.log
if (String.IsNullOrEmpty(_savePath))
{
_savePath = Common.GetDocumentPath();
if (!_savePath.EndsWith("/"))
{
_savePath += "/";
}
_savePath += Common.FileService.GetPackageName() + "_";
}
//ログ内容の成形
string msg = "---------------------------------------------------------------------------------------------" + System.Environment.NewLine +
DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") + " Error " + System.Environment.NewLine +
err;
//Visual Studio 上でのログを出力する
System.Diagnostics.Debug.WriteLine(msg);
//ファイルログを出力する
DependencyService.Get<IFileService>().OutPutLog(_savePath + DateTime.Now.ToString("yyyyMMdd") + ".log", msg);
}
}
}
私の知識では今の段階でリソースコードなしで実行までいける気がしません。質問の前提が変わって申し訳ないのですが、ここにある記事を理解、実行できるようにするためにはどういう言語、どういうメソッドなどをまず勉強するべきでしょうか。
Re: ISmbService
返信が遅くなり申し訳ございません。
AndroidプロジェクトのSmbService.csでエラーが出るという事でよろしいでしょうか。
取り急ぎ思い当たるところを以下に挙げますので、一度ご確認いただくと良いかもしれません。
(1)HostInfoは当記事の末尾にも記載してございますが、UserName や Password といったPublic Property を保持するエンティティを実装して下さい。PCLプロジェクトにHostInfo.csファイルとして実装します。ご面倒であれば変数に置き換えて頂いてもかまいませんが、エンティティを作成してオブジェクト指向で実装することをお勧めします。
(2)私の場合は、LogUtilityとしてログをファイルに出力するユーティリティを作成しています。PCLプロジェクト\Common\LogUtility.csという名前空間(namespace)で実装していないことでエラーとなっているのではないでしょうか。
尚、LogUtility.csは以下の記事でご紹介していますので、よろしければご参考ください。 (これもSMBの動作には直接的には必要のない機能ですので、Debug.WriteLineやConsol.WriteLineに置き換えて頂いてもかまいません。
ttps://itblogdsi.blog.fc2.com/blog-entry-86.html
または、上記の記事でCommon.csというクラスも追加していますが、そのクラスが無いことによりエラーとなっているのでしょうか。
あくまでソースコードを拝見しておりませんので、推測となりますが、基本的には名前空間とそのクラスが無いことによるエラーと考えています。
ISmbService
石川様が仰られたとおり、ISmbService.csインターフェイスを空にしたため、インターフェイスのエラーはなかったのですが、
CS0246 型または名前空間の名前 'HostInfo' が見つかりませんでした SmbService.cs
CS0103 現在のコンテキストに 'Common' という名前は存在しません。LogUtility.cs
といういうエラーが出ます。HostInfoはISmbService.csインターフェイスに記載すると思っていたのですが。
ソリューションにはこちらのHPを参考にしてC#プロジェクトにIDependencyService.csインターフェイス、ISmbService.csインターフェイス、LogUtility.csクラスを追加しました。
Xamarin.Androidプロジェクトに当ページのサンプルコードのクラスSmbService.csを追加しました。よろしくお願いします。
Re: ISmbService
お問い合わせありがとうございます。
インターフェースは空っぽの定義だけですので、つまずきポイントとしては名前空間のところでしょうか。
具体的にどこに問題があるのか事例を上げていただければ、お答えしますよ。
ISmbService
ISmbServiceのインターフェイスをつくることができません。もし石川様がよろしければ、教えていただけないでしょうか。
コメントの投稿
※名前とタイトルが入力されていないコメントでは他のコメントとの区別ができません。
入力されていないコメントには返信しませんのであらかじめご了承くださいませ。