I need to get (not download) the content from 10.000~ manifest files within a project in Azure DevOps, but I don't manage to achieve this. I have found several ways to retrieve the content from one file at a time, but in this context, it is neither an efficient nor sustainable solution. I have managed to retrieve all files of a particular file type by checking if the file path ends with the name of the file, then using the TfvcHttpClientBase.GetItemsBatch method. However, this method does not return the item's content.
Program.cs
using Microsoft.TeamFoundation.SourceControl.WebApi;
AzureRest azureRest = new AzureRest();
var tfvcItems = azureRest.GetTfvcItems();
List<TfvcItemDescriptor> itemDescriptorsList = new List<TfvcItemDescriptor>();
foreach(var item in tfvcItems)
{
//Example manifest file .NET
if (item.Path.EndsWith("packages.config"))
{
var itemDescriptor = new TfvcItemDescriptor()
{
Path = item.Path,
RecursionLevel = VersionControlRecursionType.None,
Version = "",
VersionOption = TfvcVersionOption.None,
VersionType = TfvcVersionType.Latest
};
itemDescriptorsList.Add(itemDescriptor);
}
}
TfvcItemDescriptor[] itemDescriptorsArray = itemDescriptorsList.ToArray();
var itemBatch = azureRest.GetTfvcItemsBatch(itemDescriptorsArray);
foreach(var itemList in itemBatch)
{
foreach(var itemListList in itemList)
{
Console.WriteLine("Content: " + itemListList.Content); //empty/null
Console.WriteLine("ContentMetadata: " + itemListList.ContentMetadata); //not empty/null
}
}
AzureRest.cs
using Microsoft.TeamFoundation.SourceControl.WebApi;
using Microsoft.VisualStudio.Services.Common;
using Microsoft.VisualStudio.Services.WebApi;
public class AzureRest
{
const string ORG_URL = "https://org/url/url";
const string PROJECT = "Project";
const string PAT = "PersonalAccessToken";
private string GetTokenConfig()
{
return PAT;
}
private string GetProjectNameConfig()
{
return PROJECT;
}
private VssConnection Authenticate()
{
string token = GetTokenConfig();
string projectName = GetProjectNameConfig();
var credentials = new VssBasicCredential(string.Empty, token);
var connection = new VssConnection(new Uri(ORG_URL), credentials);
return connection;
}
public List<TfvcItem> GetTfvcItems()
{
var connection = Authenticate();
using (TfvcHttpClient tfvcClient = connection.GetClient<TfvcHttpClient>())
{
var tfvcItems = tfvcClient.GetItemsAsync(scopePath: "/Path", recursionLevel: VersionControlRecursionType.Full, true).Result;
return tfvcItems;
}
}
public List<List<TfvcItem>> GetTfvcItemsBatch(TfvcItemDescriptor[] itemDescriptors)
{
TfvcItemRequestData requestData = new TfvcItemRequestData()
{
IncludeContentMetadata = true,
IncludeLinks = true,
ItemDescriptors = itemDescriptors
};
var connection = Authenticate();
using (TfvcHttpClient tfvcClient = connection.GetClient<TfvcHttpClient>())
{
var tfvcItems = tfvcClient.GetItemsBatchAsync(requestData).Result;
return tfvcItems;
}
}
}
}
For reference:
I have tested the codes you shared and when debugging at "itemDescriptorsList" and have found that there is no content specified in it, so that's why you cannot get the txt content.
You should first check and add the content property into the "itemDescriptorsList".
I am creating an app that will move files from my C drive, or anywhere else, to a specified sharepoint library. I am able to copy the file to a sharepoint Library but I want it to "move" instead of just "copy" i have read documentation but can't find a good link to showcase what I am doing.
Here is the code in my console app that I am trying to accomplish this task
namespace FMB_Reports_Console
{
class Program
{
static void Main(string[] args)
{
using (var db = new FMBDBSTAGEEntities())
{
var dataIterator = db.FMB_Reports_Action.Where(x => x.Active);
foreach (var item in dataIterator)
{
if (item.Active)
{
string filePath = #"C:\Users\fmb03113.FMB\Documents\testing";
string libraryName = item.DropOffPath;
string siteUrl = "https://reports.fmb.com/";
string fileName = filePath.Substring(filePath.LastIndexOf("\\") + 1);
MovingFiles(filePath, libraryName, siteUrl, fileName);
}
}
}
}
public static void MovingFiles(string filePath, string libraryName, string siteUrl, string fileName)
{
using (ClientContext ctx = new ClientContext(siteUrl))
{
FileCreationInformation fcInfo = new FileCreationInformation();
fcInfo.Url = fileName;
fcInfo.Overwrite = true;
fcInfo.Content = System.IO.File.ReadAllBytes(filePath);
//fcInfo.Content = System.IO.File.ReadAllBytes(filePath);
Web myWeb = ctx.Web;
List myLibrary = myWeb.Lists.GetByTitle(libraryName);
var fileToMOve = myLibrary.RootFolder.Files.Add(fcInfo);
//fileToMOve.MoveTo(libraryName, movce);
//myLibrary.RootFolder.MoveTo(libraryName);
ctx.ExecuteQuery();
}
}
}
}
I am trying to delete message in SQS queue, but it is not deleting in the queue. I have been trying to make a lot of changes, but is still not working. I am new to c#, .net core, and AWS. Can anyone please help me with this?
Here is my main method:
[HttpGet]
public async Task<ReceiveMessageResponse> Get()
{
ReceiveMessageRequest receiveMessageRequest = new ReceiveMessageRequest
{
WaitTimeSeconds = 3 //it'll ping the queue for 3 seconds if I don't do this, sometimes I receive message and sometimes I don't
};
receiveMessageRequest.QueueUrl = myQueueUrl;
receiveMessageRequest.MaxNumberOfMessages = 10; // can change number of messages as needed
//receiveing messages/responses
var receiveMessageResponse = await amazonSQSClient.ReceiveMessageAsync(receiveMessageRequest);
if (receiveMessageResponse.Messages.Count > 0){
var bucketName = getBucketName(receiveMessageResponse);
var objectKey = getObjectKey(receiveMessageResponse);
var versionId = getVersionId(receiveMessageResponse);
string filePath = "C:\\InputPdfFile\\"; // change it later
string path = filePath + objectKey;
//get the file from s3 bucket and download it in in
var downloadInputFile = await DownloadAsync(path, versionId, objectKey);
//Get score from the output file
string jsonOutputFileName = "\\file-1.txt"; //change it later from text file to json file
string jsonOutputPath = "C:\\OutputJsonFile"; //change it later
string jasonArchivePath = "C:\\ArchiveJsonFile"; //change it later
int score = GetOutputScore(jsonOutputPath, jsonOutputFileName);
//update metadata from the score received from ML worker (GetOutputScore)
PutObjectResponse putObjectResponse = await UpdateMetadataAsync(score);
//Move file from output to archive after updating metadata
string sourceFile = jsonOutputPath + jsonOutputFileName;
string destFile = jasonArchivePath + jsonOutputFileName;
if (!Directory.Exists(jasonArchivePath))
{
Directory.CreateDirectory(jasonArchivePath);
}
System.IO.File.Move(sourceFile, destFile);
//delete message after moving file from archive
*DeleteMessage(receiveMessageResponse);* //not sure why it is not deleting**
}
return receiveMessageResponse;
}
Here is my Delete method:
public async void DeleteMessage(ReceiveMessageResponse receiveMessageResponse)
{
if (receiveMessageResponse.Messages.Count > 0)
{
foreach (var message in receiveMessageResponse.Messages)
{
var delRequest = new DeleteMessageRequest
{
QueueUrl = myQueueUrl,
ReceiptHandle = message.ReceiptHandle
};
var deleteMessage = await amazonSQSClient.DeleteMessageAsync(delRequest);
}
}
else // It is not going in else because the message was found but still not deleting it
{
Console.WriteLine("No message found");
}
}
Any help would be greatly appreciated!
I'm suffered from making text files with UWP.
I've experienced how to make a text file in UWP.
but when I tried to make own my program, I got some problems with Creating File. I don't know where is the reason from. the lack of my knowledge about C# class p? or misuse of builtin Class(like storageFile etc...) function?
I made my application to read files from device and save as a another file.
but It doesn't work at all.
when I use break point to figure out what is problem.
Picture1. outputFile is setted as a null
you can see i.outputFile(type StorageFile) is setted as a null. but with my intent, it shouldn't be remained as a null.
because I set its(i's) outputFile with member function called "setOutFile(StorageFolder)". you can see in the picture above.
below is my source code which handle my ClassType. it stops when meet FileIO.WriteTextAsync ... because i.outPutFile is null.
public async Task<List<string>> DoRandom(FileLists fl, StorageFolder folder)
{
FileLists retLists = new FileLists();
List<string> encodingList = new List<string>();
foreach (UploadedFile i in fl)
{
// read stream from storagefile
Stream s = await i.originFile.OpenStreamForReadAsync();
// streamreader from stream
StreamReader sr = new StreamReader(s, Encoding.ASCII);
i.setOutFile(folder);
if (sr.CurrentEncoding == Encoding.ASCII)
{
encodingList.Add("ASCII " + i.outputName);
}
string str = await sr.ReadToEndAsync();
StringBuilder stringBuilder = new StringBuilder(str);
if (Option1)
{
doOption1(stringBuilder);
}
await FileIO.WriteTextAsync(i.outputFile, stringBuilder.ToString());
if (Option1);
};
return encodingList;
}
in Uploaded Class (you can just see setOutFile function).
class UploadedFile
{
public StorageFile originFile;
public StorageFile outputFile { get; set; }
public string inputName {get; private set; }
public string outputName {get; private set; }
public string fileSz{get; private set;}
public UploadedFile(StorageFile storageFile)
{
originFile = storageFile;
inputName = storageFile.Name;
}
public async Task GetFileSz()
{
var bp = await originFile.GetBasicPropertiesAsync();
this.fileSz = string.Format("{0:n0} Byte", bp.Size);
}
public async void setOutFile(StorageFolder folder)
{
var rand = new Random();
string charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
StringBuilder result = new StringBuilder(13);
for (int i=0; i<13; i++)
{
result.Append(charset[rand.Next(charset.Length)]);
}
StringBuilder outputName = new StringBuilder();
outputName.Append(inputName.Substring(0, inputName.Length - 4));
outputName.Append("_");
outputName.Append(result);
outputName.Append(".txt");
this.outputName = outputName.ToString();
outputFile = await folder.CreateFileAsync(outputName.ToString(), CreationCollisionOption.ReplaceExisting);
for (int i = 0; i <= 10000; i++) // break point
i++;
}
when I insert a assignment(below) in constructor.
outputFile = storageFile;
it barely make a file in target directory with purposed fileName. but it has no data in it!!!..... I tried with below source Code but it has no data in it, either.
await FileIO.WriteTextAsync(i.outputFile, "constant String");
my app makes file with edited constructor, but it has no data in it.
I don't know what is my problem, C# Class syntax or ...what?
Thanks all of you, guys who commented on my posts.
I desperately tried to figure out what is problem, I met. I carefully read your comments and I think your advice is definitely good.
but the problem that I met was, Straightforwardly, sync,async- matter thing. I struggled with this problem with more than 5 hours, and I found the class's member function setOutfile has async function "StorageFoder.CreateFileAsync" and when the machine read that statement, It create asynchronously and begin to write some text(implemented in handler class) on It even It's not created.
...In myType Class, I changed my member function's type from async void to async Task.
public async Task setOutFile(StorageFolder folder)
{
var rand = new Random();
string charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
StringBuilder result = new StringBuilder(13);
for (int i=0; i<13; i++)
{
result.Append(charset[rand.Next(charset.Length)]);
}
StringBuilder outputName = new StringBuilder();
outputName.Append(inputName.Substring(0, inputName.Length - 4));
outputName.Append("_");
outputName.Append(result);
outputName.Append(".txt");
this.outputName = outputName.ToString();
if (folder != null)
{
outputFile = await folder.CreateFileAsync(outputName.ToString(), CreationCollisionOption.ReplaceExisting);
}
}
and then in handler class member function, i just added await keyword before i.setOutFile(StorageFolder ..)
public async Task<List<string>> DoRandom(FileLists fl, StorageFolder folder)
{
FileLists retLists = new FileLists();
List<string> encodingList = new List<string>();
foreach (UploadedFile i in fl)
{
// read stream from storagefile
Stream s = await i.originFile.OpenStreamForReadAsync();
// streamreader from stream
StreamReader sr = new StreamReader(s, Encoding.ASCII);
await i.setOutFile(folder) ; // wait until setOutFile ends
if (sr.CurrentEncoding == Encoding.ASCII)
{
encodingList.Add("ASCII " + i.outputName);
}
string str = await sr.ReadToEndAsync();
StringBuilder stringBuilder = new StringBuilder(str);
if (Option1)
{
doOption1(stringBuilder);
}
await FileIO.WriteTextAsync(i.outputFile, stringBuilder.ToString());
if (Option1);
};
return encodingList;
}
and It works, thanks all you guys.
I'm looking to parse the WebCacheV01.dat file using C# to find the last file location for upload in an Internet browser.
%LocalAppData%\Microsoft\Windows\WebCache\WebCacheV01.dat
I using the Managed Esent nuget package.
Esent.Isam
Esent.Interop
When I try and run the below code it fails at:
Api.JetGetDatabaseFileInfo(filePath, out pageSize, JET_DbInfo.PageSize);
Or if I use
Api.JetSetSystemParameter(instance, JET_SESID.Nil, JET_param.CircularLog, 1, null);
at
Api.JetAttachDatabase(sesid, filePath, AttachDatabaseGrbit.ReadOnly);
I get the following error:
An unhandled exception of type
'Microsoft.Isam.Esent.Interop.EsentFileAccessDeniedException' occurred
in Esent.Interop.dll
Additional information: Cannot access file, the file is locked or in use
string localAppDataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
string filePathExtra = #"\Microsoft\Windows\WebCache\WebCacheV01.dat";
string filePath = string.Format("{0}{1}", localAppDataPath, filePathExtra);
JET_INSTANCE instance;
JET_SESID sesid;
JET_DBID dbid;
JET_TABLEID tableid;
String connect = "";
JET_SNP snp;
JET_SNT snt;
object data;
int numInstance = 0;
JET_INSTANCE_INFO [] instances;
int pageSize;
JET_COLUMNDEF columndef = new JET_COLUMNDEF();
JET_COLUMNID columnid;
Api.JetCreateInstance(out instance, "instance");
Api.JetGetDatabaseFileInfo(filePath, out pageSize, JET_DbInfo.PageSize);
Api.JetSetSystemParameter(JET_INSTANCE.Nil, JET_SESID.Nil, JET_param.DatabasePageSize, pageSize, null);
//Api.JetSetSystemParameter(instance, JET_SESID.Nil, JET_param.CircularLog, 1, null);
Api.JetInit(ref instance);
Api.JetBeginSession(instance, out sesid, null, null);
//Do stuff in db
Api.JetEndSession(sesid, EndSessionGrbit.None);
Api.JetTerm(instance);
Is it not possible to read this without making modifications?
Viewer
http://www.nirsoft.net/utils/ese_database_view.html
Python
https://jon.glass/attempts-to-parse-webcachev01-dat/
libesedb
impacket
Issue:
The file is probably in use.
Solution:
in order to free the locked file, please stop the Schedule Task -\Microsoft\Windows\Wininet\CacheTask.
The Code
public override IEnumerable<string> GetBrowsingHistoryUrls(FileInfo fileInfo)
{
var fileName = fileInfo.FullName;
var results = new List<string>();
try
{
int pageSize;
Api.JetGetDatabaseFileInfo(fileName, out pageSize, JET_DbInfo.PageSize);
SystemParameters.DatabasePageSize = pageSize;
using (var instance = new Instance("Browsing History"))
{
var param = new InstanceParameters(instance);
param.Recovery = false;
instance.Init();
using (var session = new Session(instance))
{
Api.JetAttachDatabase(session, fileName, AttachDatabaseGrbit.ReadOnly);
JET_DBID dbid;
Api.JetOpenDatabase(session, fileName, null, out dbid, OpenDatabaseGrbit.ReadOnly);
using (var tableContainers = new Table(session, dbid, "Containers", OpenTableGrbit.ReadOnly))
{
IDictionary<string, JET_COLUMNID> containerColumns = Api.GetColumnDictionary(session, tableContainers);
if (Api.TryMoveFirst(session, tableContainers))
{
do
{
var retrieveColumnAsInt32 = Api.RetrieveColumnAsInt32(session, tableContainers, columnIds["ContainerId"]);
if (retrieveColumnAsInt32 != null)
{
var containerId = (int)retrieveColumnAsInt32;
using (var table = new Table(session, dbid, "Container_" + containerId, OpenTableGrbit.ReadOnly))
{
var tableColumns = Api.GetColumnDictionary(session, table);
if (Api.TryMoveFirst(session, table))
{
do
{
var url = Api.RetrieveColumnAsString(
session,
table,
tableColumns["Url"],
Encoding.Unicode);
var downloadedFileName = Api.RetrieveColumnAsString(
session,
table,
columnIds2["Filename"]);
if(string.IsNullOrEmpty(downloadedFileName)) // check for download history only.
continue;
// Order by access Time to find the last uploaded file.
var accessedTime = Api.RetrieveColumnAsInt64(
session,
table,
columnIds2["AccessedTime"]);
var lastVisitTime = accessedTime.HasValue ? DateTime.FromFileTimeUtc(accessedTime.Value) : DateTime.MinValue;
results.Add(url);
}
while (Api.TryMoveNext(session, table.JetTableid));
}
}
}
} while (Api.TryMoveNext(session, tableContainers));
}
}
}
}
}
catch (Exception ex)
{
// log goes here....
}
return results;
}
Utils
Task Scheduler Wrapper
You can use Microsoft.Win32.TaskScheduler.TaskService Wrapper to stop it using c#, just add this Nuget package [nuget]:https://taskscheduler.codeplex.com/
Usage
public static FileInfo CopyLockedFileRtl(DirectoryInfo directory, FileInfo fileInfo, string remoteEndPoint)
{
FileInfo copiedFileInfo = null;
using (var ts = new TaskService(string.Format(#"\\{0}", remoteEndPoint)))
{
var task = ts.GetTask(#"\Microsoft\Windows\Wininet\CacheTask");
task.Stop();
task.Enabled = false;
var byteArray = FileHelper.ReadOnlyAllBytes(fileInfo);
var filePath = Path.Combine(directory.FullName, "unlockedfile.dat");
File.WriteAllBytes(filePath, byteArray);
copiedFileInfo = new FileInfo(filePath);
task.Enabled = true;
task.Run();
task.Dispose();
}
return copiedFileInfo;
}
I was not able to get Adam's answer to work. What worked for me was making a copy with AlphaVSS (a .NET class library that has a managed API for the Volume Shadow Copy Service). The file was in "Dirty Shutdown" state, so I additionally wrote this to handle the exception it threw when I opened it:
catch (EsentErrorException ex)
{ // Usually after the database is copied, it's in Dirty Shutdown state
// This can be verified by running "esentutl.exe /Mh WebCacheV01.dat"
logger.Info(ex.Message);
switch (ex.Error)
{
case JET_err.SecondaryIndexCorrupted:
logger.Info("Secondary Index Corrupted detected, exiting...");
Api.JetTerm2(instance, TermGrbit.Complete);
return false;
case JET_err.DatabaseDirtyShutdown:
logger.Info("Dirty shutdown detected, attempting to recover...");
try
{
Api.JetTerm2(instance, TermGrbit.Complete);
Process.Start("esentutl.exe", "/p /o " + newPath);
Thread.Sleep(5000);
Api.JetInit(ref instance);
Api.JetBeginSession(instance, out sessionId, null, null);
Api.JetAttachDatabase(sessionId, newPath, AttachDatabaseGrbit.None);
}
catch (Exception e2)
{
logger.Info("Could not recover database " + newPath + ", will try opening it one last time. If that doesn't work, try using other esentutl commands", e2);
}
break;
}
}
I'm thinking about using the 'Recent Items' folder as when you select a file to upload an entry is written here:
C:\Users\USER\AppData\Roaming\Microsoft\Windows\Recent
string recent = (Environment.GetFolderPath(Environment.SpecialFolder.Recent));