Visual Studio Installer › Как да стартирате приложението в края на инсталатора

Това вероятно е глупав въпрос и търсенето ми в Гугъл просто не работи днес.

Имам приложение, към което добавих Visual Studio Installer > Setup Wizard проект. Чудя се как да добавя бутон или квадратче за отметка, които да стартират приложението след успешно инсталиране. Това ще се намира на последната страница на инсталационния пакет на MSI. Използвам Visual Studio 2010 Ultimate.

Имам нужда от това, така че когато приложението извършва автоматична актуализация, то автоматично да стартира инсталатора. Просто имам нужда от инсталатора, за да стартирам отново приложението след актуализацията.

Това вероятно е много просто, но за живота си не мога да го разбера. Благодаря предварително за помощта.


person ThaKidd KG5ORD    schedule 02.07.2010    source източник
comment
Бих препоръчал да използвате решението на Cheeso тук.   -  person Baddack    schedule 05.12.2015


Отговори (7)


Предупреждение: В крайна сметка приложението ще работи като акаунт с високи привилегии, което има последици за сигурността и потребителското изживяване.

За да стартирате всяко приложение, след като инсталацията приключи,

  1. Щракнете с десния бутон върху вашия проект за настройка, щракнете върху Персонализирани действия.
  2. След това щракнете с десния бутон върху Commit, Add Custom Action и изберете файла, който искате да стартирате. (Имайте предвид, че вече трябва да е в папката на вашето приложение, което не би трябвало да е проблем във вашия случай, тъй като така или иначе изпълнявате програмата си.
  3. Просто изберете резултата от вашия проект.
  4. След това щракнете върху този добавен .exe и променете InstallerClass на false. Това е от решаващо значение, защото иначе ще търси програма за инсталиране.
  5. Можете дори да подадете параметри към вашия .exe, като ги добавите към свойството Arguments
person sbenderli    schedule 02.07.2010
comment
Отлично.. един въпрос, основното приложение ще се счита ли за „Първичен изход от ApplicationName (Active)“? - person ThaKidd KG5ORD; 03.07.2010
comment
Един проблем. Приложението за инсталиране стартира приложението ми, но никога не се затваря, докато не изляза от приложението си. Засяда на 98% и завършва едва когато изляза от приложението си. Има ли начин да изключите инсталатора грациозно? Уверих се, че съм задал InstallerClass на False. Има ли нещо, което пропускам? - person ThaKidd KG5ORD; 03.07.2010
comment
ааа да, това ще се случи...в моя случай това беше приемливо. това, което можете да направите вместо това, е да изпълните скрипт от вашия инсталатор, който на свой ред ще стартира вашето приложение и ще излезе. по този начин вашето приложение ще работи, но скриптът ще излезе, което ще позволи на инсталатора ви също да завърши. - person sbenderli; 03.07.2010
comment
Току-що поставих INSTALLER като аргументи и във входната точка на приложението ми направих: if (args.Length == 1 && args[0] == INSTALLER) { Process.Start(Application.ExecutablePath); връщане; } Забележка: Не използвайте Application.Restart(), тъй като той предава същия аргумент в ;-) - person Danny Tuppeny; 18.08.2011
comment
Или, за да използвате решението на Danny в WPF приложение: Първо създайте метод на входна точка: frankmao.com/2009/05/07/ След това добавете това към метода: if (e.Args.Length == 1 && e.Args[0] == INSTALLER ) { Process.Start(Assembly.GetExecutingAssembly().Location); Application.Current.Shutdown(); } - person Anders; 02.11.2011
comment
Само за информация, exe ще работи като акаунт с висока привилегия, а не като нормален акаунт, може или не може да е проблем за вас (за мен е) stackoverflow.com /questions/3939731/ - person Maurice Flanagan; 31.12.2011
comment
Кога се извършва пожар? След завършване на инсталационната част ли е? - person Urbycoz; 01.02.2012
comment
Съжалявам, но този отговор е просто грешен. За начало персонализираните действия за извършване са предназначени само за почистване на данни за връщане назад. Те не се изпълняват, когато връщането назад е деактивирано. След това се обсъждат проблемите на модела за сигурност. - person Christopher Painter; 10.10.2013
comment
Инсталатор, създаден от VS2010, не може да изпълнява JS скриптове, ако инсталирате на Windows 8. Необходим скрипт и т.н. не може да бъде стартиран. Това е единственият случай, който тествах; доколкото знам, никога не е работило при никакви обстоятелства. - person 15ee8f99-57ff-4f92-890c-b56153; 02.03.2015
comment
Искам да те целуна за това, това ми спаси деня, благодаря много - person Arsalan Saleem; 31.08.2015
comment
Както отбеляза Морис Фланаган, exe ще работи като акаунт с висока привилегия. Това накара приложението ми да не работи правилно, освен ако не се стартира като администратор. Дори премахването на решението на sbenderli не реши проблема ми. За да поправя проблема си, трябваше да премахна решението на sbenderli от моя проект, след което да променя кода на продукта и кода си за надграждане. Надявам се това да спести време на някого. - person Baddack; 04.12.2015
comment
В моя сценарий исках да стартирам изпълним файл, който инсталира лог в програмата за преглед на събития на Windows, преди потребителят да има шанс да използва приложението. Създадох първичен изход от WindowsEventLogMaker в папката Custom Actions › Install. Не забравяйте да проверите свойствата на основния изход от WindowsEventLogMaker, по-специално променете настройката InstallerClass на False. връзка - person LargeDachshund; 15.09.2016
comment
Здравейте, моля, някой ще ми предложи, ако е необходимо, да кодирам нещо в класа на инсталатора за това? Защото получавам този проблем и не мога да го разреша без вашата помощ. Така че, моля, помогнете ми. Благодаря предварително - person dilipkumar1007; 16.05.2017
comment
Аз съм правил същото. Проблемът е, че преди да щракнете върху бутона „OK“ на последния екран по време на инсталацията, приложението се стартира. Приложението се стартира само и само когато щракна върху бутона OK. Моля, помогнете ни - person dilipkumar1007; 16.05.2017
comment
@sbenderli Здравейте, След завършване на инсталирането на MSI настройката на прозорец, моите необработени файлове (дизайн и кодиране) също се показват на мястото за инсталиране. Разработих това приложение с помощта на Visual Studio 2010. Инсталацията е създадена успешно, но след инсталирането на този MSI този проблем се случва. Моля, помогни ми. Благодаря предварително. - person dilipkumar1007; 02.08.2017

