Jump to content

This site uses cookies. By continuing to browse the site you are agreeing to our use of cookies. Find out more here. X
X


Photo

Progress bar when applying WIM image file


  • Please log in to reply
19 replies to this topic

#1 Catdaddy

Catdaddy

    Seeker

  • Active Members
  • 33 posts

Posted 02 July 2008 - 04:13 PM

I hope I'm posting this in the right place as I am a general noob who is just asking for advice.

I've searched the forums and researched different sources about using or controlling Imagex.exe with Autoit. One of the drawbacks I and many others have had is getting callback or feedback information from it in order to properly display progress (ie. ProgressBar) in a script. Especially if you are trying to apply an image to a drive because of the multi-threading issue. Sure, we could run Imagex and let the user see the text progress from an unhidden command window, but where's the fun in that?

Below is some code I've been tinkering with that might be a solution:

CODE
$NeededSpace = (428876393)

ProgressOn("Progress Meter", "Increments every second", "0 percent")

$RunImagex = Run("imagex.exe /Apply c:\temp\winpe.wim 1 c:\temp2", "c:\temp")

While 1
Sleep (1000)
$CurDirSize = DirGetSize("c:\temp2")
$Size = (($CurDirSize/$NeededSpace)*100)
$Perc = (Round ($Size, 0))
ProgressSet ($Perc, $Perc & " percent")
If $CurDirSize >= $NeededSpace Then
ExitLoop
EndIf
If ProcessExists ("Imagex.exe") = 0 Then ExitLoop
WEnd

ProgressOff()

msgbox(0,"", "Return code: " & $RunImagex & @CRLF & "Current Folder Size: " & $CurDirSize & @CRLF & "Size That Was Needed: " & $NeededSpace)





Please excuse my sloppy code as this is just for demonstration purposes.

I have two folders on the root of C: named TEMP and TEMP2 (yeah, I know, real imaginative). This script resides in TEMP along with the WIM file I'll be using and TEMP2 is empty. Also, Imagex.exe is in my path and Wimfltr.sys is applied as I am running XP. (Not that I need it for this demonstration). The WIM file is simply a PE 2.0 image that I extracted from the MS WAIK for testing purposes. As it stands now this script works very effectively and gives me a nice clean progress bar. My only drawback is $NeededSpace is a given in the beginning. This does not trouble me too much because if you run Imagex against your WIM file with the /INFO switch you can glean through the XML output the TotalBytes that the uncompressed image will require.

In this example I am polling DirGetSize every second to compare the current folder size of TEMP2 against $NeededSpace. More or less when they are equal then my progress bar should read 100%. If you were applying the image to a drive letter you could use DriveSpaceFree and DriveSpaceTotal to get the same results I would imagine (more testing to come). In case the operation errors out or Imagex blows up I use ProcessExists to see if Imagex.exe is still running and if it isn't then I exit the loop.

So, basically I have two questions for you fine folk:

1. Has anyone else already tried this approach? If so, would you be so kind as to point me in the right direction where I might find examples?

2. Does anyone know the exit or return codes from Imagex.exe? You'll notice if you try the above script that you'll get differing results for $RunImagex each time you successfully run it. Knowing what Imagex returns would be a great help in knowing if the apply operation was successful or not.

Of course, the only drawback to this method is that your target folder or drive must be empty when you start. What I want to use this for is a template script that I can burn on a PE 2.0 DVD with any WIM file I choose and be able to get the same clean results. One use for this would be, if you were a system builder, you could create a clean image of an install, place it on a DVD with this script and give the user an instant recovery disk.

At any rate, any help I could get would be appreciated. Thanks.

Edit: Disregard the return code from $RunImagex. I am such a noob that I assumed since RunWait returns exit codes that Run does as well. Doh! RTFM!

Edited by Catdaddy, 02 July 2008 - 05:14 PM.








#2 LarryDalooza

LarryDalooza

    Schmember

  • Active Members
  • PipPipPipPipPipPip
  • 957 posts

Posted 02 July 2008 - 06:06 PM

http://www.autoitscript.com/forum/index.ph...st&p=246908
Posted ImageAutoIt3 Yahoo Group - Expert LarryA tool of Big Blue...

#3 LarryDalooza

