@@ -158,24 +158,21 @@ namespace AppInstaller::CLI::Workflow
158158
159159 std::filesystem::path outputFilePath{ context.Args .GetArg (Execution::Args::Type::OutputFile) };
160160
161- // Check if the file exists and is hidden
162- DWORD attrs = std::filesystem::exists (outputFilePath) ? GetFileAttributesW (outputFilePath.c_str ()) : INVALID_FILE_ATTRIBUTES ;
161+ // GetFileAttributesW returns INVALID_FILE_ATTRIBUTES for non-existent files, so no separate exists() check is needed.
162+ DWORD attrs = GetFileAttributesW (outputFilePath.c_str ());
163163 bool isHidden = (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_HIDDEN));
164164
165- if (isHidden)
166- {
167- // Remove hidden attribute so we can write to it
168- SetFileAttributesW (outputFilePath.c_str (), attrs & ~FILE_ATTRIBUTE_HIDDEN);
169- }
170-
171- std::ofstream outputFileStream{ outputFilePath };
172- outputFileStream << packages;
173-
174- if (isHidden)
175- {
176- // Restore hidden attribute
177- SetFileAttributesW (outputFilePath.c_str (), attrs);
178- }
165+ // Open the file directly without changing its attributes:
166+ // - For an existing hidden file, use TRUNCATE_EXISTING to clear its content while preserving its attributes.
167+ // - Otherwise, use CREATE_ALWAYS to create a new file or overwrite an existing one.
168+ DWORD creationDisposition = isHidden ? TRUNCATE_EXISTING : CREATE_ALWAYS;
169+ wil::unique_hfile fileHandle{ CreateFileW (outputFilePath.c_str (), GENERIC_WRITE, 0 , nullptr , creationDisposition, FILE_ATTRIBUTE_NORMAL, nullptr ) };
170+ THROW_LAST_ERROR_IF (!fileHandle);
171+
172+ Json::StreamWriterBuilder writerBuilder;
173+ std::string jsonContent = Json::writeString (writerBuilder, packages);
174+ DWORD bytesWritten = 0 ;
175+ THROW_LAST_ERROR_IF (!WriteFile (fileHandle.get (), jsonContent.c_str (), static_cast <DWORD>(jsonContent.size ()), &bytesWritten, nullptr ));
179176 }
180177
181178 void ReadImportFile (Execution::Context& context)
0 commit comments