Решението от https://blogs.msdn.microsoft.com/astebner/2006/08/12/mailbag-how-can-i-customize-an-msi-in-the-visual-studio-setupdeployment-project/ добавя квадратче за отметка в края на настройката, за да изберете дали искате да стартирате приложението или не. Можете да промените скрипта така, че да се проверява по подразбиране...или дори да го скриете.

Голямото предимство тук е, че приложението няма да работи с повишени права, както спомена Морис Фланаган.

Необходимият скрипт, от който се нуждаете, е:

// EnableLaaunchApplication.js <msi-file>
// Performs a post-build fixup of an msi to launch a specific file when the install has completed


// Configurable values
var checkboxChecked = true;         // Is the checkbox on the finished dialog checked by default?
var checkboxText = "Launch [ProductName]";  // Text for the checkbox on the finished dialog
var filename = "WindowsApplication1.exe";   // The name of the executable to launch - change this to match the file you want to launch at the end of your setup


// Constant values from Windows Installer
var msiOpenDatabaseModeTransact = 1;

var msiViewModifyInsert         = 1
var msiViewModifyUpdate         = 2
var msiViewModifyAssign         = 3
var msiViewModifyReplace        = 4
var msiViewModifyDelete         = 6



if (WScript.Arguments.Length != 1)
{
    WScript.StdErr.WriteLine(WScript.ScriptName + " file");
    WScript.Quit(1);
}

var filespec = WScript.Arguments(0);
var installer = WScript.CreateObject("WindowsInstaller.Installer");
var database = installer.OpenDatabase(filespec, msiOpenDatabaseModeTransact);

var sql
var view
var record

