简单的C#应用程序无法正常工作,但在Visual Studio中运行时可以正常工作

4

我是C#和VS的新手,遇到了一个奇怪的问题。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace ExampleApplication {
    class Program {
        static void Main(string[] args) {
            FileInfo fi = new FileInfo("C:\\TEST.TXT");
            fi.Create();
            Console.WriteLine("File exists: {0}", fi.Exists);
        }
    }
}

这是我的程序,它创建一个名为TEST.TXT的文件。当我使用VS 2010中的“调试”->“开始调试”命令(F5)运行该程序时,程序可以正常工作并创建文件。
但是,如果我构建解决方案,然后使用cmd提示符从.exe运行程序:
C:\...\Visual Studio 2010\Projects\ExampleApplication\ExampleApplication\bin\Debug\ExampleApplication.exe

它运行并输出: 文件存在: 真。但是文件没有被创建。有人有任何想法吗?
谢谢。

2
可能是权限问题。尝试以管理员权限运行您的exe文件,看看是否可以解决问题。 - dowhilefor
你确定它不存在吗?fi.Create()这行代码明确地创建了文件。 - Chris Laplante
在我的电脑上尝试过(Win7x64 Net4),并且按预期工作!可能是权限问题。您是否尝试手动在根目录中创建一个文件(记事本)? - Steve
你是在哪个版本的Windows上尝试这个操作的?如果是Win7,UAC是否已经打开? - Chibueze Opata
@RickyJones:请看下面我的回答。 - Chibueze Opata
显示剩余4条评论
10个回答

3
也许操作系统最终没有释放文件流,因此文件系统不反映最近的更改?尝试在创建后明确关闭新文件流即可:
FileInfo fi = new FileInfo("C:\\TEST.TXT");
using (var stream = fi.Create());

由于这是一个有点疯狂的想法,所以请告诉我们它是否有效 ;) 我相信问题可能会很简单


@RickyJones:你是否分享了你正在使用的确切源代码?也许你已经删除了一些你认为不重要的小东西?请分享确切的代码,也许你在这里发布时跳过了像Console.ReadLine()或其他类似的东西? - sll

3
我猜测用户账户控制将文件创建重定向到了影子副本目录;在VS下,您作为管理员运行,因此文件创建未被重定向。
请在VirtualStore目录中查找该文件。该目录位于:
C:\Users\YourUserNameHere\AppData\Local\VirtualStore

实际文件夹名称将类似于:
C:\Users\YourUserNameHere\AppData\Local\VirtualStore\C

为了解决这个问题,您可以更改程序,以便将文件写入用于用户数据的位置;一个明显的选择是文档文件夹。您还可以使用管理员权限运行应用程序。至少有三种方法可以做到这一点:
  • 右键单击可执行文件,选择“以管理员身份运行”
  • 在检查快捷方式属性对话框中的“以管理员身份运行”复选框后,使用快捷方式运行可执行文件
  • 使用上述任一方法打开“管理员”命令提示符会话;然后通过在命令提示符中输入其名称来正常运行应用程序。

2

可能是权限问题。如果运行vS的用户帐户与运行命令提示符的用户帐户不同,则它们可能对创建文件具有不同的权限。请查看您的Windows事件查看器,以查看是否报告了错误。然后,像Marc建议的那样使用try-catch。


1

只是一个小技巧。当你处理文件时,总是要使用 try catch。你永远不知道会发生什么,就像你的情况一样。

你以管理员身份运行 cmd 吗?也许你没有创建文件的权限。

还要添加 try catch 并在控制台返回错误。如果以管理员身份运行不起作用,这会帮助你找出问题所在。

        try
        {            
            your code..
        }

        catch (Exception e)
        {
            Console.WriteLine("{0} Exception caught.", e);
        }

谢谢,但没有抛出任何异常。 - Ricky Jones
你以管理员身份运行了cmd吗? - Marc

1
尝试按照以下方式关闭文件:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace ExampleApplication {
    class Program {
        static void Main(string[] args) {
            FileInfo fi = new FileInfo("C:\\TEST.TXT");
            fi.Create();
            fi.Close();
            Console.WriteLine("File exists: {0}", fi.Exists);
        }
    }
}

FileInfo没有提供Close方法,也许您的意思是FileStream.Close() - sll

1

你这样做是错误的。在完成操作后,你必须释放文件对象。要在.NET中创建一个空文件,我建议你这样做:

using (File.Create("C:\\TEST.TXT"));

或者像这样:

File.Create("C:\\TEST.TXT").Dispose();

或者你可以直接修改你的fi.Create()为:

fi.Create().Dispose();

很可能Visual Studio调试器会自动为您清理垃圾,当您停止调试时,它会正确地处理所有对象的释放。


此外,在尝试此代码之前,我建议您重新启动计算机,以确保Windows不会再次尝试使用相同的内存空间。 - Chibueze Opata

1
use the following code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace ExampleApplication {
    class Program {
        static void Main(string[] args) {
         if(!File.Exists("C:\\TEST.TXT"))
         {
             GC.Collect();
             GC.WaitForPendingFinalizers();
             fi.Create();
             fi.Close();
             Console.WriteLine("File exists: {0}", fi.Exists);
        }
      }
    }
}

1

我不知道这个问题的原因,但你为什么不试试这个:

if(!File.Exists("C:\\TEST.TXT"))
{
   File.Create("C:\\TEST.TXT");
   Console.WriteLine("File exists");
}

有趣的 ;) 当文件实际存在时,它会打印“文件不存在”;) - sll
它创建了一个文件但是写着“文件不存在”? - GaaRa
刚刚读了你的 else 代码块,它会在 File.Exists("C:\\TEST.TXT") == true 的情况下运行。 - sll

1

你需要调用 fi.Refresh() 函数来重新检查基对象,否则它将始终返回 false。


1

这是一个简单的解决方案,

我运行了你的代码并得到了一个UnauthorizedAccessException异常,这是一个安全异常,你没有正确的安全权限来保存文件在根目录(C:\)

如果你将它改为FileInfo("TEXT.TXT");而不是C:\TEXT.TXT,它就会工作

顺便说一下,你不能使用using语句,因为FileInfo没有实现IDisposable接口。


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