DuplicateHandle用于文件

时间:2011-07-14 19:36:51

标签: windows winapi

我正在尝试为另一个进程写入的文件创建DuplicateHandle()。我成功了,但我得到了所有者流程的位置。在我寻求开始之后,它也在所有者的过程中寻求。我可以以某种方式寻求而不改变第一个过程的进展吗?

修改

另一个应用程序在没有CreateFile的情况下打开此文件。是不是一种从ReadFile开始读取文件的方法,而不是手动搜索?

再次编辑:

没有办法只从一侧读取重复句柄。谢谢你的帮助。

2 个答案:

答案 0 :(得分:3)

来自MSDN

重复句柄指的是与原始句柄相同的对象。因此,对象的任何更改都通过两个句柄反映出来。例如,如果复制文件句柄,则两个句柄的当前文件位置始终相同。要使文件句柄具有不同的文件位置,请使用CreateFile函数创建共享对同一文件的访问权限的文件句柄。

答案 1 :(得分:2)

而不是DuplicateHandle,您必须在两个进程中调用CreateFile,并使用正确的访问模式和共享标志组合。 MSDN有full set of rules,这是一个有效的组合:

作家程序:

 HANDLE file = CreateFile(..., GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, ...);

读者流程:

 HANDLE file = CreateFile(..., GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, ...);

如果你需要玩旗帜,这里是我写的(粗)测试应用程序来回答你的问题:

 // 2process1file.cpp : Defines the entry point for the console application.
 //

 #include "stdafx.h"
 #include <Windows.h>
 #include <stdio.h>
 #include <tchar.h>

 #define NUMBER_OF_LINES 100
 #define IO_PERIOD 250
 static const char message[] = "The quick brown fox jumps over the lazy dog.\n";

 HANDLE file = INVALID_HANDLE_VALUE;

 BOOL CtrlHandler(DWORD ctltype)
 {
     if(file != INVALID_HANDLE_VALUE) 
     {
         CloseHandle(file);
         file = INVALID_HANDLE_VALUE;
     }

     return FALSE;
 }

 int _tmain(int argc, _TCHAR* argv[])
 {
     if(argc == 3) 
     {
         DWORD access = GENERIC_READ;
         DWORD share = FILE_SHARE_READ;
         bool is_writer = false;

         if((*argv[1]|' ') == 'w')
         {
             access |= GENERIC_WRITE;
             is_writer = true;
         }
         else
         {
             share |= FILE_SHARE_WRITE;
         }

         file = CreateFile(argv[2], access, share, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);

         if(file != INVALID_HANDLE_VALUE)
         {
             DWORD nbytes = 1;

             SetFilePointer(file, 0, 0, FILE_BEGIN); //Redundant when writing

             for(int i=0; (i<NUMBER_OF_LINES) && nbytes; ++i) {
                 if(is_writer) {
                     if(WriteFile(file, message, sizeof(message)-1, &nbytes, 0) == 0)
                     {
                         //Write failed somehow
                         break;
                     }

                     //Sleep(INFINITE);

                     if(i%25 == 0) printf("%d\n", i); 
                 } else {
                     char buffer[sizeof message] = "";

                     if(ReadFile(file, buffer, sizeof(buffer)-1, &nbytes, 0) && nbytes) {
                         buffer[sizeof(buffer)-1] = 0;
                         printf(buffer);
                     } else {
                         //Read failed somehow
                         break;
                     }
                 }

                 Sleep(IO_PERIOD);
             }

             CloseHandle(file);
             file = INVALID_HANDLE_VALUE;
         }
     }
     else
     {
         wprintf(L"Usage : %s [w|r] filename\n");
     }

     return 0;
 }