LarryDalooza

    Schmember

  • Active Members
  • PipPipPipPipPipPip
  • 957 posts

Posted 03 July 2008 - 08:24 PM

Perhaps you could try the "/scroll" option?

Lar.
Posted ImageAutoIt3 Yahoo Group - Expert LarryA tool of Big Blue...

#4 LarryDalooza

LarryDalooza

    Schmember

  • Active Members
  • PipPipPipPipPipPip
  • 957 posts

Posted 03 July 2008 - 08:38 PM

Also there is a DLL... WIMGAPI.dll if you want to research the API and learn how to use a callback to get progress info.

Lar.
Posted ImageAutoIt3 Yahoo Group - Expert LarryA tool of Big Blue...

#5 Björn Kaiser

Björn Kaiser

    Seeker

  • Active Members
  • 35 posts

Posted 07 July 2008 - 06:03 AM

Also there is a DLL... WIMGAPI.dll if you want to research the API and learn how to use a callback to get progress info.

Lar.

From my unsuccessfull attempts using wimgapi.dll I can only say it's not possible (or I didnt dig in far enough) to read the progress while applying. I get the callbacks while capturing, but for some reason the whole thing gets blocked when I apply the image. As soon as the image is completely applied I get the whole callbacks in one bunch. (not very useful I guess)

All I could gather from the MSDN forums was that it has something to do with MS enabling multithreading in the "apply" function. So the callbacks never reach my AutoIt instance. (given I understood it right)

Edit: I guess I should have read the OP to the end. The problem with the callbacks and multithreading was already mentioned there.

Edited by Björn Kaiser, 07 July 2008 - 06:07 AM.

"I teleported home one nightWith Ron and Sid and Meg.Ron stole Meggie's heart awayAnd I got Sidney's leg."- A poem about matter transference beams.

#6 Catdaddy

Catdaddy

    Seeker

  • Active Members
  • 33 posts

Posted 07 July 2008 - 12:16 PM

http://www.autoitscript.com/forum/index.ph...st&p=246908


Thanks, Larry and Bjorn Kaiser. I followed the link above but I'm afraid it did not help me. I think what I'm going to try is creating an XML file with the /INFO switch in Imagex and then save it to the X: drive while in PE 2.0 (the RAM drive should be able to hold a small KB file I would imagine). Then I will attempt to use the XMLDom wrapper written by Stephen Podhajecki to get all of the variables I need from the XML output. (I'll freely admit I'm XML illiterate so this will be a learning experience).

Bjorn,

I researched the forums some time ago and found this: http://www.autoitscript.com/forum/index.ph...;hl=wimgapi.dll
but it appears they ran into the same problem. I also prefer Valik's explanation as to why it does not work:

"Quite simply, Microsoft, as is typical, are idiots. They never call fflush() on the stream. The output builds up and is not flushed until the program closes. AutoIt shows you the output the instant it sees it, but during the entire run of the program, the ouput is buffered in imagex. By the way, you can confirm that it's not AutoIt's fault by using the command line and re-directing output to a file when using the /scroll argument. Even doing that will leave an empty file (IIRC, there is some output, but not the progress percentage). Then when the program is done, poof, magically all the data is there. Without using the /scroll argument, data is written directly to the screenbuffer and not to stdout."

For the time being though, I still have Jon's excellent Gimagex found here: http://www.autoitscript.com/gimagex/ to fall back on.

#7 Björn Kaiser

Björn Kaiser

    Seeker

  • Active Members
  • 35 posts

Posted 07 July 2008 - 03:00 PM

...
For the time being though, I still have Jon's excellent Gimagex found here: http://www.autoitscript.com/gimagex/ to fall back on.


Did you ever try to integrate that into a script, not using the GUI? IIRC the last time I tried it, which is honestly like 8 weeks ago or so, I got the same problem as with the wimgapi.dll itself when it came to the status callbacks.

I guess the only thing we could do would be complain to MS about that. But how are the chances they care for that or would even want to allow scripting the wimgapi with anything other than VBS?
"I teleported home one nightWith Ron and Sid and Meg.Ron stole Meggie's heart awayAnd I got Sidney's leg."- A poem about matter transference beams.

#8 Catdaddy

Catdaddy

    Seeker

  • Active Members
  • 33 posts