try
{
    var fileId = FindFileIdentifier(database, filename);
    if (!fileId)
        throw "Unable to find '" + filename + "' in File table";


    WScript.Echo("Updating the Control table...");
    // Modify the Control_Next of BannerBmp control to point to the new CheckBox
    sql = "SELECT `Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, `Attributes`, `Property`, `Text`, `Control_Next`, `Help` FROM `Control` WHERE `Dialog_`='FinishedForm' AND `Control`='BannerBmp'";
    view = database.OpenView(sql);
    view.Execute();
    record = view.Fetch();
    record.StringData(11) = "CheckboxLaunch";
    view.Modify(msiViewModifyReplace, record);
    view.Close();

    // Resize the BodyText and BodyTextRemove controls to be reasonable
    sql = "SELECT `Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, `Attributes`, `Property`, `Text`, `Control_Next`, `Help` FROM `Control` WHERE `Dialog_`='FinishedForm' AND `Control`='BodyTextRemove'";
    view = database.OpenView(sql);
    view.Execute();
    record = view.Fetch();
    record.IntegerData(7) = 33;
    view.Modify(msiViewModifyReplace, record);
    view.Close();

    sql = "SELECT `Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, `Attributes`, `Property`, `Text`, `Control_Next`, `Help` FROM `Control` WHERE `Dialog_`='FinishedForm' AND `Control`='BodyText'";
    view = database.OpenView(sql);
    view.Execute();
    record = view.Fetch();
    record.IntegerData(7) = 33;
    view.Modify(msiViewModifyReplace, record);
    view.Close();

    // Insert the new CheckBox control
    sql = "INSERT INTO `Control` (`Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, `Attributes`, `Property`, `Text`, `Control_Next`, `Help`) VALUES ('FinishedForm', 'CheckboxLaunch', 'CheckBox', '18', '117', '343', '12', '3', 'LAUNCHAPP', '{\\VSI_MS_Sans_Serif13.0_0_0}" + checkboxText + "', 'Line1', '|')";
    view = database.OpenView(sql);
    view.Execute();
    view.Close();



    WScript.Echo("Updating the ControlEvent table...");
    // Modify the Order of the EndDialog event of the FinishedForm to 1
    sql = "SELECT `Dialog_`, `Control_`, `Event`, `Argument`, `Condition`, `Ordering` FROM `ControlEvent` WHERE `Dialog_`='FinishedForm' AND `Event`='EndDialog'";
    view = database.OpenView(sql);
    view.Execute();
    record = view.Fetch();
    record.IntegerData(6) = 1;
    view.Modify(msiViewModifyReplace, record);
    view.Close();

    // Insert the Event to launch the application
    sql = "INSERT INTO `ControlEvent` (`Dialog_`, `Control_`, `Event`, `Argument`, `Condition`, `Ordering`) VALUES ('FinishedForm', 'CloseButton', 'DoAction', 'VSDCA_Launch', 'LAUNCHAPP=1', '0')";
    view = database.OpenView(sql);
    view.Execute();
    view.Close();



    WScript.Echo("Updating the CustomAction table...");
    // Insert the custom action to launch the application when finished
    sql = "INSERT INTO `CustomAction` (`Action`, `Type`, `Source`, `Target`) VALUES ('VSDCA_Launch', '210', '" + fileId + "', '')";
    view = database.OpenView(sql);
    view.Execute();
    view.Close();



    if (checkboxChecked)
    {
        WScript.Echo("Updating the Property table...");
        // Set the default value of the CheckBox
        sql = "INSERT INTO `Property` (`Property`, `Value`) VALUES ('LAUNCHAPP', '1')";
        view = database.OpenView(sql);
        view.Execute();
        view.Close();
    }



    database.Commit();
}
catch(e)
{
    WScript.StdErr.WriteLine(e);
    WScript.Quit(1);
}



function FindFileIdentifier(database, fileName)
{
    var sql
    var view
    var record

    // First, try to find the exact file name
    sql = "SELECT `File` FROM `File` WHERE `FileName`='" + fileName + "'";
    view = database.OpenView(sql);
    view.Execute();
    record = view.Fetch();
    if (record)
    {
        var value = record.StringData(1);
        view.Close();
        return value;
    }
    view.Close();

    // The file may be in SFN|LFN format.  Look for a filename in this case next
    sql = "SELECT `File`, `FileName` FROM `File`";
    view = database.OpenView(sql);
    view.Execute();
    record = view.Fetch();
    while (record)
    {
        if (StringEndsWith(record.StringData(2), "|" + fileName))
        {
            var value = record.StringData(1);
            view.Close();
            return value;
        }

        record = view.Fetch();
    }
    view.Close();
    
}

