How to detect the install directory of a project? - c#

I have a Visual studio C# project and I have an installer that installs the files into whatever directory the user specifies. I also have another installer with localized language resources and I want that to be installed in the aforementioned directory.
Can anyone point me in the right direction on this? I think I have to do something with registry keys but I don't know what to do.
Edit: For the record, I found this page: How to: Use a Registry Launch Condition to Specify a Target Directory. And I followed the instructions and it did what I wanted it to do.

Typically, you would create a registry subkey and value of HKEY_LOCAL_MACHINE\SOFTWARE\ and then just read that key back in your second installer to decide where to put that.
Something like HKLM\SOFTWARE\MyApplication,
Then you make a string value called InstallPath and write the path from your first installer there.
Depending on what you're doing, you may want to have a look at merge modules for installing several components with one MSI.

You are on the right track. Your first installer would write it's install path to a well known registry key. The second installer would read the path from that well known key and put it's dlls in the appropriate sub folders.

Here is one way to go at it:
Assembly a = Assembly.GetExecutingAssembly();
string folder = System.IO.Path.GetDirectoryName(a.CodeBase);

Related

C# How to get current directory path

Scenario :
I've created a library project which provides interface to installer(exe created using install shield).I want to check whether a particular file exists in the installer folder.
I've tried following :
1). Assembly.GetEntryAssembly().Location
// Throws "Object reference not set to an instance of an object"
2). new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath
// return :
C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
3). Assembly.GetExecutingAssembly().Location
// returns empty string
4). AppDomain.CurrentDomain.BaseDirectory
// returns "C:\Windows\syswow64\" irrespective of the actual path
Could anyone tell me how can I get directory path from where the installer is being executed?
You can use
Directory.GetCurrentDirectory();
to get current directory path
import System.IO
I will answer my own question, It's not possible to get current path from library project. You'll have to get it from installer. There is no other way.
Thank you.
If you want to get the folder where your exe is resting
AppDomain.CurrentDomain.BaseDirectory
this returns the whole path to the Folder which contains the exe. From there on you can add your folders manually
AppDomain.CurrentDomain.BaseDirectory + #"MyFolder1\MyFolder2";
Assuming you are running an MSI-based install built by InstallShield:
The problem you're having is because of the way those calls work. You're implementing this in an external Dll, and Dlls don't have their own current directory - they have the current directory of the process that's calling into the Dll. In this case you're being called from an msiexec.exe process (assuming you are doing this in a custom action) so you'll get msiexec.exe's current directory.
Apart from that, some other observations:
You don't say exactly when you are calling your code, but it might be before the user has chosen the installation folder, so the search doesn't really help.
InstallShield probably provides support for a file search. If this is an MSI setup it definitely does.
Installs hardly ever look for files in an install folder because there is rarely a good reason. If you need the file, add it to your install, or if it's a redistributable then add the standard redist package, maybe a merge module. If that file belongs to another setup, what will you do if that product is uninstalled? Are you checking the version to see if it's compatible with your application? In general, all setups install the files they need and shared files are backwards compatible if they are used by several different products.
Try this one, it always works for me:
Environment.CurrentDirectory
use above property as follow.
string currentDirectory = Path.GetDirectoryName(Environment.CurrentDirectory);
If you want that path in the InstallShield use this
Setup.exe - Use the SETUPEXEDIR property
http://www.installshield.com/news/newsletter/0206-articles/SetupExeDir.asp.
Depending on version of installshield you are using try different properties
1. SRCDIR
2. SETUPEXEDIR
3. SUPPORTDIR
If you have a C# code to read preperties use MsiGetProperty like below
MsiGetProperty( hMSI, "SETUPEXEDIR", Value, Size )
string assemblyPath = Context.Parameters["assemblyPath"];
int i = assemblyPath.Length - 1;
while (assemblyPath[i] != '\\') --i;
string folder = assemblyPath.Substring(0, i);

Post-Install adding files to avoid the .MSI AutoRepair feature