Posted 07 July 2008 - 04:19 PM

Did you ever try to integrate that into a script, not using the GUI? IIRC the last time I tried it, which is honestly like 8 weeks ago or so, I got the same problem as with the wimgapi.dll itself when it came to the status callbacks.

I guess the only thing we could do would be complain to MS about that. But how are the chances they care for that or would even want to allow scripting the wimgapi with anything other than VBS?


Ironically, I just went to the above site today and noticed an update was posted on July 4 for Gimagex. No, I've never tried implementing Jon's COM object into a script. I'll admit I'm still quite the novice with these things.

You're right. MS probably has bigger fish to fry than worrying about a silly console program like this. Many people have told me to not worry about it and just use the CLI. But you don't know if something can be done until you try, right?

#9 Björn Kaiser

Björn Kaiser

    Seeker

  • Active Members
  • 35 posts

Posted 07 July 2008 - 04:55 PM

Ironically, I just went to the above site today and noticed an update was posted on July 4 for Gimagex. No, I've never tried implementing Jon's COM object into a script. I'll admit I'm still quite the novice with these things.


If you want to try, I could give you the last version of my gimagex_com.au3. However, _much_ undocumented code there. Since I'm not really a programmer I tend to do my scripts the "trial and error" way. function comes first. documentation? oh well, maybe later. :muttley:
"I teleported home one nightWith Ron and Sid and Meg.Ron stole Meggie's heart awayAnd I got Sidney's leg."- A poem about matter transference beams.

#10 Catdaddy

Catdaddy

    Seeker

  • Active Members
  • 33 posts

Posted 07 July 2008 - 05:28 PM

If you want to try, I could give you the last version of my gimagex_com.au3. However, _much_ undocumented code there. Since I'm not really a programmer I tend to do my scripts the "trial and error" way. function comes first. documentation? oh well, maybe later. :muttley:


HeeHee, I'm the same way. Sure, I would love to see what you got.

On a side note, I just discovered that 7Zip now handles WIM files as straight archives. I think I might fool around with that for a bit. Wouldn't that be interesting? To do away with the WIM format completely? I remember in the old days (Windows 3.11/95) when I worked in a repair depot for a laptop manufacturer, all of our OS images were pure and simple ZIP files! Of course we had to script FDISK and FORMAT with a BAT file. As long as the archive retained all of the original file and folder attributes, why couldn't RAR or 7ZIP be used to capture and apply an image? Heck, you could even password protect the archive.

Now, having said that, I have never attempted to create a 4GB RAR file. Depending on the compression level chosen, I would imagine the capture time would be anywhere between 45 minutes to 7 hours :)

#11 Björn Kaiser

Björn Kaiser

    Seeker

  • Active Members
  • 35 posts

Posted 07 July 2008 - 07:36 PM

HeeHee, I'm the same way. Sure, I would love to see what you got.

On a side note, I just discovered that 7Zip now handles WIM files as straight archives. I think I might fool around with that for a bit. Wouldn't that be interesting? ...

Now, having said that, I have never attempted to create a 4GB RAR file. Depending on the compression level chosen, I would imagine the capture time would be anywhere between 45 minutes to 7 hours :muttley:

I think one has to try that out. But my guess would be that 7zip loses the ACL and a lot more. (if you unpack a WIM with it.) There is one way to circumvent this though, regardless of the archive type used. I have seen commandline tools on SF.net and I guess you can export existent ACL lists to a text/settings file and import that file with another option onto a directory tree restored from an archive.

But why the hassle (given wimgapi/imagex would work nicely)?

and for the times:
what if we just use this numbers as an orientation:
http://www.codinghorror.com/blog/archives/000799.html

ok, on second thought a VHD isnt just the same as a bunch of small files. Just trying to think it through a bit.

as for the gimagex 'UDF' I'll see what I can do at work tomorrow.
"I teleported home one nightWith Ron and Sid and Meg.Ron stole Meggie's heart awayAnd I got Sidney's leg."- A poem about matter transference beams.

#12 Björn Kaiser

Björn Kaiser

    Seeker

  • Active Members
  • 35 posts

Posted 08 July 2008 - 05:30 AM

