program can't find file after install - c#

i made a program that uses a pre-made text file that hold a list of sites.
now in some computer the program works fine but, in my friend computer it doesn't.
i check the program on 2 of my windows 7 computers, and 1 xp and i don't have any errors.
this program was used for some time on XP, now my friend want to install it in his windows 7 computer at home, but the program doesn't find the file after he install the program.
this is the error he get:
System.IO.FileNotFoundException: file not found 'C:\Users\eli\AppData\Roaming\fourmlinks.txt'.
file name: 'C:\Users\eli\AppData\Roaming\fourmlinks.txt'
the thing is that i ship the this file in main program folder (Application Files), and it still cant find it.
this is the code i use to find the file when the program starts:
sring path = "";
path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\fourmlinks.txt";
System.OperatingSystem osInfo = System.Environment.OSVersion;
if (osInfo.Platform == PlatformID.Win32NT)
{
if (osInfo.Version.Major == 5 && osInfo.Version.Minor != 0)
{
//running XP
//path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\fourmlinks.txt";
path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "\\fourmlinks.txt";
}
}
you can see, that i tried to make sure it will work on windows 7 and, windows xp.
NOTE:
i don't mind changing the way i work with this file, or even loss this way and try completely different way that will work on the OS's (win 7 and XP). if u suggest me new way, i will be glad to give a try out.
my questions:
how is it possible that the program works in some computer and in some not?
will you put the file in a different place other then the program folder?
(sorry for my English)

How is it possible that the program works in some computer and in some not?
Because the program depends on something specific to a computer, and this something is different between the two computers. For example, your error message says:
file not found 'C:\Users\eli\AppData\Roaming\fourmlinks.txt'
The program is looking for a file in the Users folder; that is specific to every user on every machine, different users and different machines will have different files.
will you put the file in a different place other then the program folder
Will I? No, I can't because I'm not that user on that machine. If you mean "can my program put the file in a different place ..." then yes, it can.
string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "fourmlinks.txt");
That will get a path to the logged-on user's private application data. If you have the "fourmlinks.txt" file in this folder on your machine but someone else doesn't have this file on their machine, then that will work on your machine but not on someone else's, as you asked.
string path = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location),
"fourmlinks.txt");
That will get the path to the installed file. If both you and someone else install the program, then both you and someone else will have the file. If either of you change the file, then the other gets the changes.
So should you always use GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)? Well, that depends. GetExecutingAssembly().Location is typically a place standard users cannot write to, only read from. If you want users to only read and never write to your data, then that is a good place to put it. If you don't, then it isn't.
If you want to create a new file for users to write to and to read from, then write to Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData). If you want to install some starting data with your application but allow the user to change it, then you should include the starting data file in your application. It will get installed to System.Reflection.Assembly.GetExecutingAssembly().Location. Then your application should do something like:
string fileName = "fourmlinks.txt";
string target = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), fileName);
if (!File.Exists(target))
{
string source = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), fileName);
File.Copy(source, target);
}
Another important difference between GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) and Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) is that the former is part of your installer packages; if the user uninstalls or updates your application all their runtime changes will be deleted.
If you want each user to have their own private data that does not get deleted when the application is modified, then you want to use Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData).

Related

How do i get access to C:\Program Files\ in c#

