msi installer не может найти installstate при использовании пользовательских действий с параметрами

<p>прежде всего, да, я знаю, что проекты установки vs - зло. это то, с чем я должен работать. я также видел несколько связанных вопросов, но они либо остаются без ответа, либо не соответствуют моей ситуации достаточно близко, чтобы ответить на них (или они говорят о зле проектов по настройке vs и чудесах wix).</p><p>у меня есть проект установки для моего приложения. это прекрасно работало для копирования файлов, но мне нужно было выполнить два пользовательских действия после копирования файлов. я создал класс установщика и настроил его как настраиваемое действие в проекте установки, и его скелет (который не работал, просто показал диалог, чтобы я мог подключить отладчик и осмотреться) работал отлично. затем я обнаружил, что мне нужно передать параметры из msi в мое настраиваемое действие, чтобы я мог получить к ним доступ через свойство context класса установщика.</p><p>вот текущий код класса установщика (некоторые имена были изменены, чтобы защитить невинных). по сути, он только показывает диалоговое окно в нужное время (после копирования файлов, но до завершения установки):</p><pre><code>namespace myapp.install.customsetup { [runinstaller(true)] public partial class myappcustominstallactions : system.configuration.install.installer { public myappcustominstallactions() { initializecomponent(); } protected override void onafterinstall(idictionary savedstate) { try { base.onafterinstall(savedstate); if (messagebox.show( "custom action onafterinstall successfully integrated. you can attach a debugger if desired. do you wish to perform the custom actions?", "debug", messageboxbuttons.yesno, messageboxicon.question) == dialogresult.no) return; seteditablepermissiononfolder(savedstate); setapplicationsettingsfromwizard(savedstate); } catch (exception ex) { context.logmessage(ex.tostring()); throw; } } private void setapplicationsettingsfromwizard(idictionary savedstate) { //todo: implement } private void seteditablepermissiononviewerfolder(idictionary savedstate) { //todo: implement } } } </code></pre><p>план состоит в том, чтобы заставить пользовательские действия работать, затем вынуть диалоговое окно и просто сделать это.</p><p>вот строка для customactiondata для действия install пользовательских действий проекта установки:</p><pre><code>/phonenumber=[phonenumber] /thirdpartyinstallpath1="[thirdpartyinstallpath1]\" /thirdpartyinstallpath2="[thirdpartyinstallpath2]\" /thirdpartyinstallpath3="[thirdpartyinstallpath3]\" </code></pre><p>если я не использую эту строку параметров, это нормально, но у меня нет параметров. если я укажу эту строку, программа установки завершит работу до того, как появится мое диалоговое окно, с двумя ошибками: <code>"exception occurred while initializing the installation: could not load file or assembly 'file:///c:\windows\syswow64\files' or one of its dependencies. the system cannot find the file specified"</code> и <code>"error 1001. could not find file c:\program files (x86)\mycompany\myapp\myapp.install.customsetup.installstate"</code>.</p><p>что я делаю неправильно? я делаю что-то не так? есть ли решение, которое не требует от меня повторного создания установщика с использованием какой-либо другой инфраструктуры?</p><p><strong>edit:</strong> я обнаружил, что удаление всего, кроме параметра номера телефона, и помещение [phonenumber] в кавычки позволяет передавать этот параметр. однако я не могу передать ни один из путей к каталогам; я попробовал с [installdir] в точности то, что несколько блогов и пошаговых руководств говорят, что делать это, без игры в кости.</p>

<p>я обнаружил, что проблема была в формате строки параметра. поскольку различные параметры, хотя они и были путями к файлам, включали имя файла вместо того, чтобы заканчиваться обратной косой чертой, мне не требовалась конечная обратная косая черта для завершения этих строк значений. поскольку я все равно это сделал, заключительные кавычки были обработаны как часть строки, что заставило парсер использовать следующую открывающую кавычку в качестве конца предыдущего значения, что повредило всю строку параметров. из-за этого installstate не мог быть написан правильно, и потерпел неудачу, когда пользовательская логика установки пыталась использовать его.</p>

<p>у меня была похожая проблема, и я решил ее:</p><p>в свойствах вашего настраиваемого действия установите для installerclass значение false.</p>

<p>если кто-то получит эту ошибку <strong> после обновления с vs2008 до vs2010 </strong>, то просмотрите эту ветку: <a href="http://social.msdn.microsoft.com/forums/en-us/winformssetup/thread/829d5c90-9a0d-4258-9d4d-1341cc50f95b/">http://social.msdn.microsoft.com/форум/en-us/winformssetup/резьба/829d5c90-9a0d-4258-9d4d-1341cc50f95b /</a> </p><p>это решило проблему для меня:</p><blockquote> <p>измените "backwardcompatibleidgeneration" на true при настройке свойств проекта.</p> </blockquote>

<p>в одном я бы удостоверился, что мои пути были должным образом спасены; либо сделай это с</p><pre><code>@"my documents\blah" </code></pre><p>или же</p><pre><code>"my\ documents\\blah" </code></pre>

<p>в моем случае это было потому, что я по ошибке добавил пользовательское действие в узел отката вместо узла установки. простая ошибка.</p>

<p>проблема в том, что один обратный слеш перед завершающей кавычкой будет интерпретироваться как кавычка, которая принадлежит строке и не завершает строку. в строке customactionactiondata</p><pre><code>/thirdpartyinstallpath1="[thirdpartyinstallpath1]\" /thirdpartyinstallpath2="[thirdpartyinstallpath2]\" </code></pre><p>установщик подставляет <code>[thirdpartyinstallpath1]</code> и <code>[thirdpartyinstallpath2]</code> с помощью ввода пользователя и затем пытается интерпретировать строку customactionactiondata. если пользовательский ввод для "thirdpartyinstallpath1" - "c:\test \", то приведенная выше строка customactionactiondata может быть в порядке, но если пользователь вводит "c:\test", установка завершается с ошибкой</p><blockquote> <p>"возникла исключительная ситуация при инициализации установки: не удалось загрузить файл или сборку 'file: /// c:\windows\syswow64\files ...' или одну из его зависимостей ..."</p> </blockquote><p>со строкой customactionactiondata, например</p><p><code>/thirdpartyinstallpath1="[thirdpartyinstallpath1]" /thirdpartyinstallpath2="[thirdpartyinstallpath2]"</code></p><p>установка завершится неудачно, если пользователь введет "c:\test \". это будет нормально, если пользовательский ввод "c:\test". но вы никогда не можете знать, что будет делать пользователь.</p><p>мой обходной путь - пустой перед самой завершающей строкой:</p><p><code>/thirdpartyinstallpath1="[thirdpartyinstallpath1] " /thirdpartyinstallpath2="[thirdpartyinstallpath2] "</code></p><p>поэтому нет никаких изменений, чтобы убрать завершающую строку с помощью пользовательского ввода. в коде вы можете удалить все начальные и конечные пробельные символы из пользовательского ввода trim</p>