c# custom action is not deleting particular file - c#

I have found that on un-installing myproject setup installer is removing all files but not one conn.cnf file .I want it to be removed too . so I used custom Actions installer class.but it is not removing that file .
this is my code
[System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)]
public override void Uninstall(IDictionary savedState)
{try
{
base.Uninstall(savedState);
if (System.IO.File.Exists(Application.StartupPath + "\\Conn.cnf"))
System.IO.File.Delete(Application.StartupPath + "\\Conn.cnf");
}
catch (Exception es) { MessageBox.Show(es.Message); }
}
i have tested if cursor is going in this block or not, by putting a messageBox. which is being execute on un-installation .I have also checked file name ,am i trying to delete file in a wrong way ? Help me. thanks

This is quite difficult to find out the application path. Actually its not an application path its installation directory. When you try to find Application path using Application.StartupPath. You may get C:\System or something like that directory. Because your application is using Windows Installer to uninstall and install the application from the computer and the Windows Installer is installed in System folder. You should try to find Target Directory instead of Application or Executable path.
You can get the Target Directory from the Context Parameter like this.
string targetFolder = Context.Parameters["TARGETDIR"];

Related

Creating an auto updating Windows service [duplicate]

For the project I am working on, I am not allowed to use ClickOnce. My boss wants the program to look "real" (with an installer, etc).
I have installed Visual Studio 2012 Professional, and have been playing around with the InstallShield installer, and it definitely makes nice installers, but I can't figure out how to enable the application to "auto-update" (that is, when it starts up, checks to make sure that it is using the latest version).
I have been asked to make a tiny change to the code - switching an addition to a subtraction, and I don't really want people to have to uninstall the old version, and then have to reinstall the new version every time I make a small change like this.
How can I make the application check for updates, and install them? Or is this not possible (or not easy)?
There are a lot of questions already about this, so I will refer you to those.
One thing you want to make sure to prevent the need for uninstallation, is that you use the same upgrade code on every release, but change the product code. These values are located in the Installshield project properties.
Some references:
Auto update .NET applications
Auto-update library for .NET?
Auto update for WinForms application
Suggest a method for auto-updating my C# program
Automatic update a Windows application
I think you should check the following project at codeplex.com
http://autoupdater.codeplex.com/
This sample application is developed in C# as a library with the project name “AutoUpdater”. The DLL “AutoUpdater” can be used in a C# Windows application(WinForm and WPF).
There are certain features about the AutoUpdater:
Easy to implement and use.
Application automatic re-run after checking update.
Update process transparent to the user.
To avoid blocking the main thread using multi-threaded download.
Ability to upgrade the system and also the auto update program.
A code that doesn't need change when used by different systems and
could be compiled in a library.
Easy for user to download the update files.
How to use?
In the program that you want to be auto updateable, you just need to call the AutoUpdate function in the Main procedure. The AutoUpdate function will check the version with the one read from a file located in a Web Site/FTP. If the program version is lower than the one read the program downloads the auto update program and launches it and the function returns True, which means that an auto update will run and the current program should be closed. The auto update program receives several parameters from the program to be updated and performs the auto update necessary and after that launches the updated system.
#region check and download new version program
bool bSuccess = false;
IAutoUpdater autoUpdater = new AutoUpdater();
try
{
autoUpdater.Update();
bSuccess = true;
}
catch (WebException exp)
{
MessageBox.Show("Can not find the specified resource");
}
catch (XmlException exp)
{
MessageBox.Show("Download the upgrade file error");
}
catch (NotSupportedException exp)
{
MessageBox.Show("Upgrade address configuration error");
}
catch (ArgumentException exp)
{
MessageBox.Show("Download the upgrade file error");
}
catch (Exception exp)
{
MessageBox.Show("An error occurred during the upgrade process");
}
finally
{
if (bSuccess == false)
{
try
{
autoUpdater.RollBack();
}
catch (Exception)
{
//Log the message to your file or database
}
}
}
#endregion
The most common way would be to put a simple text file (XML/JSON would be better) on your webserver with the last build version. The application will then download this file, check the version and start the updater. A typical file would look like this:
Application Update File (A unique string that will let your application recognize the file type)
version: 1.0.0 (Latest Assembly Version)
download: http://yourserver.com/... (A link to the download version)
redirect: http://yournewserver.com/... (I used this field in case of a change in the server address.)
This would let the client know that they need to be looking at a new address.
You can also add other important details.
A Lay men's way is
on Main() rename the executing assembly file .exe to some thing else
check date and time of created.
and the updated file date time and copy to the application folder.
//Rename he executing file
System.IO.FileInfo file = new System.IO.FileInfo(System.Reflection.Assembly.GetExecutingAssembly().Location);
System.IO.File.Move(file.FullName, file.DirectoryName + "\\" + file.Name.Replace(file.Extension,"") + "-1" + file.Extension);
then do the logic check and copy the new file to executing folder
This is the code to update the file but not to install
This program is made through dos for copying files to the latest date and run your program automatically. may help you
open notepad and save file below with ext .bat
xcopy \\IP address\folder_share_name\*.* /s /y /d /q
start "label" /b "youraplicationname.exe"
These days you could use included in Windows 10 mechanism for app delivery called AppInstaller by packaging your app in MSIX bundle or package.
With it, you don't have to think about an installer (if your app doesn't use a lot of dependencies), background updating, and all of that. It's much better than ClickOnce, command-line usage works like a charm thanks to aliases, updates are non-obtrusive and could be used for background apps too.
The installation experience is much better too: a user just needs to click a button on HTML and Windows will install the app automatically.
It's not super-simple, I'd say more complicated than ClickOnce, but not as hard as Wix.
Official guide doesn't work with .NET Core or .NET 5 apps, so you can refer to this article, or to this great video, for example. This site also contains a lot of useful information.