function StringEndsWith(str, value)
{
    if (str.length < value.length)
        return false;

    return (str.indexOf(value, str.length - value.length) != -1);
}

Редактирайте файла, за да покажете желаното от вас име и името на изпълнимия файл, поставете този файл до вашия проект за настройка .vdproj и в последващото изграждане добавете следния ред:

CALL cscript.exe $(ProjectDir)EnableLaunchApplication.js $(BuiltOuputPath)

person JayTee    schedule 30.11.2018
comment
Това наистина е правилният отговор, особено като се има предвид, че приложението ми използва информация за влизане в AD и инсталаторът работи като SYSTEM потребител. Недостатъкът е, че не работи с тиха или пасивна инсталация. Сега да разкъсам този js и да видя дали мога да го разбера. - person Ricky; 14.08.2019
comment
Това не проработи при мен, получих грешка 2810. Което успях да открия този SO отговор stackoverflow.com/a/59469922/637783, който ме накара да използвам Orca и да променя JS файла, където вмъква новата контрола CheckboxLaunch, за да бъде следващата контрола Line1 вместо CloseButton. Само един СЪВЕТ да използвате Orca за отстраняване на грешки, ако имате затруднения, защото тогава скриптът работи перфектно! - person jbtule; 04.01.2020
comment
На ред 71 на js файла се променя от CloseButton на Line1 и грешката 2810 изчезва, както и формулярът показва квадратчето за отметка с Lauch AppName. Въпреки това на Windows 10 изглежда не стартира приложението. Някакви предположения? - person Rahul Kate; 25.04.2020

Предупреждение: В крайна сметка приложението ще работи като акаунт с висока привилегия, което има последици за сигурността и потребителското изживяване.

Във Visual Studio 2010 тук е лесно...

Стъпка 1: Добавете нов клас на инсталатора към проекта на приложението, който искате да стартирате след инсталирането, наречете го както искате.

Стъпка 2: Добавете следния код към класа Installer, който току-що добавихте, като замените MyApplication.exe с името на вашето.

Public Overrides Sub Commit(ByVal savedState As System.Collections.IDictionary)

    MyBase.Commit(savedState)
    System.Diagnostics.Process.Start(System.IO.Path.GetDirectoryName(Me.Context.Parameters("AssemblyPath")) + "\MyApplication.exe")

End Sub

Компилирайте и тръгвайте...

person Jarrod    schedule 14.03.2013
comment
След завършване на инсталирането на MSI настройката на прозорец, моите необработени файлове (дизайн и кодиране) също се показват на мястото за инсталиране. Разработих това приложение с помощта на Visual Studio 2010. Инсталацията е създадена успешно, но след инсталирането на този MSI този проблем се случва. Моля, помогни ми. Благодаря предварително. - person dilipkumar1007; 02.08.2017
comment
Използването на този метод ще стартира новата програма с администраторски привилегии, което вероятно е нежелателно за сигурността. - person Kenneth M. Kolano; 28.05.2018

В моя случай се борех с това известно време и решението беше там. Предоставеното решение с използване на персонализираното действие директно към първичния изход на приложението не беше добро за мен, тъй като приложението за инсталиране остава, докато не напуснете основното приложение. Така че проблемът може да бъде решен чрез следния подход:

  1. Добавете инсталационен клас към вашия проект;
  2. In the new class, override the Commit method, like Jarrod talked above.

    System.Diagnostics.Process.Start(System.IO.Path.GetDirectoryName(this.Context.Parameters["AssemblyPath"]) + @"\MyApplication.exe");

  3. Сега трикът: отидете в панела „Персонализирани действия“ в проекта на инсталатора и добавете основния изход на вашия проект към папките „Комитиране“ и „Инсталиране“. Не променяйте нищо в свойствата. Ще работи точно така. По подразбиране той ще получи класа на инсталатора, където сте вмъкнали кода в предишната точка;
  4. Създайте своя инсталационен пакет и го инсталирайте. Трябва да забележите, че приложението ще започне в края;
  5. Просто затворете предупреждението за успешна инсталация и продължете.