I am unsure how to phrase the title - which may be incorrect - so I will attempt to elaborate here.
The problem: .MSI installer auto repairs missing files (images) after manually deleting them from the directory.
What I want: I need my application to install a bunch of icons into the directory. These icons are considered "default" Icons and the user can, if they want, remove them from the directory. When the user removes them from the directory, I don't want the .MSI installer to "Auto Repair" them back into the directory.
I am not sure the best way to handle this situation. Any programming advice will be taken seriously.
Thanks for your time.
I think you can set the ComponentId to null https://msdn.microsoft.com/en-us/library/aa368007(VS.85).aspx

Find / Predict *.msi file installation location reading *.msi database

Whenever we install a software, Windows OS will keep a backup copy of installer *.msi at C:\Windows\Installer\ location.
So I am iterating through all the msi file present at "C:\Windows\Installer\"
I want to prepare a mapping list where list will have *.msi file and its default location.
Let say C:\Windows\Installer[some product key]\123xR23.msi
Consider "123xR23.msi" is backup file for WinZip installation. And installer has install WinZip at location "C:\Program Files(x86)\WinZip"
So list will have following entry
"123xR23.msi","C:\Program Files(x86)\WinZip"
Please help me.
Thanks
First off, why do you even need this?
There is a mapping of these *.msi files already in existence in the registry at HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\\Products\\InstallerProperties then the value of the msi is under LocalPackage
The S-1-5-18 is the Security ID of Local System.
The ProductGUID is also a bit weird here. In your installer you will see something like
2F7DBBE6-8EBC-495C-9041-46A772F4E311
but the product GUID in the registry path will look like this
6EBBD7F2CBE8C5940914647A274F3E11
There's definitely a reason for this but I don't know what it is. You'll just have to transform your product guid to this other representation when looking in the registry.
There is also a registry key called InstallLocation which should contain the install location of the msi package. This isn't always filled in though. Perhaps the install directory is stored somewhere else in the registry I don't know you'll have to look around probably.
Edit: Looks like each component of the install gets an entry by GUID in the registry as well which contains the path it was installed to. This could help you find the install location of a specific MSI if it is not listed under InstallLocation mentioned above. Per Micheal's comment, I would suggest taking advantage of the Msi related functions (https://msdn.microsoft.com/en-us/library/windows/desktop/aa372420(v=vs.85).aspx)

Install app which uses .dll with IExpress Wizard

I have two applications which will be installed by a single executable. The problem I'm facing is that one of them uses a .dll. And whenever the IExpress package tries to run the first executable it says that the .dll could not be found, even tough I added the .dll inside and outside the package.
There is any way to make it work with IExpress, which has the required characteristics?
There is any alternative to my problem, as a similar software, for instance?
This sounds vaguely similar to this question:
Iexpress is extracting to %temp% folder... How do I prevent this?
As I mentioned in my answer, check: (1) is long file name (LFN) support enabled? and (2) is the .dll actually in the archive?
If checking those things doesn't resolve it, I would use Process Monitor to see which directories the executable is searching to locate the .dll file. It should ideally be looking in the extraction directory (eg %temp%\IXP000.TMP), since that's the current directory when the executable is running.
Of course there are several other utilities that do what IExpress does that you might try instead: 7-Zip, Inno Setup, NSIS, WinRAR, WiX – just to name a few.

How to check if c# project installation path exists

I want to get the installed path of a C# project setup. In C#.net. How can I use this path in Installer Class for checking that the setup is installed or not?
Actually I want to check if the setup is installed in the system or not . If it is, I want to repair this.
Create a register entry with the installer.
hkey_local_machine/software/ and a var installdir with value the path.
When you have an update version of your program, check in the installer class for that key. If it exists update, else new install.
You can get the path of the folder that you are installing to from
Context.Parameters["targetdir"]
So you can check that is empty before installing. Obviously that won't tell you if there are other versions installed elsewhere.
I don't understand exactly what you want but you could simply check whether a directory exists by using Directory.Exists method
Environment.SystemDirectory gets the system directory on the machine.

Categories

Resources