http://social.msdn.microsoft.com/Forums/windowsapps/en-US/386eb3b2-e98e-4bbc-985f-fc143db6ee36/read-local-file-in-portable-library#386eb3b2-e98e-4bbc-985fから-fc143db6ee36
ファイル アクセスは、Windows ストア アプリと Windows Phone 8 アプリの間でポータブルに行うことはできません。ファイルを開いてストリームを取得するには、プラットフォーム固有のコードを使用する必要があります。その後、ストリームを PCL に渡すことができます。
Content ビルド アクションでビルドする場合、XML は DLL 内にありません。ファイルシステム上にあり、PCL 内から取得する方法はありません。そのため、すべての回答でビルド アクションがEmbedded Resourceに設定されています。内にファイルを配置しますMyPCL.DLL\Path\To\Content.xml
。
ただし、ビルド アクションをContentに設定し、コピー タイプをCopy if newerに設定すると、ファイルは実行可能ファイルと同じディレクトリに配置されます。
したがって、ファイルを読み取るためのインターフェイスを PCL に配置するだけです。移植性のないコードの起動時に、実装を PCL に挿入します。
namespace TestPCLContent
{
public interface IContentProvider
{
string LoadContent(string relativePath);
}
}
namespace TestPCLContent
{
public class TestPCLContent
{
private IContentProvider _ContentProvider;
public IContentProvider ContentProvider
{
get
{
return _ContentProvider;
}
set
{
_ContentProvider = value;
}
}
public string GetContent()
{
return _ContentProvider.LoadContent(@"Content\buildcontent.xml");
}
}
}
上記で PCL が定義されたので、移植性のないコードでインターフェイスの実装を作成できます (以下)。
namespace WPFBuildContentTest
{
class ContentProviderImplementation : IContentProvider
{
private static Assembly _CurrentAssembly;
private Assembly CurrentAssembly
{
get
{
if (_CurrentAssembly == null)
{
_CurrentAssembly = System.Reflection.Assembly.GetExecutingAssembly();
}
return _CurrentAssembly;
}
}
public string LoadContent(string relativePath)
{
string localXMLUrl = Path.Combine(Path.GetDirectoryName(CurrentAssembly.GetName().CodeBase), relativePath);
return File.ReadAllText(new Uri(localXMLUrl).LocalPath);
}
}
}
アプリケーションの起動時に、実装を挿入し、コンテンツのロードを示します。
namespace WPFBuildContentTest
{
//App entrance point. In this case, a WPF Window
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
ContentProviderImplementation cpi = new ContentProviderImplementation();
TestPCLContent.TestPCLContent tpc = new TestPCLContent.TestPCLContent();
tpc.ContentProvider = cpi; //injection
string content = tpc.GetContent(); //loading
}
}
}
編集:簡単にするために、ストリームではなく文字列のままにしました。