Forum Discussion
10 Replies
- AlexKaras
Champion Level 2
Hi Ofer,
For one of my C# projects I ended-up with the code below. It works so far. I did not try to port it to TestComplete, but think that this should be possible (with the use of aqFile and/or dotNet objects).
Maybe somebody have better suggestion?
//-------------------------------------------------------------------------------
/// <summary>
/// Tries to move file with the check whether it is locked.
/// Code is based on: http://stackoverflow.com/questions/1304/how-to-check-for-file-lock-in-c
/// Also: http://stackoverflow.com/questions/685135/open-file-in-exclusive-mode-in-c
/// </summary>
/// <param name="sourceFileName">The full filename of the original file to move</param>
/// <param name="targetFileName">The full filename of the target file</param>
/// <returns>Nothing</returns>
private bool MoveFile(string sourceFileName, string targetFileName)
{
const int _numberOfTries = 60;
const int _timeIntervalBetweenTries = 500;
bool bRetVal = false;
int tries = 0;
while (true)
{
try
{
File.Move(sourceFileName, targetFileName);
return true;
return File.Open(_fileName, FileMode.Open, fileAccess, Fileshare.None);
}
catch (IOException e)
{
if (!IsFileLocked(e))
throw;
if (++tries > _numberOfTries)
throw new Exception(
String.Format(@"The file {0} is locked too long by the {1} process: {2}",
sourceFileName, GetFileProcessName(sourceFileName), e.Message),
e);
Thread.Sleep(_timeIntervalBetweenTries);
}
}
return bRetVal;
}
//-------------------------------------------------------------------------------
/// <summary>
/// Checks whether the exception was caused by the file being locked.
/// </summary>
/// <param name="exception">The exception occurred during file operation</param>
/// <returns>True if file is locked, False otherwise</returns>
private static bool IsFileLocked(IOException exception)
{
int errorCode = Marshal.GetHRForException(exception) & ((1 << 16) - 1);
return (32 == errorCode) || (33 == errorCode);
}
//------------------------------------------------------------------------------- - OfervSuper ContributorThanks Alexei,
But as for one who don't know c# how can i translate it to a language TestComplete will be able to work with?
Thanks - HKosova
Alumni
Hi Ofer,
When a file is being created, it is locked. In this case, file opening functions fail with an error. So, to wait until a file lock is released, you can call a file opening function in a loop until it succeeds.
Using TestComplete's built-in aqFile object, it should be similar to this:function Test()
{
var ERR_UNABLE_TO_OPEN = -2147467259;
var locked;
// Start the asynchronous file copying
Sys.OleObject("WScript.Shell").Run("cmd /k copy E:\\VeryLargeFile.exe E:\\VeryLargeFile2.exe");
do
{
locked = false;
try {
aqFile.OpenBinaryFile("E:\\VeryLargeFile2.exe", aqFile.faRead, false).Close();
}
catch (err)
{
if (err.number == ERR_UNABLE_TO_OPEN)
{
locked = true;
aqUtils.Delay(1000);
}
}
}
while (locked);
} - OfervSuper ContributorThanks Helen :)
- OfervSuper ContributorHi Helen,
Just started working on the function you sent and i find that in order to check that the file is finish creating i need to copy it to different location which is not something i want to do.isn't it?
is there another way to check that the file finish creating?
Thanks - HKosova
Alumni
Hi Ofer,
I used the copy operation to reproduce the file creation process as you said in your original post:if let say i copy a file from somewhere and i'm checking the folder it has been copied to,to know when it has been finish copied.
how can i make sure it did truly finished copied?
If your target file is created in another way, simply replace the copy operation with the operations that initiate file creation in your scenario. Also, make sure to replace the file name in the aqFile.OpenBinaryFile operation with your file name. - OfervSuper ContributorSure,my fault sorry about that,basically i'm creating the file in a folder so,how can i make sure it's done creating before start creating the second file?
I'm checking that the file size is not 0kb and the problem is that the getsize method is checking the file(it's a big file)before it's even created so the size i'm getting is 0,if the system will wait untill the file finish creating i'll be able to get it's real size and that's my problem.
can you please modify the script so it'll do what i just typed?
Thanks - OfervSuper ContributorHi Helen,
After talking to the developer who's responssible for this application he told be that the best way to check if a document has finish printing is to go over the print queue and see if the document is still there.if it's gone from the list it means it finish printing.I've tried to search for a script who do that and i found this http://www.pcreview.co.uk/forums/detect-print-job-completion-vbscript-t1573152.html but, i have no idea how to convert this code to something i need.If you can help me do that i'll be happy.I need to sample the print queue every 500 milliseconds and check if a file(using the file name)is still on the list,if so hang the script execution if not sample the file size.
Thanks for the help - OfervSuper ContributorHi Helen,
I'm so sorry but, the problem with the function you sent is that the file is able to open (aqFile.OpenBinaryFile("E:\\VeryLargeFile2.exe", aqFile.faRead, false).Close();) while it's size is still 0kb means there's something wrong here.can you tell why
Thanks - Hi Ofer,
As far as I understand, the problematic file is created by a virtual printer. If so, there's no guarantee that the file is always exclusively open by the printer from the files creation till the end of writing data to it. Thus, I think we'll need to try using your developer's advice and use a function that will delay the execution until the document gets out of the printing queue:function test()
{
waitUntilTheDocumentIsNotInTheQueue("TestDocument");
}
function waitUntilTheDocumentIsNotInTheQueue(document)
{
var wmi = GetObject("winmgmts:{impersonationLevel=impersonate}");
var documentFound = false;
do
{
var documentFound = false;
e = new Enumerator(wmi.InstancesOf("Win32_PrintJob"));
for(; !e.atEnd(); e.moveNext())
{
var s = e.item();
if (s.Document == document)
{
documentFound = true;
break;
}
}
}
while (documentFound)
}