I want to save my Files in a more generic way than on Desktop.
So i want to create my own Subfolder in Programs Folder, which i can use to save my stuff.
But i get "System.UnauthorizedAccessException" if i try to create a File using File.AppendAllText(#"C:\Program Files\MySubfolder\MyFile.txt,someString);
I even disabled the Protection of the Folders manually.
My App is not yet compiled so i cant run it as administrator, can i?
How does every Program use this Folder but i cant?
Do i need to compile my App everytime i make a small change and want to test it?
I would really apreciate Help since im stuck with that multiple hours now
It is a very bad practice to try to write in Program Files. This folder as well as other sensitive folders are protected by the OS to prevent malicious code hide between your programs or to prevent unsavy users from messing on the installed programs.
If you want to write your private stuff on your disk you can use these folders
string folder = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
string myFolder = Path.Combine(folder, "MyReservedPath");
Directory.CreateDirectory(myFolder); // if exists does nothing
string myFile = Path.Combine(myFolder, "MyPrivateData.txt");
File.WriteAllText(myFile, dataToWriteOnDisk);
The CommonApplicationData resolves to C:\programdata and this place is usually used to store information needed by your program for any user that uses it.
If you want to store some data that your program produces then it is better to use the
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
There are many other places available, just look at the Environment.SpecialFolder enum.
This code will give you a list of everything mapped to the actual folders in your system
foreach (Environment.SpecialFolder x in Enum.GetValues(typeof(Environment.SpecialFolder)))
Console.WriteLine($"{x} = {Environment.GetFolderPath(x)}");

Anybody can help to reach exact path [duplicate]

I have the code to save a file in a folder in directory
string timestamp = DateTime.Now.ToString("MM-dd-yyyy.HH-mm-ss");
var file = File.Create("Owe-Data.txt" + timestamp);
var com = System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase + timestamp + #"\Data" + file;
MessageBox.Show(com);
if (!Directory.Exists(com))
{
Directory.CreateDirectory(com);
}
using (var sw = new StreamWriter(com))
{
sw.WriteLine(InputData);
}
}
i Displayed COM it gives path bt i cant see the Data folder or Owe-Data file at that path
Anybody can tell why this happening, or should i save the Data folder in current directory where this prgram running? bt i dnt know how to reach that path. Any solutions ??
Working on windows phone 5, visual studio 2008 .NET framwork 2.0
As per the Exceptions section of documentation,the above exception is thrown when
ArgumentException ------- folder is not a member of System.Environment.SpecialFolder.
It means the OS where you are running this command does not have Environment.SpecialFolder.CommonApplicationData as one of the special folder.
For knowledge,
Environment.SpecialFolder.ApplicationData is the most common one. This folder holds per-user, non-temporary application-specific data, other than user documents. A common example would be a settings or configuration file.
Environment.SpecialFolder.CommonApplicationData is similar, but shared across users. You could use this to store document templates, for instance.
Environment.SpecialFolder.LocalApplicationData is a non-roaming alternative for ApplicationData. As such, you'd never store important data there. However, because it's non-roaming it is a good location for temporary files, caches, etcetera. It's typically on a local disk.
I think the problem may be that Environment.SpecialFolder.CommonApplicationData is common and shared between different users and the user with which you have logged in is not having rights to access the folder or the Visual Studio has not been started in Admin mode.
EDIT Look at link and try to add a manual registry Common AppData defined in the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\
Given you are asking about a .NET Windows Phone application as per the tags
I think your problem is that a .NET Windows Phone application does not have direct access to the file system; it can only access IsolatedStorage this is by design.
I would quote a Microsoft source for this but I can't seem to find one!
EDIT
See this article from MSDN

Get access to program's own directory

this is a very simple issue.
Note: I am sure people have found and posted this same issue somewhere but I can't figure out the correct search terms to find it.
Okay, so here is my issue.
Let's say my program is stored at C:\Program Files (x86)\MyProgram\Program.exe.
Now in the program, it basically does
Directory.CreateDirectory(Application.StartUpPath + "\\Files")
So basically, this would create a directory called Files in the same folder as the program itself.
Assume that I have to create the folder in that location, so using a different location is not an option.
So the real problem is, if its located in the c:\Program Files directory, my program gets "access denied" when I try to create the folder.
So how can I get something like this to work without forcing the user to run it as an admin?
If it's in Windows 7, if UAC is elevate, you won't be able to modify anything in c:\Program Files without rooting yourself via 'run as administrator'.
And since windows is a multi-user operating system, storing anything user-specific there is a recipe for disaster.
The right place for your program to put its data is in the appropriate special folder, which you can get/create via either
// user-specific application data is stored here
string userSpecificAppDataDirectory = Environment.GetFolderPath(
SpecialFolder.ApplicationData ,
SpecialFolderOption.Create
) ;
// application data common to all users is stored here
string commonAppDataDirectory = Environment.GetFolderPath(
SpecialFolder.CommonApplicationData ,
SpecialFolderOption.Create
) ;
or one of the other Environment.GetFolderPath() overloads.
In modern operating system the folder C:\program files (x86) is write protected by the OS. You can't create sub folders here without using an administrative account (and also in that case you will be asked to confirm this action unless you disable UAC). So the correct way to follow is to create your data folder in another place. The best option is the CommonApplicationData folder extracted using:
Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)
or the SpecialFolder.ApplicationData enum if your data should be differentiated by the current user of the application, or the SpecialFolder.MyDocuments if these files are produced by your user and need to be opened freely by other programs (or need to be included in a backup)
After you get the special folder provided by the OS to store application data remember to create a subfolder for your application and the other subfolders as required by your requirements
// In Win7 this usually resolves to C:\ProgramData, but do not use this folder
string appCommon = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
// This resolves to C:\programdata\your_app_name\files
string appData = Path.Combine(appCommon, "your_app_name", "files");
// This will create all directories in the specified path one by one....
if(!Directory.Exists(appData)) Directory.CreateDirectory(appData);
You could try creating any files or folders you need during your installation procedure. I am not sure what success you would find if using a third party install creator, but my understanding is that items added via the Application Files... button in the Publish tab of the Project Properties section in Visual Studio then have access privileges kind of inherently granted for use by the application.