За да научите повече за това и откъде го взех, моля, посетете това.

PS.: Направих го с помощта на VS2017 и Framework 2.0.

person Artur Gomes    schedule 26.04.2017
comment
Здравей @Artur, аз направих същото. Проблемът е, че преди да щракнете върху бутона „OK“ на последния екран по време на инсталацията, приложението се стартира. Приложението се стартира само и само когато щракна върху бутона OK. Моля, помогнете ни. - person dilipkumar1007; 16.05.2017
comment
Здравей @dilipkumar1007. Опитахте ли да замените метода OnAfterInstall? Не съм сигурен за това. Ако имате някакви резултати, моля споделете. Актуализация: Не... поведението е същото... - person Artur Gomes; 17.05.2017
comment
Здравей @dilipkumar1007. След последния ми отговор направих някои търсения и мисля, че най-накрая получих поведението, от което се нуждаете. Опитах подхода fire.eagle по-долу, използвайки стъпките в тази връзка тук. В моя случай трябваше да премахна всички кавички в скрипта PostBuildEvent. (...) - person Artur Gomes; 17.05.2017
comment
(...) След това и възстановяването на моя проект за настройка, инсталационният процес ще има последна страница за отваряне на приложението? което ще стане, след като прекратите инсталационното приложение. - person Artur Gomes; 17.05.2017
comment
Още нещо. С помощта на този метод можете да се отървете от тези персонализирани действия и класове за настройка, тъй като скриптът ще направи всичко вместо вас. Надяваме се, че това е, което търсите. - person Artur Gomes; 17.05.2017
comment
Здравейте @Artur Gomes, Благодаря за вашето предложение. Но не работи. Остава същият. - person dilipkumar1007; 19.05.2017
comment
Здравей @Artur Gomes, имам същия код в PostBuildEvent и не премахнах кавички. Но проблемът е същият. Приложението е стартирано преди да щракнете върху бутона за затваряне. - person dilipkumar1007; 19.05.2017
comment
Здравей @dilipkumar1007. Копирахте ли името на файла EnableLaunchApplication.js в папката на проекта за настройка? Моля, следвайте връзката, посочена в точка 1 на тази статия. (...) - person Artur Gomes; 19.05.2017
comment
(...) след това трябва да замените var filename в горната част на скрипта с името на вашия изпълним файл (файлът, който искате да стартирате). Не забравяйте да попълните PostBuildEvent в свойствата на проекта за настройка със споменатия низ cscript.exe $(ProjectDir)EnableLaunchApplication.js $(BuiltOuputPath). При мен работи без никакви кавички. С кавички ще даде грешка при изграждането на msi пакета. - person Artur Gomes; 19.05.2017
comment
Здравей, @Artur Gomes, благодаря ти за любезната подкрепа. Но бих искал да кажа, че съм добавил същите неща, каквото и да предложи чрез дадена връзка, и също така, обвързвам скрипта PostBuildEvent с кавички, защото без кавички той повдига код на грешка 1. - person dilipkumar1007; 23.05.2017
comment
Здравей @dilipkumar1007. Няма проблем. Странно наистина. В моя случай с кавички дава код 1 грешка. Може би низът на пътя, който използвате, има интервали или невалидни знаци. Също така, изписвате ли правилно името на вашия изпълним файл в горната част на скрипта? (питам само за да съм сигурен, съжалявам). Можете ли да опитате да изградите своя проект за настройка в път без интервали? - person Artur Gomes; 23.05.2017
comment
Здравей @Artur Gomes, Опитах всички аспекти, които спомена, но не постигнах никакъв успех. Можем ли да разговаряме на [email protected], ако нямате проблем, сър? - person dilipkumar1007; 24.05.2017
comment
Здравей @dilipkumar1007. Съжалявам, че късно отговарям. Опитахте ли опциите, споменати в тази публикация. Те обясняват някои промени в скрипта, за да заобиколят няколко проблема и може би са разрешили грешката в код 1. - person Artur Gomes; 31.05.2017
comment
Здравейте, @Artur, след завършване на инсталирането на MSI настройката на прозорец, моите необработени файлове (дизайн и кодиране) също се показват на мястото за инсталиране. Разработих това приложение с помощта на Visual Studio 2010. Инсталацията е създадена успешно, но след инсталирането на този MSI този проблем се случва. Моля, помогни ми. Благодаря предварително. - person dilipkumar1007; 02.08.2017
comment
Здравей @dilipkumar1007. Присъединихте ли тези файлове към инсталационния пакет? Освен ако не го искате, не трябва. В края на краищата, основно ви трябва само първичният изход за вашите изпълними проекти в решението и всички други допълнителни файлове, които ще ви трябват в производството. Проверете какво сте избрали да добавите към инсталационния проект. - person Artur Gomes; 03.08.2017

