我正在尝试为另一个进程写入的文件创建DuplicateHandle()。我成功了,但我得到了所有者流程的位置。在我寻求开始之后,它也在所有者的过程中寻求。我可以以某种方式寻求而不改变第一个过程的进展吗?
修改
另一个应用程序在没有CreateFile的情况下打开此文件。是不是一种从ReadFile开始读取文件的方法,而不是手动搜索?
再次编辑:
没有办法只从一侧读取重复句柄。谢谢你的帮助。
答案 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;
}