Win32异常:目录名称无效。

14

我正试图以拥有管理员特权的不同用户身份运行进程,其中两台计算机都运行着Vista,并启用了UAC,但在其中一台计算机上,我遇到了一个Win32Exception错误,该错误提示“目录名无效”。

有人能告诉我我的代码哪里出了问题吗?

var myFile = "D:\\SomeFolder\\MyExecutable.exe";
var workingFolder = "D:\\SomeFolder";
var pInfo = new System.Diagnostics.ProcessStartInfo();
pInfo.FileName = myFile;
pInfo.WorkingDirectory = workingFolder;
pInfo.Arguments = myArgs;
pInfo.LoadUserProfile = true;
pInfo.UseShellExecute = false;
pInfo.UserName = {UserAccount};
pInfo.Password = {SecureStringPassword};
pInfo.Domain = ".";

System.Diagnostics.Process.Start(pInfo);

更新

执行上述代码的应用程序需要管理员权限。

我甚至将工作目录设置为 "Path.GetDirectoryName(myFile)""New System.IO.FileInfo(myFile).DirectoryName"


错误发生在哪一行代码?是在创建FileInfo对象时还是在启动进程时? - Dirk Vollmar
@divo System.Diagnostics.Process.Start(pInfo) @divo System.Diagnostics.Process.Start(pInfo) - mrtaikandi
你可以使用Sysinternals的Process Monitor来确定哪个底层Win32文件/文件夹操作失败了。 - Richard
顺便提一下,你可以使用字符串字面量来避免在路径中转义斜杠。例如:var myFile = @"D:\SomeFolder\MyExecutable.exe"; - Edgar
如果您的SomeFolder路径包含Program Files(x86)文件夹,Visual Studio或其他一些工具会神奇地删除“s”和“(”之间的空格,并将其变为“Program Files(x86)”。也许您错过了这个拼写错误。 - user3079364
6个回答

19
您需要指定ProcessStartInfo类的WorkingDirectory属性。从Win32Exception错误代码267“目录名称无效”中: “我正在开发一个“自动运行”工具,旨在帮助像我一样必须为用户提供以管理员身份执行一个或两个程序的手段且不想放弃管理员密码的管理员。 所以,我正在Vista上开发,并且只是制作了一个小型概念原型,该原型将使用ProcessStartInfo和Process将calc.exe作为其他用户运行。当我像我一样以自己的身份执行它时(我必须承认这是毫无意义的练习),它很好地工作了,但是当我创建一个新用户并尝试让他作为他运行时,我遇到了Win32Exception抱怨目录名称无效,本机错误代码267。我当时感到困惑,因为我不知道哪个提供的目录名称可能无效。然后我在XP机器上测试了代码,而且它可以正常工作! 我开始搜索谷歌,但无济于事,错误的许多报告,但没有确切的解决方案,或处于不同的上下文。最终,在一段时间后,我醒悟过来,我没有指定ProcessStartInfo类的WorkingDirectory属性,只要我添加了以下行

FileInfo fileInfo = new FileInfo(path); startInfo.WorkingDirectory = fileInfo.DirectoryName;

到我的代码中,它就被允许以与登录用户不同的代码运行。...


1
我添加了一个与目录名称相同的字符串,但不起作用。但是在我按照这个答案更改后 FileInfo fileInfo = new FileInfo(path); startInfo.WorkingDirectory = fileInfo.DirectoryName; 就正常工作了。很奇怪。 - Loran

8

这是因为文件路径长度超过了255个字符。


2
谢谢,这对我也起作用了。我把整个路径和文件名都设置在了“filename”属性中,而应该将路径放在“工作目录”属性下,只在“文件名”属性中留下文件名即可。 - Dalbir Singh

4

尝试替换

pInfo.WorkingDirectory = New System.IO.FileInfo(myFile).DirectoryName;

使用(with)
pInfo.WorkingDirectory = Path.GetDirectoryName(myFile);

FileInfo可以访问文件系统,我假设只有管理员用户可以访问该目录。如果它不能解决您的问题,至少会使您的代码稍微快一点...


没有解决问题。我甚至指定了一个静态地址。 - mrtaikandi

3
如果您想知道目录是已登录用户映射的主文件夹还是其下级文件夹,则可以参考这篇知识库文章:

在 Windows 中使用“以其他身份运行”功能启动 Cmd.exe 或 Notepad.exe 时出现“目录名称无效”的错误消息

更新:请注意,成为 Vista 的本地管理员组成员并拥有管理权限并不相同。
我猜当您将 C# 应用程序作为管理员运行时,一切都正常。右键单击可执行文件,然后选择以管理员身份运行,或从提升的命令提示符中启动应用程序(最快的方法是按开始,输入'cmd',然后按Ctrl+Shift+Return)。
或者,作为替代方案,禁用运行该进程的帐户的 UAC。

该目录是非系统驱动器上的普通目录,管理员组拥有完全控制权限。 - mrtaikandi
运行第二进程的应用程序需要管理员权限执行级别。因此它将以管理员身份运行。 - mrtaikandi
1
“...禁用运行该进程的帐户的UAC” - 一旦开始这样做,就几乎不可能回头了。这就像走向黑暗面一样。 - jww

2

这是因为文件夹名称中有空格。一旦我移除了这个空格,当我遇到这个问题时它就开始正常工作了。


即使路径中没有空格,这仍然无法正常工作。 - Shekhar Reddy

2
我有过类似的经历,最终发现是我们的开发环境出了问题。我们使用subst命令将源代码目录映射到虚拟驱动器上。因此,FileName和WorkingDirectory属性被设置为"W:\SomeFolder\FileName.exe"。
当我将FileName和WorkingDirectory硬编码为通过我的实际磁盘(C:)访问文件时,我就不再收到“无效目录”异常了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接