Launching .vsto file after installation. (InstallShield) - vsto

I have an msi installer, made via InstallShield, which moves some files to required location,
writes some info to registry and installes VSTO runtime. But I need to launch the .vsto file, that is installed with the application, after the installation is over. Can I do this with custom actions? If that file was an .exe file, that would be rather easy, but how could I launch a .vsto file?
[upd]
Well, may be there is an easier solution:
Can I just call the function:
public override void Install(IDictionary stateSaver)
from InstallShield? Something like that:
Custom Action->Call a function in a Windows Installer dynamic link library->stored in binary table=>
AssemblyFile = \InclusionListCustomActions.dll
MethodSignature = InclusionListCustomActions.TrustInstaller.Install(but what parameter goes here?)

You shouldn't launch the VSTO file because this will only install it per-user. What you should do is add it to the AddIns registry key for the office application you need and use the |vstolocal attribute to tell it to not deploy to the click once cache.

you can follow steps described in http://msdn.microsoft.com/en-us/library/cc563937%28v=office.12%29.aspx, you can copy same steps in Installshield, After file is copied and registry value set as specified, on starting office app it will automatically pick up vsto file
To add information to inclusion list you will have to write a console application and then call console app from installshield. Below code will help
string RSA_PublicKey = #"<RSAKeyValue><Modulus></Modulus></RSAKeyValue>";
//get this key from .vsto file
try
{
SecurityPermission permission =
new SecurityPermission(PermissionState.Unrestricted);
permission.Demand();
}
catch (SecurityException)
{
Console.WriteLine(
"You have insufficient privileges to " +
"register a trust relationship. Start Excel " +
"and confirm the trust dialog to run the addin.");
Console.ReadLine();
}
Uri deploymentManifestLocation = null;
var excelPath = YourAPPPath;
if (Uri.TryCreate(excelPath,
UriKind.RelativeOrAbsolute, out deploymentManifestLocation) == false)
{
Console.WriteLine(
"The location of the deployment manifest is missing or invalid.");
Console.ReadLine();
}
if (!File.Exists(excelPath))
{
UserInclusionList.Remove(deploymentManifestLocation);
Console.WriteLine(deploymentManifestLocation.ToString() + "removed from inclusion list");
}
else
{
AddInSecurityEntry entry = new AddInSecurityEntry(
deploymentManifestLocation, RSA_PublicKey);
UserInclusionList.Add(entry);
Console.WriteLine(deploymentManifestLocation.ToString() + "Added to inclusion list");
}

Related

How do I generate a file based on user input in MSI created using WixSharp?

I created an installation MSI package using WixSharp. I have a custom dialog with language, server, etc. options. I want to generate an application config file based on these options and deploy it next to the .exe file as part of an installation process. If it is possible, how should I do that?
You can subscribe on AfterInstall event (when files has been coppied) and modify your config file there.
AfterInstall demostration
project.AfterInstall += project_AfterInstall;
...
static void project_AfterInstall(SetupEventArgs e)
Installation directory you can find here:
private void OnAfterInstall(SetupEventArgs e)
{
var installationPath = e.Session["INSTALLDIR"];
// Change your config file here
// if you need to modify your file once time after installation
// just add this one condition if (e.IsInstalled) { ... }
}

How to Add Permission on Visual Basic for Windows 10 [duplicate]