here is my try on wrapping GImageX COM:
http://autoit.pastebin.com/f7afcd31f
and here a small example for capturing:
http://autoit.pastebin.com/f16ecd5f
"I teleported home one nightWith Ron and Sid and Meg.Ron stole Meggie's heart awayAnd I got Sidney's leg."- A poem about matter transference beams.

#13 Björn Kaiser

Björn Kaiser

    Seeker

  • Active Members
  • 35 posts

Posted 20 October 2008 - 09:26 AM

ok, digging out old topics.
But after reading the "wimgapi freezes VB6 UI" thread at MSDN again I have come to the idea, to just put wimgapi into its own process. Meaning, I'll write a windows service in AutoIt that is only there to read/write to a named pipe and execute wimgapi functions. So I can send commands to it through the named pipe and the service can write the progress and other status back to the named pipe. On the other side of the pipe I would have my client in AutoIt3 that handles the progress/log window.
I guess that should work. Anyone got better ideas before I start working on this?
"I teleported home one nightWith Ron and Sid and Meg.Ron stole Meggie's heart awayAnd I got Sidney's leg."- A poem about matter transference beams.

#14 rroot

rroot

    Seeker

  • Active Members
  • 5 posts

Posted 22 October 2008 - 06:15 PM

But after reading the "wimgapi freezes VB6 UI" thread at MSDN again I have come to the idea, to just put wimgapi into its own process.

You can also put wimgapi into a thread and pass events through a hidden window. I do a bit of work on an ActiveX control called SmartWIM (which is free for personal use and $29 for business use) and we've been able to stop GUI blocking through that technique.

I've had good luck using AutoIT and SmartWIM together as well. If you like, I can wrangle up some scripts to illustrate.

#15 rroot

rroot

    Seeker

  • Active Members
  • 5 posts

Posted 23 October 2008 - 04:15 PM

Okay, here's a simple one with SmartWIM using the ProgressOn, ProgressSet, ProgressOff.
http://autoit.pastebin.com/f3ecfe1f4
And another showing how to use it with the full GUI.
http://autoit.pastebin.com/f3242f14f

I highlighted the .Async = 1 option on each of these examples, because that's a setting that's specifically there for AutoIT. People who use VBScript or .NET often are okay with the capture or apply not returning until it's done, so Async isn't turned on by default.

But what it does is spawn a thread with the capture or apply or split (or whatever) running in the background and it'll call the Progress and AsyncCompleted events when it's done. Anyway, you can download a pre-release of SmartWIM 2.0 from here and try the examples for yourself.

I don't know, I hope that helps.

#16 Björn Kaiser

Björn Kaiser

    Seeker

  • Active Members
  • 35 posts

Posted 14 January 2009 - 01:20 PM

yeah, old topic. however, seems MS modified imagex.exe and maybe wimgapi.dll with the advent of Windows 7. imagex got some new options (/logfile for one) and it seems the screen buffers are flushed now.

I'll take a look at it as soon as I have some time.
"I teleported home one nightWith Ron and Sid and Meg.Ron stole Meggie's heart awayAnd I got Sidney's leg."- A poem about matter transference beams.

#17 Björn Kaiser

Björn Kaiser

    Seeker

  • Active Members
  • 35 posts

Posted 13 May 2009 - 11:01 AM

ok, it took some time, but I finally got around to test my old code with a new version of WIMGAPI.dll.

Test environment:
Virtualbox 2.2 VM with one guest CPU on Ubuntu 9.04
OS: Windows 7, Build 7100 (RC)
wimgapi.dll version 6.1.7100.0 (Windows 7 WAIK RC)

with that setup I got progress callbacks in both cases, capturing and applying the image.

Just for those still interested in working with wimgapi.dll from autoit.

btw, here is my code:

my wimgapi.wrapper
http://autoit.pastebin.com/f9857fa3

my test script
http://autoit.pastebin.com/f7002099b

Edited by Björn Kaiser, 13 May 2009 - 11:07 AM.

"I teleported home one nightWith Ron and Sid and Meg.Ron stole Meggie's heart awayAnd I got Sidney's leg."- A poem about matter transference beams.

#18 Sypher

Sypher

    Wayfarer

  • Active Members
  • Pip
  • 91 posts

Posted 20 October 2009 - 03:10 PM

Thanks Björn, this code has been very helpful to me :)