Опитайте да разгледате тази публикация в блога: http://blogs.msdn.com/b/astebner/archive/2006/08/12/696833.aspx

Не мога да потвърдя дали работи за 2010 г. или не; Все още съм заседнал да използвам 2008, докато моят TFS сървър не бъде надстроен. Освен това използвам WiX за моите инсталатори. Но това е просто персонализирано действие, така че мисля, че все още трябва да се поддържа.

Надявам се това да помогне!

(Между другото, докато се упражнявах да търся в Google, за да намеря това, вашият въпрос се показваше на първата страница на Google за този въпрос.)

person fire.eagle    schedule 02.07.2010
comment

Не можете да добавяте един и същ изглед няколко пъти. Манипулаторът на потребителския интерфейс ще полудее. За да се уверя в това, опитах да направя това, което казахте по-горе, и получих същия проблем. Потребителският интерфейс замръзва, изображението се появява само за една от клетките.

Най-доброто нещо, което можете да направите, е да съхранявате вашето изображение като разпределено UIImage и да имате помощна функция, която връща нов UIImageView на клетка.

Използвайки текущия си метод (без съхранено UIImage), можете да направите:

-(UIImageView *) makeCheckmarkOffAccessoryView
{
    return [[[UIImageView alloc] initWithImage:
        [UIImage imageNamed:@"checkmarkOff.png"]] autorelease];
}

И тогава направете

cell.accessoryView = [self makeCheckmarkOffAccessoryView];

Както може би знаете, UIImages от друга страна може да се използва произволен брой пъти. UIImageView не заема много място, така че можете лесно да имате куп такива, без да се притеснявате.

За да разширите сделката само на едно място, представете си, че добавяте UIView на две места едновременно.

Какво ще направи [ob removeFromSuperview] за този обект? Ще премахне ли изгледа и от двете места? Само от един от тях? Коя стойност ще бъде върната, когато поискате [ob superview]? Ясно е, че потребителският интерфейс не е направен да се справя с това, което искате.

- person fire.eagle; 03.07.2010
comment
Благодаря! Мисля да разгледам WiX, тъй като прочетох някои добри неща за него. - person ThaKidd KG5ORD; 03.07.2010

Добавяне на друг отговор, тъй като нито един от предишните отговори не се отнася до въпроса за квадратчето за отметка или бутона в оригиналната публикация.

Бихте добавили един от готовите диалогови прозорци към вашия проект за настройка, нещо като CheckBoxes(A), като щракнете с десния бутон върху бутона Старт в изгледа на потребителския интерфейс. Щракнете с десния бутон върху диалоговия прозорец след добавяне, за да го преместите нагоре. Нуждаете се само от едно квадратче за отметка за въпроса за стартиране на програмата, така че елиминирайте останалите. Името на свойството по подразбиране е CHECKBOXA1, така че добавете условие към персонализираното действие, което задейства вашия код CHECKBOXA1=1, което означава, че е отметнато.

person PhilDW    schedule 06.12.2015

първо генерирайте клас на инсталатора. в това замени метода на инсталиране. и поставете следната команда.

  public override void Install(IDictionary stateSaver) {
        
    System.Diagnostics.Process.Start(System.IO.Path.GetDirectoryName(this.Context.Parameters["AssemblyPath"]) + @"\windowsAgent.exe");   
              
 }
person Hirusha Randunu    schedule 29.06.2021