-1

我有这个 c++ 代码,它应该检测何时在目录中修改了文件并将文件名添加到列表框中。

这是文件监视器部分,它位于启动监视过程的按钮内

private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
    array<String^>^ args = Environment::GetCommandLineArgs();

    FileSystemWatcher^ fsWatcher = gcnew FileSystemWatcher( );
    fsWatcher->Path = "C:\\users\\patchvista2";
    fsWatcher->IncludeSubdirectories = true;
    fsWatcher->NotifyFilter = static_cast<NotifyFilters> 
              (NotifyFilters::FileName | 
               NotifyFilters::Attributes | 
               NotifyFilters::LastAccess | 
               NotifyFilters::LastWrite | 
               NotifyFilters::Security | 
               NotifyFilters::Size );

    Form1^ handler = gcnew Form1(); 
    fsWatcher->Changed += gcnew FileSystemEventHandler(handler, &Form1::OnChanged);
    fsWatcher->Created += gcnew FileSystemEventHandler(handler, &Form1::OnChanged);

    fsWatcher->EnableRaisingEvents = true;
}

然后对于 onchange 部分我有这个代码

void OnChanged (Object^ source, FileSystemEventArgs^ e)
{
    // Here is the problem
    MessageBox::Show(e->FullPath);
    listBox1->Items->Add(e->FullPath);
    // End problem

    System::Security::Cryptography::MD5 ^ md5offile = MD5CryptoServiceProvider::Create();
    array<Byte>^ hashValue;
    FileStream^ fs = File::Open(e->FullPath, IO::FileMode::Open, IO::FileAccess::Read, IO::FileShare::ReadWrite);
    fs->Position = 0;
    hashValue = md5offile->ComputeHash(fs);
    PrintByteArray(hashValue);
    fs->Close();
    Application::DoEvents();
}

它会向我发送文件名消息框,但不会将其添加到列表框中。我尝试让它将文件名显示到标签上,但这也不起作用。一旦启动此代码循环,屏幕似乎不会刷新。我在 vb.net 中有这段代码,它确实将文件名添加到列表框中。有人可以告诉我为什么文件名没有添加到列表框中。

4

1 回答 1

1

两件事情:

  1. 您需要保持 FileSystemWatcher 处于活动状态。它很可能会在你现在拥有它的地方被垃圾收集。(创建一个类字段并将其粘贴在那里。)
  2. 每当您对 UI 组件执行任何操作时,都需要调用UI 线程。

这是 #2 的大致语法(我现在远离编译器,这可能不准确。)

void Form1::AddToListBox(String^ filename)
{
    listBox1->Items->Add(filename);
}

void Form1::OnChanged(Object^ source, FileSystemEventArgs^ e)
{
    Action<String^>^ addDelegate = gcnew Action<String^>(this, &Form1::AddToListBox);
    this->Invoke(addDelegate, e->FullPath);
    ...
}
于 2013-04-02T23:34:23.123 回答