提问人:Gary 提问时间:11/14/2023 更新时间:11/14/2023 访问量:26
如何在不覆盖的情况下将多个进程追加到 Windows 终端服务器客户端文件?
How can multiple processes append to a Windows Terminal Server Client file without overwriting?
问:
我想在多个进程中运行一个程序,并让该程序将记录追加到同一个文件中。追加在非 Windows Server 上运行到本地文件时有效。当程序在 Windows Server 上运行并使用终端服务器客户端语法写入共享客户端驱动器上的文件时,它不起作用。例如,\tsclient\c\temp\myfile-append.txt。如果我调用 CreateFile() 并将 dwDesiredAccess 设置为 GENERIC_WRITE,则进程 1 中的所有数据都会被进程 2 覆盖,而不是追加到。如果我将 GENERIC_WRITE 替换为 FILE_APPEND_DATA,则会创建文件,但在调用 WriteFile() 时会ERROR_INVALID_PARAMETER。
当我在 Windows Server 上运行时,我看到 WriteFile() 错误,FILE_APPEND_DATA:
process 1:
Running on a Windows Server and Terminal Services are enabled
CreateFile: \\tsclient\c\temp\myfile-write.txt
WriteFile: TEST-6620
WriteFile: TEST-6620
WriteFile: TEST-6620
WriteFile: TEST-6620
**CreateFile: \\tsclient\c\temp\myfile-append.txt
WriteFile: TEST-6620
WriteFile returned ERROR_INVALID_PARAMETER errno:87**
Press return to exit...
process 2:
Running on a Windows Server and Terminal Services are enabled
CreateFile: \\tsclient\c\temp\myfile-write.txt
WriteFile: TEST-9020
WriteFile: TEST-9020
WriteFile: TEST-9020
WriteFile: TEST-9020
**CreateFile: \\tsclient\c\temp\myfile-append.txt
WriteFile: TEST-9020
WriteFile returned ERROR_INVALID_PARAMETER errno:87**
Press return to exit...
myfile-append 已创建,但由于错误而为空。 myfile-write 具有从进程 2 写入的预期最后 4 条记录:
TEST-4424
TEST-4424
TEST-4424
TEST-4424
当我在非 Windows Server 上运行时,没有错误:
process 1
Terminal Services are not enabled so using local files
CreateFile: myfile-write.txt
WriteFile: TEST-8320
WriteFile: TEST-8320
WriteFile: TEST-8320
WriteFile: TEST-8320
CreateFile: myfile-append.txt
WriteFile: TEST-8320
WriteFile: TEST-8320
WriteFile: TEST-8320
WriteFile: TEST-8320
Press return to exit...
process 2
Terminal Services are not enabled so using local files
CreateFile: myfile-write.txt
WriteFile: TEST-11992
WriteFile: TEST-11992
WriteFile: TEST-11992
WriteFile: TEST-11992
CreateFile: myfile-append.txt
WriteFile: TEST-11992
WriteFile: TEST-11992
WriteFile: TEST-11992
WriteFile: TEST-11992
Press return to exit...
myfile-append 正确有 8 条记录,每个进程 4 条:
TEST-24820
TEST-16324
TEST-24820
TEST-16324
TEST-24820
TEST-16324
TEST-24820
TEST-16324
myfile-write 具有从进程 2 写入的预期最后 4 条记录:
TEST-16324
TEST-16324
TEST-16324
TEST-16324
有谁知道我如何让这个程序在多个进程中运行,并让该程序在同一个文件中追加记录,当程序在 Windows Server 上运行时,使用终端服务器客户端语法写入共享客户端驱动器上的文件?
用于在多个进程中运行 ConsoleApplication1.cpp 的 Windows 批处理脚本
@echo off
del \\tsclient\c\temp\myfile-append.txt
del \\tsclient\c\temp\myfile-write.txt
echo Starting process 1
START "process 1" ConsoleApplication1.exe
timeout /t 1
echo Starting process 2
START "process 2" ConsoleApplication1.exe
echo Press return after both processes have finished...
timeout /t -1
echo myfile-append file, should have 8 records, 4 from each process:
type \\tsclient\c\temp\myfile-append.txt
echo myfile-write file, should have last 4 records written from process 2:
type \\tsclient\c\temp\myfile-write.txt
控制台应用程序1.cpp
#define COUNT 4
#define SLEEP 2000
#include <Windows.h>
#include <iostream>
#include <stdlib.h>
#include <fileapi.h>
#include <errhandlingapi.h>
wchar_t filename_local_write[512] = L"myfile-write.txt";
wchar_t filename_local_append[512] = L"myfile-append.txt";
wchar_t filename_ts_write[512] = L"\\\\tsclient\\c\\temp\\myfile-write.txt";
wchar_t filename_ts_append[512] = L"\\\\tsclient\\c\\temp\\myfile-append.txt";
wchar_t* filename_write;
wchar_t* filename_append;
void* myExit(int exitVal);
int main()
{
int ii;
char buf[512];
DWORD rval;
SECURITY_ATTRIBUTES sa;
HANDLE hFile = 0;
DWORD pid;
// See if Terminal Services are enabled
OSVERSIONINFOEX osVersionInfo;
ULONGLONG dwlConditionMask = VerSetConditionMask(0, VER_SUITENAME, VER_AND);
ZeroMemory(&osVersionInfo, sizeof(osVersionInfo));
osVersionInfo.dwOSVersionInfoSize = sizeof(osVersionInfo);
osVersionInfo.wSuiteMask = VER_SUITE_TERMINAL;
int tsEnabled = VerifyVersionInfo((POSVERSIONINFOEX)&osVersionInfo, VER_SUITENAME, dwlConditionMask);
if (tsEnabled) {
printf("Running on a Windows Server and Terminal Services are enabled\n");
filename_write = filename_ts_write;
filename_append = filename_ts_append;
} else {
printf("Terminal Services are not enabled so using local files\n");
filename_write = filename_local_write;
filename_append = filename_local_append;
}
// Use process id as part of the records written so we
// know what process the records were written from.
pid = GetCurrentProcessId();
// Create a file using GENERIC_WRITE
memset(&sa, 0, sizeof(sa));
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = FALSE;
printf("CreateFile: %ws\n", filename_write);
hFile = CreateFileW(
filename_write, // lpFileName
GENERIC_READ | GENERIC_WRITE, // dwDesiredAccess
FILE_SHARE_READ | FILE_SHARE_WRITE, // dwShareMode
&sa, // lpSecurityAttributes
OPEN_ALWAYS, // dwCreationDisposition
FILE_ATTRIBUTE_NORMAL, // dwFlagsAndAttributes
NULL); // hTemplateFile
if (hFile == INVALID_HANDLE_VALUE) {
printf("CreateFile returned INVALID_HANDLE_VALUE errno:%d\n", GetLastError());
myExit(1);
}
// write COUNT records to the file that was created using GENERIC_WRITE
rval = 0;
for (ii = 0; ii < COUNT; ii++) {
sprintf_s(buf, "TEST-%d\n", pid);
printf("WriteFile: %s", buf);
if (!WriteFile(hFile, buf, strlen(buf), &rval, NULL)) {
errno = GetLastError();
if (errno == ERROR_INVALID_PARAMETER) {
printf("WriteFile returned ERROR_INVALID_PARAMETER errno:%d\n", errno);
} else {
printf("WriteFile ERROR: returned errno:%d\n", errno);
}
myExit(1);
}
Sleep(SLEEP);
}
// close the file
CloseHandle(hFile);
// Create a file using FILE_APPEND_DATA
memset(&sa, 0, sizeof(sa));
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = FALSE;
printf("CreateFile: %ws\n", filename_append);
hFile = CreateFileW(
filename_append, // lpFileName
GENERIC_READ | FILE_APPEND_DATA, // dwDesiredAccess
FILE_SHARE_READ | FILE_SHARE_WRITE, // dwShareMode
&sa, // lpSecurityAttributes
OPEN_ALWAYS, // dwCreationDisposition
FILE_ATTRIBUTE_NORMAL, // dwFlagsAndAttributes
NULL); // hTemplateFile
if (hFile == INVALID_HANDLE_VALUE) {
printf("CreateFile returned INVALID_HANDLE_VALUE errno:%d\n", GetLastError());
myExit(1);
}
// write COUNT records to the file that was created using FILE_APPEND_DATA
rval = 0;
for (ii = 0; ii < COUNT; ii++) {
sprintf_s(buf, "TEST-%d\n", pid);
printf("WriteFile: %s", buf);
if (!WriteFile(hFile, buf, strlen(buf), &rval, NULL)) {
errno = GetLastError();
if (errno == ERROR_INVALID_PARAMETER) {
printf("WriteFile returned ERROR_INVALID_PARAMETER errno:%d\n", errno);
}
else {
printf("WriteFile ERROR: returned errno:%d\n", errno);
}
myExit(1);
}
Sleep(SLEEP);
}
// close the file
CloseHandle(hFile);
myExit(0);
} // main
void *myExit(int exitVal)
{
printf("Press return to exit...\n");
int rval = getchar();
exit(exitVal);
} // myExit
答: 暂无答案
评论
FILE_APPEND_DATA | FILE_GENERIC_READ
SetFilePointer(hAppend, 0, NULL, FILE_END)
open()
write()
close()