Finding Install path of a program

I am new to C# and I have made a simple Windows Forms Application that basically updates the persons files for a game.
They have to manually move and delete certain folders just to change version every time. I have successfully accomplished this.
However before I start giving it out I really should improve it. I know I need to change the name of the processes and remove my descriptions ETC.
I have stumbled onto an error and instead of me taking a guess I think it is best to get an opinion from a more experienced person about how to do this.
I am going to use Inno Setup to make the installer for my application, this way I can be sure it will go into their program files 32 and 64 bit. So I know this will be in program files.
So now I am wondering if I have done this the correct way or not? I was using this format to find their program files:
string programFilesFolder = Environment.GetEnvironmentVariable("PROGRAMFILES(X86)") ?? Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);
However, would this work on all windows systems(XP, Vista, Win7, Win8) and is it completely accurate? I was going to use the above, and then use this:
string PATCHSELECTOR = Path.Combine(programFiles, #"PATCH SELECTOR");
if (Directory.Exists(PATCHSELECTOR))
{
string GamereliteFolder = Path.Combine(programFiles, #"GAMERELITE~1");
if (Directory.Exists(GamereliteFolder))
And then I move the files using the string method. If the file exists it is deleted before I copy the file over from PATCH SELECTOR to GAMERELITE.
Also will windows XP support using the .exe with an assembly resource embedded which is making the program need to be ran as administrator? I previously was making the assembly work through UAC however that wouldnt always work if they have UAC off or if it is XP so I thought I would try the admin assembly instead.
Can anyone possibly give me some insight, ideas or links?
For executables (not sure for websites & web application) this returns the directory where the executable lives (it's actually the base path where the framework will probe for Assemblies to load, 99% of the the that's the same thing).
System.AppDomain.CurrentDomain.BaseDirectory
This method works for any executable located in a folder which is defined in the windows PATH variable:
private string LocateEXE(String fileName)
{
string path = Environment.GetEnvironmentVariable("path");
string[] folders = path.Split(';');
foreach (var folder in folders)
{
if (File.Exists(Path.Combine(folder, fileName)))
{
return Path.Combine(folder, fileName);
}
}
return String.Empty;
}
Usage:
string pathToEXE = LocateEXE("Example.exe");
Reference:
how to find the execution path of a installed software
How can I get another application's installation path programmatically?
Couple things:
Among the already stated answers, Assembly.GetExecutingAssembly().Location will also give you the full file path of the currently "executing" Assembly. (Alternatively, GetCurrentAssembly)
If I'm reading your question correctly, you're trying to find both your own location as well as another application's. I would highly recommend seeing if the other application has a registry key that specifies the exact location - it'll make your copy step WAY more stable.

silently execute a MSI package from C#

Newbie question, let me try and make this as clear as possible. I have a program that needs to silently execute a msi package (well multiple but that's not the problem)
The MSI packages are contained in a folder located in the same directory as my program. I've given it a simple name of "InstallFiles" for the time being.
I'm not keen on using the full path name eg. C:\my program\another directory\another directory etc because it'll be put on multiple PC's, old and new, in which case the drive letter can change. So far I have:
install.StartInfo.FileName = "msiexec";
install.StartInfo.Arguments = "/i F:\\InstallFiles\\JRE.msi";
install.Start();
install.WaitForExit();
However, when its launched it only gives me the Windows Installer switch information and then terminates, how do I get it to run and how would I go about changing the file path?
use with the following switch:
/q[n|b|r|f]
Sets user interface level
n - No UI
b - Basic UI
r - Reduced UI
Check http://msdn.microsoft.com/en-us/library/windows/desktop/aa367988%28v=vs.85%29.aspx for detailed commandline options.
The executing of .msi file should be like .exe file that here is your answer : https://stackoverflow.com/a/12436300/359170
start the application with this code :
Process.Start("yourfile.msi");
and it don't need the full path, it adds current directory to the file name you written there.
But
System.IO.Directory.GetCurrentDirectory();
gets the current executed file directory. And you can get the file path by adding just the name of the file to it like this :
string path = System.IO.Directory.GetCurrentDirectory() + "\\yourfile.msi";

Categories