Windows Server调用msg.exe偶发“目录名称无效”异常求助
排查调用msg.exe偶发“目录名称无效”异常的思路
我在Windows Server环境下编写了一个程序,通过调用msg.exe向其他用户发送通知。程序大部分时候能正常运行,但会偶发“目录名称无效”的异常——循环执行时传入完全相同的参数,首次运行正常,第二次却可能失败,异常出现概率大概20%。目前没找到有效解决方案,求排查方向。
string username = "XXX"; string password = "XXX"; string ret = ""; ProcessStartInfo processInfo = new ProcessStartInfo(); processInfo.FileName = "msg"; processInfo.Arguments = ToUser + " /SERVER:" + ToServer + " /time:3600 \"" + Text + "\""; processInfo.UseShellExecute = false; processInfo.Domain = "XXX"; processInfo.UserName = username; processInfo.WindowStyle = ProcessWindowStyle.Minimized; SecureString securePassword = new SecureString(); foreach (char c in password) { securePassword.AppendChar(c); } processInfo.Password = securePassword; try { Process process = new Process(); process.StartInfo = processInfo; process.Start(); process.WaitForExit(); } catch (Exception error) { ret = error.ToString(); MessageBox.Show(error.ToString(), "Benachrichtigungen:"); } return ret;
排查思路
- 指定
msg.exe绝对路径:直接写msg依赖系统PATH,但切换用户身份后环境变量可能变化,导致路径解析失败。改成C:\Windows\System32\msg.exe,避免PATH依赖问题。 - 显式设置工作目录:
ProcessStartInfo默认继承当前程序工作目录,但跨用户启动时该目录可能无访问权限。手动设置processInfo.WorkingDirectory = "C:\Windows\System32",确保工作目录有效。 - 清理进程资源:循环执行时,前一次的
Process对象未释放可能导致资源冲突。在WaitForExit()后添加process.Close(); process.Dispose();,确保每次调用都清理资源。 - 改用
ArgumentList处理参数:手动拼接参数容易因特殊字符(如引号、反斜杠)导致解析错误,间接触发目录异常。用ArgumentList自动处理转义:processInfo.ArgumentList.Add(ToUser); processInfo.ArgumentList.Add($"/SERVER:{ToServer}"); processInfo.ArgumentList.Add("/time:3600"); processInfo.ArgumentList.Add(Text); - 检查用户临时目录权限:指定用户的
%TEMP%目录可能存在权限问题,导致进程启动时无法访问临时文件。显式设置processInfo.EnvironmentVariables["TEMP"]为该用户有权访问的目录,比如C:\Users\{username}\AppData\Local\Temp。 - 避免密集进程调用:短时间内多次启动
msg.exe可能触发系统资源竞争,在循环中添加100ms左右的延迟,或者用异步方式分散进程启动时机。
内容的提问来源于stack exchange,提问作者Larian
相关产品推荐
相关产品推荐