I only have one slight problem with it. I am displaying the status on a label.
Somehow the modified text is put *on top* of the old one, after a few seconds of updates you can't really read the seconds.

Instead of the ProgressSet(...) in _Progress, i'm using GuiCtrlSetData($label, "Remaining " & Int($3 / 1000) & " seconds"))
Any suggestions on what could be wrong here?

Thanks!

Edit:
Well kind-of- solved it by deleting the label and re-creating it every time there's a new text. Not really optimal though :)

Edited by Sypher, 21 October 2009 - 07:18 PM.


#19 ttleser

ttleser

    Adventurer

  • Active Members
  • PipPip
  • 138 posts

Posted 15 November 2010 - 05:41 PM

Björn Kaiser,

I just tried your test script modifying it slightly for a different WIM file and a different destination directory and while the progress window does appear, neither the progress indicator moves nor does the any seconds appear other than zero. It does appears to apply the image to my destination directory, but after about 10-20 seconds I'll get a not-responding for the AutoIt script.

I did find out my DLL is 6.1.7600.16385

Here's the script I was using:

Plain Text         
Opt("MustDeclareVars", 1) #include <wimgapi.au3> ;~ #include <DllCallback.au3> Dim $fhandle, $vhandle, $imageinfo, $i, $pProgress $pProgress = DllCallBackRegister ("_Progress", "int", "dword;lparam;wparam;ptr") ConsoleWriteError("DllCallBack error: " & @error & @CRLF & "_DllCallBack rc: " & $pProgress & @CRLF) $pProgress = DllCallbackGetPtr($pProgress) ProgressOn("Wimgapi.dll","Applying image ...") Apply("c:\PanasonicBootWim\boot.wim", "c:\test\") ;Apply("d:\distribution\Images\XP\GWPXP82.wim", "c:\test") ;~ ProgressOn("Wimgapi.dll","Capturing image ...") ;~ Capture("c:\temp\test.wim", "C:\temp\1\") DllCallBackFree($pProgress) ProgressOff() Func _Progress($1,$2,$3,$4)         If $1 = 38008 Then                 ProgressSet($2,"Remaining time : " & Int($3 / 1000) & " seconds")         EndIf ;~ If $1 = 38008 Then         ConsoleWrite("_Progress: " & @CRLF & $1 & @CRLF & $2 & @CRLF & $3 & @CRLF & $4 & @CRLF) ;~ EndIf Return $wim_msg_success ;~ Return 0 EndFunc Func Apply($wim,$sPath) Local $rc_apply, $rc_close, $rc_shutdown, $lhandle, $rc_temppath         $fhandle = _wim_createfile ($wim, $wim_generic_read) ;~      ConsoleWrite("_wim_createfile : " & $fhandle & @CRLF)         $rc_temppath = _wim_settemporarypath($fhandle,@TempDir) ;~      ConsoleWrite("_wim_settemporarypath : " & $rc_temppath & @CRLF)         $lhandle = _wim_loadimage ($fhandle,1) ;~      ConsoleWrite("_wim_loadimage : " & $lhandle & @CRLF)         _wim_registermessagecallback($fhandle,$pProgress)         $rc_apply = _wim_applyimage ($lhandle, $sPath) ;~      ConsoleWrite("_wim_applyimage : " & $rc_apply & @CRLF)         _wim_unregistermessagecallback($fhandle,$pProgress)         $rc_close = _wim_closehandle ($lhandle) ;~      ConsoleWrite("_wim_closehandle : " & $rc_close & @CRLF)         $rc_close = _wim_closehandle ($fhandle) ;~      ConsoleWrite("_wim_closehandle : " & $rc_close & @CRLF)         $rc_shutdown = _wim_shutdown () ;~      ConsoleWrite("_wim_shutdown : " & $rc_shutdown & @CRLF) EndFunc   ;==>Apply Func Capture($wim,$sPath)         $fhandle = _wim_createfile ($wim,$wim_generic_write,$wim_create_always,$wim_flag_verify,$wim_compress_xpress) ;~ $imageinfo = _wim_getimageinformation ($fhandle) ;~ ConsoleWrite("-- ImageInfo createFile" & @CRLF & UBound($imageinfo) & @CRLF) ;~ For $i = 0 To UBound($imageinfo) - 1 ;~      ConsoleWrite("$imageinfo[" & $i & "]: " & $imageinfo[$i] & @CRLF) ;~ Next ;~ _wim_setimageinformation ($fhandle, $imageinfo[3], $imageinfo[1])         _wim_registermessagecallback($fhandle,$pProgress)         $vhandle = _wim_captureimage ($fhandle, $sPath)         _wim_unregistermessagecallback($fhandle,$pProgress) ;~ $imageinfo = _wim_getimageinformation ($vhandle) ;~ ConsoleWrite("-- ImageInfo catureImage" & @CRLF & UBound($imageinfo) & @CRLF) ;~ For $i = 0 To UBound($imageinfo) - 1 ;~      ConsoleWrite("$imageinfo[" & $i & "]: " & $imageinfo[$i] & @CRLF) ;~ Next ;~ _wim_setimageinformation ($vhandle, $imageinfo[3], $imageinfo[1])         _wim_closehandle ($vhandle)         _wim_closehandle ($fhandle)         _wim_shutdown () EndFunc   ;==>Capture


