Im trying to make a winapp that fills the document template file using the C# form and create a new .docx file. Where should i put the .docx file and how should i use it. I placed my template inside the Debug folder and load it like:
dox.LoadFromFile("template.docx");
Im having a problem when using the executable because it doesnt seem to find the template.docx
It is possibly to have files copies into the Output Directory. This is a simple mater of setting the File up accordingly.
However, having data like this in the Programm directory is frowned upon. As of Windows XP, you are unlikely to get write access to those files anymore. So any form of changes would be blocked unless your programm runs with full Administrative Rights.
The intended place for such files are the SpecialFolders. On those you are guaranteed write rights to some degree. While you could still store the template in the programm directory to copy it there if needed, it might be better to use copy it to default user as part of hte setup process.
Of course Visual Studio loves to run code under rather odd user accounts. So I am not sure how far that works for testing.
You can store you word document directly in your assembly (juste copy past the file in your project).
Then you just copy it to windows temp folder before doing your own business. Just don't forget to delete the file in the temp folder when you are good because windows won't do it for you.
Dim fileLocation As String = Path.GetTempFileName()
Using newFile As Stream = New FileStream(fileLocation, FileMode.Create)
Assembly.GetExecutingAssembly().GetManifestResourceStream("YourAssemblyName.yourfile.docx").CopyTo(newFile)
End Using
...
System.IO.File.Delete(fileLocation)
Related
I have a .txt file that I need to read in my program. For the moment I have the directory hardcoded as such:
file = new StreamReader(#"C:\Users\<username>\Documents\File.txt");
However that will (obviously) not work on any other PC that does not have that access to altering the code, or (by some strange happenstance) the same directory as the original code.
How can I get the full file path to set it in my program using C#?
You could create the file in their Application Data directory (they could still find it if they wanted to, but at least it wouldn't be as obvious as the My Documents folder).
When you want to access it, use the Environment class. There are methods for locating special folders for the current user, without resorting to hard-coded paths:
var filePath = Path.Combine(Environment.GetFolderPath(
Environment.SpecialFolder.ApplicationData), "File.txt");
Option 1:
Application.StartupPath can be used for the purpose.
It gets the path for the executable file that started the application, not including the executable name.
Keep File.txt with your executable.
Option 2:
Use Environment.SpecialFolder.ApplicationData
It gives directory that serves as a common repository for application-specific data for the current roaming user.
NOTE: If you want to restrict the user to look into the contents of File.txt then you might need to encrypt the contents.
I have a C# app which reads from and writes to an Access database. There is one database file per user. My intention is to check for the existence of the MDB in the user's My Documents folder at launch, and if the MDB isn't found, then copy the template MDB to that folder.
I have already added the template MDB to my project and placed it in its own folder which I have called Packaged. However, I am unable to refer to this Packaged folder from code as it doesn't appear in IntelliSense.
My intention had been to use File.Copy to copy the MDB over, but I cannot determine the file path as I can't access the MDB in code. And presumably it wouldn't have a file path anyway if it's just packaged in the .exe?
What would be the best way to achieve this, given that I would rather not distribute a separate MDB if possible?
I've done this in the past by making the MDB an embedded resource, and writing it to disk as needed (if it doesn't exist).
Here is more info on writing an embedded resource to file.
You'd almost have to use one of the Environmental paths for the template MDB. Like ApplicationData or Documents and Settings\Username\Local Settings\ or one of the other ones. Local User Data is the best way for user specific data. IN the code in the beginning, determine to see if the file exists in the first run. If it exists copy the template, if not don't.
That way the user has full read and write access and the ability to copy the file or duplicate the file without security problems. These environmental variables are accessible through
Environment.GetEnvironmentVariable
You could also have a registry setting and read and write to the registry for that specific application, that has a simple DatabaseAvailable key, and toggle it yes or no.
You could also embed the MDB as a resource too, and then write it as necessary.
I'm working on a simple progam, and part of it populates a list from a txt file.
this probably is not a smart question but, I didn't find any info on this.
I was wondering where is the best place to put text files in the application directory.
O know about the Resouces but, I wasn't able to get the path of the file I stored there.
so 2 questions:
where is the best place to put a txt file? (or any other importent file to use in the application)
if I put files in the Resources how do I get its path ?
(sorry fo my English)
If these are files that you do not need to expose to the users and only serve an internal purpose, then you can embed them in your assembly as resources, and extract them when you need them.
To do this, create a new directory in your application. Let's call it 'Resources'. Then, add text files to it. Use the properties window of each text file to change the BuildAction setting to "Embedded Resource". Then, in your code once you need the contents of the file you can use code like this to extract it:
using System.Reflection;
// ...
using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("MyApplication.Resources.MyFile.txt")) {
using (StreamReader reader = new StreamReader(stream)) {
string contents = reader.ReadToEnd();
// Do stuff with the text here
}
}
If you don't want to do this, the correct location to place files is in a directory you create under the AppData directory. This is a known system path, which you can obtain like this:
string folderLocation = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
string myPath = Path.Combine(folderLocation, "MyAppName");
You can then use a StreamReader or other class in System.IO to find/enumerate and read the files.
When an application has associated/companion data files it sometimes makes sense to embed them as a Resource, because then there is less chance for them to be tampered with e.g. deleted, or the data modified.
And other times it makes sense to keep the file loose....so you have to decide the best place to store them....you can locate these in the place where the application is installed, or in the Application Data/AppData directory.
For embedding files in Resources have a look at this link:
http://support.microsoft.com/kb/319292
It has a step-by-step guide showing how to embed a file (e.g. a Text file into Resources), and then using a StreamReader to access it and read its contents.
To store the files and access them from a suitably located directory you can use:
System.Environment.SpecialFolder.ApplicationData
with
Environment.GetFolderPath()
to find out where the AppData directory is.
Then when you create your application Setup/Installer, you should get it to create a directory for your application underneath AppData, and then you can decide what files you want to be installed into that location.
See:
Saving a file to Application Data in c#
Note, ApplicationData "roams"...i.e. when you logon to a different machine, the files are transferred onto that machine as part of your profile....you may not want this....so you could instead use:
System.Environment.SpecialFolder.CommonApplicationData
I am using WritePrivateProfileString in c# (through DllImport) to store paths taken from textboxes on the interface. And the .ini file name is hardcoded in my application
string ini_file = ".\\config.ini";
However, when the file writing happens, the configuration file is written to the first path taken from the interface instead of writing it to the exe directory. Which is quite odd.
Debugging shows that the values are sent correctly to the WritePrivateProfileString but it still is written to the wrong location. Anyone knows why is that happenening?
I'd guess that something is changing the working directory of your process, most likely your code in the process. Note that the documentation has this to say:
If the lpFileName parameter does not contain a full path and file name for the file, WritePrivateProfileString searches the Windows directory for the file. If the file does not exist, this function creates the file in the Windows directory.
Now my guess is that this applies if you supply just a file name. Because your file name starts with . I believe that will force the function to start from the current working directory.
Having said all of that, and no matter what the cause of the problem is, you should use a fully-qualified path in order to make sure the file is written where you want it to be written. Whenever you want the file to go in a specific directory, it's always easiest to force that by using fully-qualified paths.
You can find the path to your executable using Application.ExecutablePath and then remove the file name part.
Another point to make is that the same directory as the executable may be a bad choice. If your program is installed under the Program Files directory then the directory which contains the executable will not be generally writeable. I think you should consider using a directory under in the user profile. Look for one of the Environment.SpecialFolder values.
Further to David Heffernan's answer - you can use
Path.GetDirectoryName(Application.ExecutablePath);
to safely get just the running application's folder part.
If you're in a dll rather than an executable, you can use
Path.GetDirectoryName(Assembly.GetAssembly(typeof(MyClass)).CodeBase);
Both require System.IO, and were originally posted here. Second example also requires System.Reflection).
Application data files are supposed to be written to the LocalApplicationData special folder.
string path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData);
You typically will not have permissions to write into the Program Files folder etc.
say my application is installed in C:\programfiles\xyz\ I've some setting & other data files (*.dat files) in this directory too.
My application uses OpenFileDialog to open an image. Problem is that when ever user browses to some directory (say MyPictures) for an image. The current working directory of the application becomes that directory (MyPictures in this case).
After user inputs the image. I do some processing over it and save some values to imagedata.dat which will be located in the path where original application is installed.(C:\programfiles\xyz here )
In my code I'm just using FileStream("imagedata.dat",...,...) without any path prefix before the filename. Problem here is that application is crashing because it is searching for imagedata.dat in 'MyPictures\imagedata.dat'.
How can I avoid this?
You should be using absolute path names when saving data to files. The current working directory is controlled by the user, not by you (for example, if they launch your process from a shortcut then the working directory could've been changed before your process even starts up).
Also, you should never save anything under C:\Program Files during normal use. Doing this means your program needs to be running as an administrator, and unless you're doing administrator-y things then you should be able to run it as a regular user.
The correct thing to do in your case is to use the Environment.GetFolderPath() function to get the location of the ApplicationData folder and save your data under there. Just choose a sub-directory based on your application's name.
You could save it to GetCurrentDirectory then restore with SetCurrentDirectory. However, I agree wih codeka that using the appropriate GetFolderPath (probably ApplicationData, CommonApplicationData or LocalApplicationData) is a better solution.