在Phalanger中使用System.Reflection和资源

时间:2012-05-29 09:09:05

标签: phalanger

我需要在使用phalanger在php中编写的纯编译dll中嵌入一些资源。 这些是我在visual studio中设置为“嵌入式资源”的txt文件。

我的问题是我不能使用Assembly类来使用GetManifestResourceStream来获取资源。

我试过这样的代码:     使用System \ Reflection \ Assembly

$asm = Assembly::GetExecutingAssembly(); //this gives me mscorlib instead of my dll
$str = $asm->GetManifestResourceStream("name");

我的问题是:如何访问phalanger中的嵌入式资源? 非常感谢

2 个答案:

答案 0 :(得分:0)

我不确定,为什么Assembly :: GetExecutingAssembly()返回的值不正确。无论如何要解决$ asm值,请使用以下代码:

$MyType = CLRTypeOf MyProgram;
$asm = $MyType->Assembly;

然后您可以在发布时访问嵌入资源

$asm->GetManifestResourceStream("TextFile1.txt");

或者您可以将标准资源文件(.resx)包含到项目中,并使用\ System \ Resources \ ResourceManager

$this->manager = new \System\Resources\ResourceManager("",$asm);
$this->manager->GetObject("String1",null);

请注意,目前Phalanger项目中只有一个.resx

答案 1 :(得分:0)

这个问题已经很久了,但是自从问到这个问题以来,负责此事的Phalanger代码(Php.Core.Emit.AddResourceFile()方法)的部分内容并未发生变化。我遇到了同样的问题并以(几乎)非黑客的方式解决了它。您必须提供替代名称(/res:/path/to/filename,alternative-name)才能实现此目的。

$asm = clr_typeof('self')->Assembly;
$resourceStream = $asm->GetManifestResourceStream("filename");
$reader = new \System\Resources\ResourceReader($resourceStream);

$type = $data = null;
$reader->GetResourceData("alternative-name", $type, $data);

// and still there are 4 excess bytes
// representing the length of the resource
$data = \substr($data, 4);
$stream  = new IO\MemoryStream($data);

// after this $stream is usable as you would expect

直截了当GetManifestResourceStream()(由Jakub建议)不起作用,因为Phalanger不使用System.Reflection.Emit.ModuleBuilder.DefineManifestResource()(就像我认为它应该在提供无法识别的文件格式时)。它使用的ModuleBuilder.DefineResource()代替ResourceWriter,仅适用于.resources个文件。这就是需要在需要阅读资源时使用ResourceReader的要求。

注意:此答案适用于Phalanger master branch at the time of writing及之前的版本,自2011年左右开始。注意,因为它看起来像一个错误(特别是需要同时使用原始和替代名称)。