Here's a snippit of the output I was getting in the console:
Plain Text         
>"C:\Program Files\AutoIt3\SciTE\AutoIt3Wrapper\AutoIt3Wrapper.exe" /run /prod /ErrorStdOut /in "E:\ImageXProgressTest.au3" /autoit3dir "C:\Program Files\AutoIt3" /UserParams     +>11:56:10 Starting AutoIt3Wrapper v.2.0.1.24    Environment(Language:0409  Keyboard:00000409  OS:WIN_7/  CPU:X64 OS:X86) >Running AU3Check (1.54.19.0)  from:C:\Program Files\AutoIt3 +>11:56:10 AU3Check ended.rc:0 >Running:(3.3.6.1):C:\Program Files\AutoIt3\autoit3.exe "E:\ImageXProgressTest.au3"     _WIM_Startup rc: 1 DllCallBack error: 0 _DllCallBack rc: 1 _WIM_CreateFile rc: 7035896 UBound $create: 7 _WIM_SetTemporaryPath rc: 1 _WIM_LoadImage rc: 7039752 _WIM_RegisterMessageCallback rc: 0 _Progress: 38009 10518488 4908908 0x00000000 _Progress: 38009 7710040 4908804 0x00000000 _Progress: 38009 8883400 4908700 0x00000000 _Progress: 38009 10788600 4908596 0x00000000 _Progress: 38009 9747864 4908492 0x00000000 _Progress: 38009 8897008 4908700 0x00000000 _Progress: 38009 8892208 4908596 0x00000000 _Progress: 38009 8883512 4908492 0x00000000 _Progress: 38009 8892312 4908596 0x00000000 _Progress: 38009 8887544 4908492 0x00000000 _Progress: 38009 8883288 4908596 0x00000000 _Progress: 38009 8887664 4908492 0x00000000 _Progress: 38009 8870928 4908804 0x00000000 _Progress: 38009 10772328 4908908 0x00000000 _Progress: 38009 7520536 4908804 0x00000000 _Progress: 38009 8871016 4908700 0x00000000 _Progress: 38009 8897104 4908596 0x00000000 _Progress: 38009 8887424 4908492 0x00000000


I'm assuming by looking at your code that $2 is the actual percentage correct? Looking at the output, one of the 2nd set of numbers is 8897104
, a little high for a percentage :graduated:


Thoughts?

#20 Björn Kaiser

Björn Kaiser

    Seeker

  • Active Members
  • 35 posts

Posted 22 November 2010 - 09:34 PM

i haven't worked on this script for quite some time, but all I know that the MsgId of the "ProgressMessage" from wimgapi.dll is 38008, thats why the if... 38008 then ... set progress is there.
And from the output you got, it looks like you never receive a progress message. For all I know, that is a threading problem of the dll (look at MSDN, some vbscript users ran into the same problem). somehow the DLL works different between applying and creating a WIM. if you are capturing a WIM, you get the progress message, if you apply a WIM, you dont get it.

Right now I dont understand why I posted in the past that the issue vanished. %)
"I teleported home one nightWith Ron and Sid and Meg.Ron stole Meggie's heart awayAnd I got Sidney's leg."- A poem about matter transference beams.




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users