-3

I have a problem with finding the file after my program installation on another computer. I'm using C# and this is a part of my code:

// template path
string tmpPath = @"|DataDirectory|\Templete.docx";

// output path
string outputName = @"|DataDirectory|\Output.pdf";

// shadow file name
string shadowFile = @"|DataDirectory|\temp.docx";

// Create shadow File
File.Copy(tmpPath, shadowFile, true);

// open word
word.Application app = new word.Application();
Document doc = app.Documents.Open(shadowFile);

I use"|DataDirectory|", it worked for finding the database but here I use it again to find my word file and it throws me this error:

System.ArgumentException: 'Illegal characters in path.'

Camilo Terevinto
  • 31,141
  • 6
  • 88
  • 120
  • Also you should not use the program directory to store data. There are per user specific folders for this use. – JAlex Dec 29 '20 at 17:16
  • [Where is |DataDirectory| defined?](https://stackoverflow.com/a/12276625) – 001 Dec 29 '20 at 17:16
  • @JohnnyMopp so what will help me to find the file I want after installation – Arevan Shamal Dec 29 '20 at 17:17
  • @JohnnyMopp i used it in the connection string to find the database, and I thought it will work with this too – Arevan Shamal Dec 29 '20 at 17:18
  • @JAlex what should I use to find the file after installation – Arevan Shamal Dec 29 '20 at 17:19
  • @JohnnyMopp is used it here ''' private const string constr = @"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\HuskyCenter.mdf;Integrated Security=True";''' – Arevan Shamal Dec 29 '20 at 17:20
  • I don't think you want to use `|DataDirectory|` here. Is `Templete.docx` installed with your program? Is it a resource? If it is in the exe's folder see: [How to get application path](https://stackoverflow.com/q/5606747) And, as mentioned in the first comment, you should be copying the file to one of the special folders like appdata or temp. – 001 Dec 29 '20 at 17:25
  • If this is a windows Forms application, using `Application.ExecutablePath` will tell you where the exe is located. @JAlex's comment has merit - don't store user data along with the application, but if this is a template word file that is part of the application then it makes sense to store next to the exe – Caius Jard Dec 29 '20 at 17:26
  • You can make use of this: https://learn.microsoft.com/en-us/dotnet/api/system.environment.specialfolder?view=net-5.0 – insane_developer Dec 29 '20 at 17:34

2 Answers2

0

You need to create a new variable for DataDirectory.

string datadirectory = "c:\pathtodatadirectory";

string tmpPath = datadirectory + @"\Templete.docx";
// output path
string outputName = datadirectory + @"\Output.pdf";
// shadow file name
string shadowFile = datadirectory + @"\temp.docx";

You obviously want your data directory to be dynamic. Fetch the directory path from the OS variable.

See this post. How can I get the current user directory?

manit
  • 604
  • 7
  • 11
  • 2
    I would prefer to use `System.IO.Path.Combine()` in order to take care of any formatting issues with directory separation characters. – JAlex Dec 29 '20 at 17:33
0

I recommend using reflection with Assembly.GetEntryAssembly().Location to get the path of the starting executable. You can use also Path to combine paths and filenames, create temporary files, and do other common path operations. Finally, use Environment.GetFolderPath() to find where My Documents is, or where C:\Users\XXXX\AppData\Local is and all other special named folders.

using static System.IO.Path;
using static System.Environment;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            var path = GetDirectoryName(Assembly.GetEntryAssembly().Location);
            var template = Combine(path, "Template.docx");
            var tempFile = Combine(GetTempPath(), "temp.docx");
            var userFile = Combine(GetFolderPath(SpecialFolder.LocalApplicationData), "UserPreferences.docx");
            var docFile = Combine(GetFolderPath(SpecialFolder.MyDocuments), "MyDocument.docx");
        }
    }
}

And alternative to this, is to store the program path in the registry during installation and then read the registry when the program runs

For example write a value to HKEY_CURRENT_USER\Software\Application1 or whatever the name is, and read it with Microsoft.Win32.Registry.CurrentUser.OpenSubKey("Software\Application1")

JAlex
  • 1,486
  • 8
  • 19
  • 1
    running console apps in task scheduler or sql server agent resulted in a wrong path using Assembly.GetEntryAssembly().Location. I ended up having use this to get the correct executable path: Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase).Replace("file:\\", ""); – manit Dec 30 '20 at 04:25
  • `GetExecutingAssembly()` is the way to go then. The rest is is just file path manipulations. – JAlex Jan 04 '21 at 13:26