Once my program is installed on a client machine, how do I force my program to run as an administrator on Windows 7?
You'll want to modify the manifest that gets embedded in the program. This works on Visual Studio 2008 and higher: Project + Add New Item, select "Application Manifest File". Change the <requestedExecutionLevel> element to:
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
The user gets the UAC prompt when they start the program. Use wisely; their patience can wear out quickly.
Adding a requestedExecutionLevel element to your manifest is only half the battle; you have to remember that UAC can be turned off. If it is, you have to perform the check the old school way and put up an error dialog if the user is not administrator (call IsInRole(WindowsBuiltInRole.Administrator) on your thread's CurrentPrincipal).
The detailed steps are as follow.
Add application manifest file to project
Change application setting to "app.manifest"
Update tag of "requestedExecutionLevel" to requireAdministrator.
Note that using this code you need to turn off the security settings of ClickOnce, for do this, go inside Properties -> Security -> ClickOnce Security
I implemented some code to do it manually:
using System.Security.Principal;
public bool IsUserAdministrator()
{
bool isAdmin;
try
{
WindowsIdentity user = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(user);
isAdmin = principal.IsInRole(WindowsBuiltInRole.Administrator);
}
catch (UnauthorizedAccessException ex)
{
isAdmin = false;
}
catch (Exception ex)
{
isAdmin = false;
}
return isAdmin;
}
You can embed a manifest file in the EXE file, which will cause Windows (7 or higher) to always run the program as an administrator.
You can find more details in Step 6: Create and Embed an Application Manifest (UAC) (MSDN).
While working on Visual Studio 2008, right click on Project -> Add New Item and then chose Application Manifest File.
In the manifest file, you will find the tag requestedExecutionLevel, and you may set the level to three values:
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
OR
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
OR
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
To set your application to run as administrator, you have to chose the middle one.
Another way of doing this, in code only, is to detect if the process is running as admin like in the answer by #NG.. And then open the application again and close the current one.
I use this code when an application only needs admin privileges when run under certain conditions, such as when installing itself as a service. So it doesn't need to run as admin all the time like the other answers force it too.
Note in the below code NeedsToRunAsAdmin is a method that detects if under current conditions admin privileges are required. If this returns false the code will not elevate itself. This is a major advantage of this approach over the others.
Although this code has the advantages stated above, it does need to re-launch itself as a new process which isn't always what you want.
private static void Main(string[] args)
{
if (NeedsToRunAsAdmin() && !IsRunAsAdmin())
{
ProcessStartInfo proc = new ProcessStartInfo();
proc.UseShellExecute = true;
proc.WorkingDirectory = Environment.CurrentDirectory;
proc.FileName = Assembly.GetEntryAssembly().CodeBase;
foreach (string arg in args)
{
proc.Arguments += String.Format("\"{0}\" ", arg);
}
proc.Verb = "runas";
try
{
Process.Start(proc);
}
catch
{
Console.WriteLine("This application requires elevated credentials in order to operate correctly!");
}
}
else
{
//Normal program logic...
}
}
private static bool IsRunAsAdmin()
{
WindowsIdentity id = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(id);
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}
As per
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
you will want to add an application manifest if you don't already have one or don't know how to add one. As some projects don't automatically add a separate manifest file, first go to project properties, navigate to the Application tab and check to make sure your project is not excluding the manifest at the bottom of the tap.
Next, right click project
Add new Item
Last, find and click Application Manifest File
In Visual Studio 2010 right click your project name.
Hit "View Windows Settings", this generates and opens a file called "app.manifest".
Within this file replace "asInvoker" with "requireAdministrator" as explained in the commented sections within the file.
You can create the manifest using ClickOnce Security Settings, and then disable it:
Right click on the Project -> Properties -> Security -> Enable ClickOnce Security Settings
After you clicked it, a file will be created under the Project's properties folder called app.manifest once this is created, you can uncheck the Enable ClickOnce Security Settings option
Open that file and change this line :
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
to:
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
This will make the program require administrator privileges.
In case you want a code-only solution for some reason, here's a standalone class file. Just call "AdminRelauncher.RelaunchIfNotAdmin()" at application start:
using System;
using System.Diagnostics;
using System.Reflection;
using System.Security.Principal;
public static class AdminRelauncher
{
public static void RelaunchIfNotAdmin()
{
if (!RunningAsAdmin())
{
Console.WriteLine("Running as admin required!");
ProcessStartInfo proc = new ProcessStartInfo();
proc.UseShellExecute = true;
proc.WorkingDirectory = Environment.CurrentDirectory;
proc.FileName = Assembly.GetEntryAssembly().CodeBase;
proc.Verb = "runas";
try
{
Process.Start(proc);
Environment.Exit(0);
}
catch (Exception ex)
{
Console.WriteLine("This program must be run as an administrator! \n\n" + ex.ToString());
Environment.Exit(0);
}
}
}
private static bool RunningAsAdmin()
{
WindowsIdentity id = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(id);
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}
}
THIS DOES NOT FORCE APPLICATION TO WORK AS ADMINISTRATOR.
This is a simplified version of the this answer, above by #NG
public bool IsUserAdministrator()
{
try
{
WindowsIdentity user = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(user);
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}
catch
{
return false;
}
}

how to download exe files in vb.net (Visual Studio 2015)

I try make one program for download one .exe file and run for help in my job.
But idk how to make this, i'm new in VB.
I am using this code, as shown in the Visual Basic document reference:
My.Computer.Network.DownloadFile _
("http://www.cohowinery.com/downloads/WineList.txt", _
"C:\Documents and Settings\All Users\Documents\WineList.txt")
But when I try to download an .exe file, the entire file doesn't complete and I the file is only 1 kb after download.
The webclient should be the way to go a comment above highlights that too.
This is an example from another question:
Either use sync method:
public void DownloadFile()
{
using(var client = new WebClient())
{
client.DownloadFile(new Uri("http://www.FileServerFullOfFiles.net/download/test.exe"), "test.exe");
}
}
Or use new async-await approach:
public async Task DownloadFileAsync()
{
using(var client = new WebClient())
{
await client.DownloadFileTaskAsync(new Uri("http://www.FileServerFullOfFiles.net/download/test.exe"), "test.exe");
}
}
Then call this method like this:
await DownloadFileAsync();
Open up the .exe file you are trying to download in a text editor like NotePad. Odds are what is being downloaded is an HTML page showing some kind of error message like 404 not found.
Another possibility might be that AntiVirus software is moving the original EXE into quarantine and replacing it with a Quarantine MetaData file.
If the file does actually contain binary content your connection could be getting interrupted but odds are if this happened an exception would be thrown.

I want to disable enable usb port and got error "Requested registry access is not allowed. vb.net [duplicate]

Once my program is installed on a client machine, how do I force my program to run as an administrator on Windows 7?
You'll want to modify the manifest that gets embedded in the program. This works on Visual Studio 2008 and higher: Project + Add New Item, select "Application Manifest File". Change the <requestedExecutionLevel> element to:
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
The user gets the UAC prompt when they start the program. Use wisely; their patience can wear out quickly.
Adding a requestedExecutionLevel element to your manifest is only half the battle; you have to remember that UAC can be turned off. If it is, you have to perform the check the old school way and put up an error dialog if the user is not administrator (call IsInRole(WindowsBuiltInRole.Administrator) on your thread's CurrentPrincipal).
The detailed steps are as follow.
Add application manifest file to project
Change application setting to "app.manifest"
Update tag of "requestedExecutionLevel" to requireAdministrator.
Note that using this code you need to turn off the security settings of ClickOnce, for do this, go inside Properties -> Security -> ClickOnce Security
I implemented some code to do it manually:
using System.Security.Principal;
public bool IsUserAdministrator()
{
bool isAdmin;
try
{
WindowsIdentity user = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(user);
isAdmin = principal.IsInRole(WindowsBuiltInRole.Administrator);
}
catch (UnauthorizedAccessException ex)
{
isAdmin = false;
}
catch (Exception ex)
{
isAdmin = false;
}
return isAdmin;
}
You can embed a manifest file in the EXE file, which will cause Windows (7 or higher) to always run the program as an administrator.
You can find more details in Step 6: Create and Embed an Application Manifest (UAC) (MSDN).
While working on Visual Studio 2008, right click on Project -> Add New Item and then chose Application Manifest File.
In the manifest file, you will find the tag requestedExecutionLevel, and you may set the level to three values:
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
OR
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
OR
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
To set your application to run as administrator, you have to chose the middle one.
Another way of doing this, in code only, is to detect if the process is running as admin like in the answer by #NG.. And then open the application again and close the current one.
I use this code when an application only needs admin privileges when run under certain conditions, such as when installing itself as a service. So it doesn't need to run as admin all the time like the other answers force it too.
Note in the below code NeedsToRunAsAdmin is a method that detects if under current conditions admin privileges are required. If this returns false the code will not elevate itself. This is a major advantage of this approach over the others.
Although this code has the advantages stated above, it does need to re-launch itself as a new process which isn't always what you want.
private static void Main(string[] args)
{
if (NeedsToRunAsAdmin() && !IsRunAsAdmin())
{
ProcessStartInfo proc = new ProcessStartInfo();
proc.UseShellExecute = true;
proc.WorkingDirectory = Environment.CurrentDirectory;
proc.FileName = Assembly.GetEntryAssembly().CodeBase;
foreach (string arg in args)
{
proc.Arguments += String.Format("\"{0}\" ", arg);
}
proc.Verb = "runas";
try
{
Process.Start(proc);
}
catch
{
Console.WriteLine("This application requires elevated credentials in order to operate correctly!");
}
}
else
{
//Normal program logic...
}
}
private static bool IsRunAsAdmin()
{
WindowsIdentity id = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(id);
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}
As per
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
you will want to add an application manifest if you don't already have one or don't know how to add one. As some projects don't automatically add a separate manifest file, first go to project properties, navigate to the Application tab and check to make sure your project is not excluding the manifest at the bottom of the tap.
Next, right click project
Add new Item
Last, find and click Application Manifest File
In Visual Studio 2010 right click your project name.
Hit "View Windows Settings", this generates and opens a file called "app.manifest".
Within this file replace "asInvoker" with "requireAdministrator" as explained in the commented sections within the file.
You can create the manifest using ClickOnce Security Settings, and then disable it:
Right click on the Project -> Properties -> Security -> Enable ClickOnce Security Settings
After you clicked it, a file will be created under the Project's properties folder called app.manifest once this is created, you can uncheck the Enable ClickOnce Security Settings option
Open that file and change this line :
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
to:
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
This will make the program require administrator privileges.
In case you want a code-only solution for some reason, here's a standalone class file. Just call "AdminRelauncher.RelaunchIfNotAdmin()" at application start:
using System;
using System.Diagnostics;
using System.Reflection;
using System.Security.Principal;
public static class AdminRelauncher
{
public static void RelaunchIfNotAdmin()
{
if (!RunningAsAdmin())
{
Console.WriteLine("Running as admin required!");
ProcessStartInfo proc = new ProcessStartInfo();
proc.UseShellExecute = true;
proc.WorkingDirectory = Environment.CurrentDirectory;
proc.FileName = Assembly.GetEntryAssembly().CodeBase;
proc.Verb = "runas";
try
{
Process.Start(proc);
Environment.Exit(0);
}
catch (Exception ex)
{
Console.WriteLine("This program must be run as an administrator! \n\n" + ex.ToString());
Environment.Exit(0);
}
}
}
private static bool RunningAsAdmin()
{
WindowsIdentity id = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(id);
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}
}
THIS DOES NOT FORCE APPLICATION TO WORK AS ADMINISTRATOR.
This is a simplified version of the this answer, above by #NG
public bool IsUserAdministrator()
{
try
{
WindowsIdentity user = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(user);
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}
catch
{
return false;
}
}

Self updating .net CF application

I need to make my CF app self-updating through the web service.
I found one article on MSDN from 2003 that explains it quite well. However, I would like to talk practice here. Anyone really done it before or does everyone rely on third party solutions?
I have been specifically asked to do it this way, so if you know of any tips/caveats, any info is appreciated.
Thanks!
This is relatively easy to do. Basically, your application calls a web service to compare its version with the version available on the server. If the server version is newer, your application downloads the new EXE as a byte[] array.
Next, because you can't delete or overwrite a running EXE file, your application renames its original EXE file to something like "MyApplication.old" (the OS allows this, fortunately). Your app then saves the downloaded byte[] array in the same folder as the original EXE file, and with the same original name (e.g. "MyApplication.exe"). You then display a message to the user (e.g. "new version detected, please restart") and close.
When the user restarts the app, it will be the new version they're starting. The new version deletes the old file ("MyApplication.old") and the update is complete.
Having an application update itself without requiring the user to restart is a huge pain in the butt (you have to kick off a separate process to do the updating, which means a separate updater application that cannot itself be auto-updated) and I've never been able to make it work 100% reliably. I've never had a customer complain about the required restart.
I asked this same question a while back:
How to Auto-Update Windows Mobile application
Basically you need two applications.
App1: Launches the actual application, but also checks for a CAB file (installer). If the cab file is there, it executes the CAB file.
App2: Actual application. It will call a web service, passing a version number to the service and retrieve a URL back if a new version exists (). Once downloaded, you can optionally install the cab file and shut down.
One potiencial issue: if you have files that one install puts on the file system, but can't overwrite (database file, log, etc), you will need two separate installs.
To install a cab: look up wceload.exe http://msdn.microsoft.com/en-us/library/bb158700.aspx
private static bool LaunchInstaller(string cabFile)
{
// Info on WceLoad.exe
//http://msdn.microsoft.com/en-us/library/bb158700.aspx
const string installerExe = "\\windows\\wceload.exe";
const string processOptions = "";
try
{
ProcessStartInfo processInfo = new ProcessStartInfo();
processInfo.FileName = installerExe;
processInfo.Arguments = processOptions + " \"" + cabFile + "\"";
var process = Process.Start(processInfo);
if (process != null)
{
process.WaitForExit();
}
return InstallationSuccessCheck(cabFile);
}
catch (Exception e)
{
MessageBox.Show("Sorry, for some reason this installation failed.\n" + e.Message);
Console.WriteLine(e);
throw;
}
}
private static bool InstallationSuccessCheck(string cabFile)
{
if (File.Exists(cabFile))
{
MessageBox.Show("Something in the install went wrong. Please contact support.");
return false;
}
return true;
}
To get the version number: Assembly.GetExecutingAssembly().GetName().Version.ToString()
To download a cab:
public void DownloadUpdatedVersion(string updateUrl)
{
var request = WebRequest.Create(updateUrl);
request.Credentials = CredentialCache.DefaultCredentials;
var response = request.GetResponse();
try
{
var dataStream = response.GetResponseStream();
string fileName = GetFileName();
var fileStream = new FileStream(fileName, FileMode.CreateNew);
ReadWriteStream(dataStream, fileStream);
}
finally
{
response.Close();
}
}
What exactly do you mean by "self-updating"? If you're referring to configuration or data, then webservices should work great. If you're talking about automatically downloading and installing a new version of itself, that's a different story.
Found this downloadable sample from Microsoft- looks like it should help.
If you want to use a third-party component, have a look at AppToDate developed by the guys at MoDaCo.