简体   繁体   中英

Process.Start fails and claims "The directory name is invalid."

We have a .NET application starting Microsoft Word explicitly with System.Diagnostics.Process.Start, eg "C:\\PROGRA~2\\MICROS~1\\Office14\\WINWORD.EXE" - the value is retrieved from the registry beforehand (see GetWordExePathFromWindowsRegistry method in the code below). Since we moved from .NET Framework 4.x to .NET Core 3.1, a runtime error in the Process.Start line is thrown: Win32Exception: "The directory name is invalid." (in our case the German message "Der Verzeichnisname ist ungültig.") We log the error, and when we open the logged directory in the file explorer, everything is fine; so as far as we can see the error message is not correct. This error occurs not always, but often. Sometimes, it helped restarting the application, sometimes restarting the computer. Sometimes nothing helps. Some users get the error more often than others. Users on another site don't have the problem at all. Yet we have no idea what the cause could be.

Please note that this has been productive code for several years without an issue, and we get the error reports since we moved from .NET Framework to .NET Core 3.1 without this code being changed.

Here is the code of how we get the path to winword.exe:

public static string GetWordExePathFromWindowsRegistry()
{
    Regex exePathRegex = new Regex(
        @".*\\winword.exe",
        RegexOptions.IgnoreCase);
    foreach ( string wowNodeName in new[] { "", @"Wow6432Node\" })
    {
        foreach (string theKeyFormat in
            new[]
            {
            @"SOFTWARE\{0}Microsoft\Windows\CurrentVersion\App Paths\Winword.exe",
            @"SOFTWARE\{0}Classes\WordDocument\protocol\StdFileEditing\server",
            @"SOFTWARE\{0}Classes\Word.Document.14\protocol\StdFileEditing\server"
            })
        {
            RegistryKey rootNode = Registry.LocalMachine;
            string keyPath = string.Format(theKeyFormat, wowNodeName);

            // Get default registry Value:
            using RegistryKey key = rootNode.OpenSubKey(keyPath);
            string fullWordPath = key?.GetValue("")?.ToString();

            if (!string.IsNullOrEmpty(fullWordPath))
                if (exePathRegex.IsMatch(fullWordPath))
                    return fullWordPath;
        }
    }
    throw new Exception("Path to Word not found"); ;
}

And then we start Word with something like that (in our case hidden==true because a VSTO add-in in Word does the real stuff):

public void StartMsOfficeAppExe(
    string msOfficeAppExePath,
    string startArguments,
    bool hidden)
{
    ProcessStartInfo startInfo = new ProcessStartInfo(
        msOfficeAppExePath,
        startArguments)
    {
        UseShellExecute = false // without this Hidden would not be allowed
    };
    if (hidden)
        startInfo.WindowStyle = ProcessWindowStyle.Hidden;
    Process.Start(startInfo);
}

It turned out that the following change helps: Instead of starting the process with providing the full path to the EXE file, we now first change the current directory to that of the EXE, then start the EXE in the current directory, and finally we change back to the directory we were in before.

It is weird, but it helps.

Did you try using the Verbatim character (@) for the string? Could be that it is not escaping the backslashes.

Escaping them manually also works (replacing \\ => \\\\ they will turn kind of yellow).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM