Использование System.Reflection и ресурсов в Phalanger

Мне нужно встроить некоторый ресурс в чистый скомпилированный dll, написанный на php, используя phalanger. Это текстовые файлы, которые я устанавливаю в Visual Studio как "Embedded Resource".

Моя проблема в том, что я не могу использовать класс Assembly для получения ресурса с помощью GetManifestResourceStream.

Я попробовал код так: используйте System\Reflection\Assembly

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

У меня вопрос: как мне получить доступ к встроенным ресурсам в phalanger? Большое спасибо

2 ответа

Решение

Я не уверен, почему 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

Этот вопрос старый, но часть кода 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() (как предположил Якуб) не работает, потому что Phalanger не использует System.Reflection.Emit.ModuleBuilder.DefineManifestResource() (как я думаю, что должно быть, когда поставляется с нераспознанным форматом файла). Оно использует ModuleBuilder.DefineResource() который возвращается ResourceWriter вместо этого это только действительно подходит для .resources файлы. И это то, что диктует требование к использованию ResourceReader когда вам нужно прочитать ваш ресурс.

Примечание. Этот ответ относится к основной ветке Phalanger во время написания и предыдущих версий начиная с 2011 года. Отмечено, что это выглядит как ошибка (особенно необходимость использовать как оригинальные, так и альтернативные имена).

Другие вопросы по тегам