My program stop when it saves files on the directory (inside the app directory) after creating the setup by inno setup Compiler?

On my project I have instructions that save Excel Files in a folder called "Ficheirs" inside the Project bin\debug directory (bin\debug\fichiers) using: Directory.GetCurrentDirectory() + "\Fichiers" to set the path to that , it works well before creating the setup
However after creating the setup using inno Setup Compiler , and eventually adding the folder "Ficheirs" while creating the setup , my program doesn't work
How to fix that so that my program keeps saving my excel files on that folder ?
Directory.GetCurrentDirectory() + "\Fichiers"
This is a very unreliable function to set a path to a directory.
Without testing, the application can work in a different directory at the time you are asking for GetCurrentDirectory().
e.g the working directory of the setup / App at the moment you run GetCurrentDirectory()
App\
App\bin\
App\bin\debug\
GetCurrentDirectory()+ "\Fichiers" returns
D:\Programs\App\Fichiers
D:\Programs\App\bin\Fichiers
D:\Programs\App\bin\debug\Fichiers
You should force at install all needed Dirs
Here is an example of a [Dirs] section:
[Dirs]
Name: "{app}\bin"
Name: "{app}\bin\debug"
Name: "{app}\bin\debug\Fichiers"
inside C#
Test before writing
try
{
// Set the current directory.
string target = Application.StartupPath + "\\bin\\debug\\Fichiers";
if (!Directory.Exists(target))
{
Directory.CreateDirectory(target);
}
// Change the current directory.
Environment.CurrentDirectory = (target);
..............
Setup iss
[Code]
var
excelPath : String;
..............
excelPath := ExpandConstant('{app}\bin\debug\Fichiers');

Changing app.configuration file during installation process with visual studio installer fails: Could not load file or assembly 'EntityFramework'

Project Info: We are creating an installer project that allows users to choose a servername and databasename. After installation of the main program a corresponding database will be created.
Installer project :
Has an additional UI screen with two textboxes, containing servername and
databasename.
An custom action will be executed on installation and has the servername and databasename defined as custom action data.
Main application:
An installer class wires the after-installation event. This class will automatically be executed during installation. The custom action data will be passed as paramaters to this class.
After-installation event will trigger a method that:
Creates the database
Gets the app.config file and adjusts the connectionstring.
Everything works well expect saving the configuration file: we recieve this error:
System.Configuration.ConfigurationErrorsException: An error occurred creating >the configuration section handler for entityFramework: Could not load file or >assembly 'EntityFramework, Version=6.0.0.0, Culture=neutral, >PublicKeyToken=b77a5c561934e089'
Strange enough we don't get any error with entityframwork when running and debugging the main application. Also we were able to execute the code as unittest, so this assembly problem occurs only when changing the configuration file during installation with visual studio installer
Below you can find the code to change the configuration file.
void DeployInstaller_AfterInstall(object sender, InstallEventArgs e)
{
try
{
Configuration config = ConfigurationManager.OpenExeConfiguration(Assembly.GetExecutingAssembly().Location);
string connectionsection = config.ConnectionStrings.ConnectionStrings
["XBSDbDataContext"].ConnectionString;
ConnectionStringSettings connectionstring = null;
if (connectionsection != null)
{
config.ConnectionStrings.ConnectionStrings.Remove("XBSDbDataContext");
}
connectionstring = new ConnectionStringSettings("XBSDbDataContext", connectionString);
config.ConnectionStrings.ConnectionStrings.Add(connectionstring);
config.Save(ConfigurationSaveMode.Minimal, true);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
Any idea what can be the cause and how to resolve it? Many thanks in advance.
-- UPDATE -- WE FOUND A WORK AROUND.
By avoiding to use the ConfigurationManager class to edit the configuration
file we no longer have this problem. This is now done with the system.xml
namespace.
//updating config file
XmlDocument XmlDoc = new XmlDocument();
MessageBox.Show(Assembly.GetExecutingAssembly().Location + ".config");
XmlDoc.Load(Assembly.GetExecutingAssembly().Location+".config");
foreach (XmlElement xElement in XmlDoc.DocumentElement)
{
if (xElement.Name == "connectionStrings")
{
xElement.LastChild.Attributes["connectionString"].Value = connectionString;
}
}
XmlDoc.Save(Assembly.GetExecutingAssembly().Location + ".config");
If that Dll (or a dependency of it) is being installed to the GAC by your MSI, the problem is that installed GAC assemblies are not actually accessible in the GAC until the Commit stage of the install. Depite the name "AfterInstall" that event is actually "near the end of the install". If you move that custom action to be a Commit custom action and it works then that was the issue.
In general it often works better to do these things at first run of the app - see that it is not configured and then do the creation, connection string stuff etc. It is much more straightforward to debug; in an installer class you are running with the local system account (in a per machine install) or a non-elevated user (in a per user install) and these can cause issues with security etc. Apart from that, if the user wants to move the database, or the server name changes etc you could run some of that configuration again.

How to get the installed application location in c#?

I have created a WPF application in my application i'm specifying the default path for the installation location suppose, XYZ is my application, "C:\MyApplication\XYZ\" this is my specified default location where my application gets installed, my application creates a folder dynamically which will be created during the installation of the application in the installed directory, i want when user uninstalls the application then my entire folder(XYZ) has to be deleted i tried many ways but i'm not getting it Please any one give suggestion it will helps me a lot.
Here is what i have tried :-
string filepath = String.Format(#"data\local", Environment.CurrentDirectory);
public override void Uninstall(IDictionary savedState)
{
try
{
base.Uninstall(savedState);
// If i Hard code this i.e if i give direct path(C:\MyApplication\XYZ\)
// then it's getting deleted but if user installs application in other
// location it gets fail.
Microsoft.VisualBasic.FileIO.FileSystem.DeleteDirectory(
filepath,
Microsoft.VisualBasic.FileIO.DeleteDirectoryOption.DeleteAllContents);
}
catch(Exception e)
{
MessageBox.Show(e);
}
}
Application installation is not something that we need to manage manually in the .NET Framework. It provides multiple installation options, so you do not have to manually install or uninstall your applications. The two main installation options the Framework are:
ClickOnce Deployment
Setup Projects
As there is far to much to discuss here, please follow the links to find out more.

Can not copy files to Environment.SpecialFolder.Startup in WPF

To make my application to start on Windows sturup I decided to put a shortcut to Startup folder.
I tried to use:
File.Move(AppDomain.CurrentDomain.BaseDirectory + "ApplicationName.exe", Environment.GetFolderPath(Environment.SpecialFolder.Startup) + "ApplicationName.lnk");
It works, but it moves my shortcut not to the folder I need.
Environment.GetFolderPath(Environment.SpecialFolder.Startup)
works well, it returns:
C:\Users\Germanov\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
But my shortcut appears in
C:\Users\Germanov\AppData\Roaming\Microsoft\Windows\Start Menu\Programs
Just 1 folder "behind".
File.Delete(Environment.GetFolderPath(Environment.SpecialFolder.Startup) + "ApplicationName.lnk");
also works "strange". It actually deletes this file, but again not in "Startup" folder.
If I try to manually add "\Startup" to the path like this:
Environment.GetFolderPath(Environment.SpecialFolder.Startup) + #"Startup\ApplicationName.lnk"
I get a System.IO.Excseption.
I can't type this path manually, I neen my application to work at diferent PCs with different versions of Windows. I also can't use Registry to make my application start with windows startup.
I use Windows 7, Visual Studio 2010, .NET 4.0, this is a WPF project.
Any ideas?
Did you tried Environment.SpecialFolder.CommonStartup instead of Startup, I don't know why startup is not working for your requirement. Most of installer package do this for you; why do you want to do this for your self? Any reason not for using Registry?
I tried this code on my machine
var startup = Environment.GetFolderPath(Environment.SpecialFolder.CommonStartup);
string file = Path.Combine(startup, "MyApp.lnk");
using (StreamWriter sw = new StreamWriter(file))
{
sw.WriteLine("Test");
}
And its coming on my startup
You should use System.IO.Path.Combine() so that you won't create StartupApplication1.exe. Note the missing backslash.

Categories