c# pdf viewer free : How to move pages around in a pdf document application control utility html azure .net visual studio Windows%20Powershell%20in%20Action%202nd%20Edition51-part1507

480
CHAPTER 12
R
EMOTING
AND
BACKGROUND
JOBS
Things to notice in this output (again reformatted for readability) include the fact 
that the module name and path are temporary generated names. This module also 
defines  an 
OnRemove
handler (see chapter 10) to clean up when the module is 
removed. To see the contents of the module, you can look at the temporary file that 
was created by opening it in an editor using the module’s 
Path
property. For exam-
ple, to open the module file in PowerShell 
ISE
, use this code:
PS (14) > powershell_ise (Get-Command Get-Bios).Module.Path
Alternatively, you can save the session to an explicitly named module for reuse with 
Export-PSSession
. You’ll save this session as a module called 
bios
:
PS (15) > Export-PSSession -OutputModule bios -Session $s ` 
>> -type function -CommandName Get-Bios -AllowClobber 
>>
Directory: C:\Users\brucepay\Documents\WindowsPowerShell\Mod
ules\bios
Mode                LastWriteTime     Length Name 
----                -------------     ------ ----
-a---        11/29/2009   1:05 PM      10359 bios.psm1 
-a---        11/29/2009   1:05 PM         99 bios.format.ps1xml 
-a---        11/29/2009   1:05 PM        532 bios.psd1
Executing this command created a new module in your user module directory. It cre-
ated the script module file (.psm1), the module manifest (.psd1), and a file containing 
formatting information for the command. You used the 
-AllowClobber
parameter 
because the export is using the remote session to gather the data. If it finds a command 
being exported that already exists in the caller’s environment, this would be an error. 
Because 
Get-Bios
already exists, you had to use 
-AllowClobber
. Now you’ll try out 
the new module. First, you need to clean the existing module and session:
PS (32) > Get-Module | Remove-Module
PS (33) > Remove-PSSession $s
Import the module
PS (34) > Import-Module bios
and it returns right away. It can do this because it hasn’t actually set up the remote 
connection yet. This will happen the first time you access one of the functions in the 
module. Run 
Get-Bios
:
PS (35) > Get-Bios
Creating a new session for implicit remoting of "Get-Bios" 
command...
The term 'Get-Bios' is not recognized as the name of a cmdlet, 
function, script file, or operable program. Check the spelling of
the name, or if a path was included, verify that the path is 
How to move pages around in a pdf document - re-order PDF pages in C#.net, ASP.NET, MVC, Ajax, WinForms, WPF
Support Customizing Page Order of PDF Document in C# Project
move pages in a pdf; move pages in pdf
How to move pages around in a pdf document - VB.NET PDF Page Move Library: re-order PDF pages in vb.net, ASP.NET, MVC, Ajax, WinForms, WPF
Sort PDF Document Pages Using VB.NET Demo Code
how to reorder pdf pages in; reorder pdf page
B
ACKGROUND
JOBS
IN
P
OWER
S
HELL
481
correct and try again.
+ CategoryInfo          : ObjectNotFound: (Get-Bios:String)
[], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
When you ran this command, you saw a message indicating that a new connection 
was being created, and then the credential prompt popped up. This is pretty much as 
expected. But then you got an error saying the command 
Get-Bios
wasn’t found. 
This is because you dynamically added the function to the remote session. When you 
established a new session, because you didn’t add the function, it wasn’t there. In the 
next section, we’ll describe how to create remote endpoints that always contain your 
custom functions.
Let’s briefly review where we are. You’ve seen how PowerShell remoting allows 
you to execute  commands on a remote machine. You  know how to use explicit 
remoting to send scriptblocks to the remote computer to be executed. We explored 
interactive remoting where every command is sent to the remote machine, making it 
look as if you’re working directly on that machine. Finally, we looked at implicit 
remoting, which makes it appear that all your commands are being run locally. This 
greatly simplifies remoting for the casual user. It allows you to do things like manage 
an  Exchange mail server without having to install any code locally: you can use 
implicit remoting to generate a proxy module for the Exchange management module 
residing on another.
One thing that’s been constant across all of these remoting experiences is that you 
always had to wait for the remote commands to complete before issuing the next 
command. But early on in our discussion of remoting, we noted that because there 
are two (or more) processes involved, things actually do happen concurrently. In the 
next section, you’ll see how this characteristic is used to implement background jobs 
in PowerShell.
12.5
B
ACKGROUND
JOBS
IN
P
OWER
S
HELL
In the previous section, you saw that although remote PowerShell sessions run in sep-
arate processes, the user is still prevented from running new commands until the 
remote command completes. If you change things so that the caller doesn’t block, 
then other commands can run in parallel. This is how PowerShell background jobs 
work. With background jobs, the arrangement of executing commands and processes 
is shown in figure 12.11.
NOTE
In section 12.1.1, you saw that some commands have built-in 
remoting capabilities. In a similar fashion, there are also commands that 
have built-in job support. For example, the 
WMI
commands have an 
-AsJob
parameter that allows one or more 
WMI
operations to execute 
in the background. This type of job doesn’t rely on the background
C# HTML5 PDF Viewer SDK to view PDF document online in C#.NET
Page: Replace PDF Pages. Page: Move Page Position. Page: Extract, Copy and Users can view PDF document in single page or continue pages. Pan around the document.
how to reorder pages in a pdf document; how to move pages around in a pdf document
VB.NET PDF- View PDF Online with VB.NET HTML5 PDF Viewer
Page: Replace PDF Pages. Page: Move Page Position. Page: Copy, Paste PDF Users can view PDF document in single page or continue pages. Pan around the document.
how to move pages in pdf; how to change page order in pdf acrobat
482
CHAPTER 12
R
EMOTING
AND
BACKGROUND
JOBS
execution mechanism we’re describing in this section. Instead, they use 
their own implementation of  background execution.  In  the case  of 
WMI
jobs, they run in process but on a separate thread. The PowerShell 
job infrastructure was explicitly designed to support this kind of exten-
sion. If third parties expose their job abstractions as subclasses of the 
PowerShell 
Job
type, these extension jobs can be managed using the 
built-in job cmdlets just like native PowerShell jobs.
There’s more to background jobs than simply executing multiple things at the same 
time. Background jobs are designed to be commands that run asynchronously while 
you continue to do other things at the console. This means that there needs to be a 
way to manage these background jobs—starting and stopping them as well as retriev-
ing the output in a controlled way. 
NOTE
Background  jobs  are  implemented  using  processes  that  are 
children of your interactive PowerShell process. This means that if you 
end your PowerShell session, causing the process to exit, this will also 
cause all the background jobs to be terminated, because child processes 
are terminated when the parent process exits.
In this section we’ll cover the cmdlets that are used to accomplish these tasks. We’ll 
look at starting, stopping, and waiting for jobs. We’ll explore the 
Job
objects used to 
represent a running job. Finally, you’ll learn how to combine remoting with jobs to 
run jobs on remote machines.
PowerShell process #1
User
Foreground
command
PowerShell process #2
PowerShell process #3
Interactive cmds
PowerShell process #4
Background
command #1
Background
command #2
Background
command #3
Figure 12.11 The user sends interactive 
commands to be executed by the foreground 
loop. Background commands are executed in 
separate processes; each process has its own 
command loop. For each background job the user 
creates, a new instance of 
PowerShell.exe
is run to host the command loop for that job. 
This means that, if there are three background 
jobs as shown, then four processes are 
running—three for the background jobs and 
one for the interactive foreground job.
C# WPF PDF Viewer SDK to view PDF document in C#.NET
Page: Replace PDF Pages. Page: Move Page Position. Page: Extract, Copy PDF pages extract, copy, paste, C#.NET rotate PDF pages, C#.NET Pan around the PDF document
rearrange pages in pdf reader; reorder pages in pdf file
VB.NET PDF - View PDF with WPF PDF Viewer for VB.NET
Page: Replace PDF Pages. Page: Move Page Position. Page: Copy, Paste PDF pages extract, copy, paste, C#.NET rotate PDF pages, C#.NET Pan around the PDF document.
reorder pages pdf; reorder pages in a pdf
B
ACKGROUND
JOBS
IN
P
OWER
S
HELL
483
12.5.1
The job commands
As with remoting, jobs are managed with a set of cmdlets. These cmdlets are shown 
in table 12.3.  
A background job runs commands asynchronously. They’re used to execute long-
running commands in a way that the interactive session isn’t blocked until that com-
mand completes.
When a synchronous command runs, PowerShell waits until that command has 
completed before accepting any new commands. When a command is run in the 
background, instead  of blocking, the command returns immediately, emitting an 
object that represents the new background job. 
Although you get back control immediately (a new prompt) with the 
Job
object, 
you obviously won’t get the results of that job even if the job runs quickly. Instead, 
you use a separate command to get the job’s results. You also have commands to stop 
the job, to wait for the job to be completed, and finally to delete the job. Let’s see 
how these commands are used.
12.5.2
Working with the job cmdlets
You use the 
Start-Job
command to start a background job on a local computer. 
Let’s try this with a simple example. You’ll start a job and then pipe the resulting 
Job 
object through 
Format-List
so you can see of the members on the object:
PS (1) > Start-Job { "Hi" } | Format-List
HasMoreData   : True
StatusMessage : 
Location      : localhost 
Command       :  "Hi"
JobStateInfo  : Running 
Finished      : System.Threading.ManualResetEvent 
InstanceId    : fefc87f6-b5a7-4319-9145-616317ac8fcb 
Id            : 1 
Name          : Job1 
ChildJobs     : {Job2}
Table 12.3 The cmdlets for working with PowerShell jobs
Cmdlet
Description
Start-Job
Used to start background jobs. It takes a scriptblock as the argument 
representing the job to execute. 
Stop-Job
Stops a job based on the JobID.
Get-Job
Returns a list of currently executing jobs associated with the current 
session.
Wait-Job
Waits for one or more jobs to complete.
Receive-Job
Gets the results for a specific job.
Remove-Job
Removes a job from the job table so the resources can be released.
484
CHAPTER 12
R
EMOTING
AND
BACKGROUND
JOBS
Output        : {}
Error         : {} 
Progress      : {} 
Verbose       : {} 
Debug         : {} 
Warning       : {} 
State         : Running
As with the remoting cmdlets, the command to execute is specified by a scriptblock. 
When the command runs, you see that an object is returned, containing a wealth of 
information about the job. We’ll look at this object in a detail later on. For now, we’ll 
keep looking at the cmdlets. Now that you’ve started a job, you can use the 
Get-Job 
cmdlet to get information about that job:
PS (3) > Get-Job | fl
HasMoreData   : True
StatusMessage : 
Location      : localhost 
Command       :  "Hi"
JobStateInfo  : Completed 
Finished      : System.Threading.ManualResetEvent 
InstanceId    : fefc87f6-b5a7-4319-9145-616317ac8fcb 
Id            : 1 
Name          : Job1 
ChildJobs     : {Job2}
Output        : {}
Error         : {}
Progress      : {}
Verbose       : {}
Debug         : {}
Warning       : {}
State         : Completed
This cmdlet returned the same 
Job
object that you saw returned from 
Start-Job
(You can tell it’s the same object by looking at the 
InstanceId
, which is a 
GUID
and 
is guaranteed to be unique for each job.) There’s one significant different in this out-
put: if you look at the 
State
property, you see that it has changed from 
Running
to 
Completed
. So the first thing to note is that a job remains in the job table even after 
it has completed and will remain there until it’s explicitly removed using the 
Remove-
Job
cmdlet. To get the results of the job, you can use another cmdlet: 
Receive-Job
This cmdlet will return the results of the command that was executed:
PS (5) > Receive-Job 1
Hi
This returns the string that was emitted by the scriptblock passed to 
Start-Job
. This 
isn’t a very interesting example. Let’s try something that will take a bit longer to run. 
First, define the scriptblock you want to run in the 
$jsb
variable:
PS (9) > $jsb = { 
>> foreach ($i in 1..10) { Start-Sleep 1; "i is $i" }
B
ACKGROUND
JOBS
IN
P
OWER
S
HELL
485
>> } 
>>
Now start the job running. Let the 
Job
object that was returned use the default for-
matting, which complains if the screen is too narrow for all the columns to be dis-
played. The compressed output doesn’t matter because the only thing you want at 
this point is the job’s 
ID
:
PS (10) > Start-Job $jsb
WARNING: column "Command" does not fit into the display and was 
removed.
Id              Name            State      HasMoreData     Locat
ion 
--              ----            -----      -----------     -----
              Job5            Running    True            lo...
Start calling 
Receive-Job
with the job’s 
ID
:
PS (11) > Receive-Job 5 
i is 1 
i is 2
The first call returned the first two items out of the 10 you’re expecting. Call it again
PS (12) > Receive-Job 5 
i is 3 
i is 4
and you get another two items. Call it again quickly
PS (13) > Receive-Job 5 
i is 5
and you get one additional item. Keep calling it until you get all the items:
PS (14) > Receive-Job 5 
i is 6 
i is 7 
PS (15) > Receive-Job 5 
i is 8 
PS (16) > Receive-Job 5 
i is 9 
PS (17) > Receive-Job 5 
i is 10 
PS (18) > Receive-Job 5
This last call didn’t return anything because the job has completed and all items have 
already been returned. You can verify this by calling 
Get-Job
PS (19) > Get-Job 5
WARNING: column "Command" does not fit into the display and was 
removed.
486
CHAPTER 12
R
EMOTING
AND
BACKGROUND
JOBS
Id              Name            State      HasMoreData     Locat
ion 
--              ----            -----      -----------     -----
              Job5            Completed  False           lo...
and you see that its state is 
Completed
. Because the job is running asynchronously, 
the number of items that are returned depends on when you call 
Receive-Job
.
Waiting for jobs to complete
So how do you wait until the job has completed? You could write a loop to keep 
checking the 
State
property, but that would be annoying and inefficient. Instead, 
you can use the 
Wait-Job
cmdlet:
PS (21) > $jb = Start-Job $jsb; Wait-Job $jb ; Receive-Job $jb
Id              Name            State      HasMoreData     Locat
ion 
--              ----            -----      -----------     -----
              Job9            Completed  True            lo... 
i is 1 
i is 2 
i is 3 
i is 4 
i is 5 
i is 6 
i is 7 
i is 8 
i is 9 
i is 10
In this example, you’re capturing the job object emitted by 
Start-Job
in the 
$jb 
variable so you can use it in the subsequent 
Wait-Job
and 
Receive-Job
commands. 
Because of the 
Wait-Job
, when you call 
Receive-Job
you get all the input.
Notice that 
Wait-Job
returns the object representing the job that has finished. 
You can use this to simplify the example a bit:
PS (22) > Start-Job $jsb | Wait-Job | Receive-Job 
i is 1 
i is 2 
i is 3 
i is 4 
i is 5 
i is 6 
i is 7 
i is 8 
i is 9 
i is 10
In this example, 
Start-Job
passes the 
Job
object to 
Wait-Job
. When the job com-
pletes, 
Wait-Job
passes the 
Job
object to 
Receive-Job
to get the results. This elim-
inates the need for an intermediate variable.
B
ACKGROUND
JOBS
IN
P
OWER
S
HELL
487
Removing jobs
So far, you’ve been creating jobs but haven’t removed any. This means that when you 
call 
Get-Job
, you’ll see that there are a number of jobs still in the job table:
PS (23) > Get-Job
WARNING: column "Command" does not fit into the display and was 
removed.
Id              Name            State      HasMoreData     Locat
ion 
--              ----            -----      -----------     -----
              Job1            Completed  False           lo...
              Job3            Completed  False           lo...
              Job5            Completed  False           lo...
              Job7            Completed  True            lo...
              Job9            Completed  False           lo...
Each time you start a job, it gets added to the job table. You can clean things up using 
the 
Remove-Job
cmdlet. To empty the table, use 
Remove-Job
with a wildcard:
PS (24) > Remove-Job *
Now when you call 
Get-Job
, nothing is returned:
PS (25) > Get-Job
PS (26) >
This is probably not the best way to clean things up. A better solution would be to 
look for jobs that have completed and have no more data. This would look like the 
following:
function Clear-CompletedJobs {
Get-Job | where { $_.State -eq "Completed" -and
-not $_.HasMoreData } | Remove-Job 
}
This function calls 
Get-Job
to get the list of all jobs, filters that list based on the 
State
and 
HasMoreData
properties, and then pipes the filtered list into 
Remove-
Job
. By doing this, only completed jobs for which all data has been received will be 
removed. This allows you to clean up the job table without worrying about losing 
information or getting errors. If you do want to kill all of the jobs immediately, you 
can use the 
-Force
parameter on 
Remove-Job
.
In the next section, we’ll look at ways you can apply concurrent jobs to solve 
problems.
12.5.3
Working with multiple jobs
So far we’ve looked at simple patterns working with one job at a time, but you can 
run a number of jobs at the same time. Doing so complicates things—you have to be
488
CHAPTER 12
R
EMOTING
AND
BACKGROUND
JOBS
able to handle the output from multiple jobs. Let’s look at how to do this. The fol-
lowing listing shows how to wait for a set of jobs and then receive the results.
1..5| foreach {
Start-Job -name "job$_" -ScriptBlock {                          
param($number)                                              
$waitTime = Get-Random -min 4 -max 10                       
Start-Sleep -Seconds $waitTime
"Job $number is complete; waited $waitTime"
} -ArgumentList $_ > $null }                                
Wait-Job job* | Receive-Job                                         
This example starts a number of jobs that will run concurrently, waits for all of them 
to complete, and then gets all the results. Run this code and see what happens:
PS (1) > 1..5| foreach { 
>>     Start-Job -name "job$_" -ScriptBlock { 
>>         param($number) 
>>         $waitTime = Get-Random -min 4 -max 10 
>>         Start-Sleep -Seconds $waitTime 
>>         "Job $number is complete; waited $waitTime" 
>>         } -ArgumentList $_ > $null } 
>>
PS (2) > wait-Job job* | Receive-Job 
Job 1 is complete; waited 4 
Job 2 is complete; waited 4 
Job 3 is complete; waited 8 
Job 4 is complete; waited 5 
Job 5 is complete; waited 7
As you can see, all the results are captured, ordered by the job name. Now let’s look at 
a more useful application of this pattern. The following listing shows a function that 
searches multiple directories in parallel looking for a specific pattern.
function Search-FilesInParallel 
{
param (
[parameter(mandatory=$true, position=0)]
$Pattern,
[parameter(mandatory=$true, position=1)]                  
[string[]]
$Path,
[parameter(mandatory=$false)]
$Filter = "*.txt",
[parameter(mandatory=$false)]
[switch]
$Any
)
Listing12.6    Example of running multiple jobs
Listing12.7    A function that searches a collection of folders in parallel
B
ACKGROUND
JOBS
IN
P
OWER
S
HELL
489
$jobid = [guid]::NewGuid().ToString() 
$jobs = foreach ($element in $path)
{
Start-Job -name "$Srch{jobid}" -scriptblock { 
param($pattern, $path, $filter, $any)                      
Get-ChildItem -Path $path -Recurse -Filter $filter
Select-String -list:$any $pattern   
} -ArgumentList $pattern,$element,$filter,$any
}
Wait-Job -any:$any $jobs | Receive-Job  
Remove-Job -force $jobs 
}
This function takes a list of folder paths to search, along with a pattern to search for. 
By default, the function will only search 
TXT
files. It also has a switch, 
-any
, that 
controls how the search is performed. If the switch isn’t specified, all matches from all 
folders will be returned. If it’s specified, only the first match will be returned and the 
remaining incomplete jobs will be canceled.
This function seems like a useful tool. Unfortunately, jobs are implemented by 
creating new processes for each job, and this is an expensive operation—so expensive, 
in fact, that generally it’s much slower than simply searching all the files serially. In 
practice, PowerShell jobs are a way of dealing with latency (the time it takes for an 
operation to return a result) and not throughput (the amount of data that gets pro-
cessed). This is a good trade-off for remote management tasks when you’re talking to 
many machines more or less at once. The amount of data, as you saw in the monitor-
ing example in section 12.2, is frequently not large, and the overall execution time is 
dominated by the time it takes to connect to a remote machine. With that in mind, 
let’s look at how remoting and jobs work together.
12.5.4
Starting jobs on remote computers
Because the job infrastructure is based on the remoting framework, it follows that we 
can also create and manage jobs on remote computers. 
NOTE
To work with remote jobs, remoting must be enabled on the 
remote machine. For local jobs, remoting doesn’t have to be enabled 
because a different communication channel (anonymous pipes) is used 
between the parent session and the child jobs.
The easiest way to do this is to use the 
-AsJob
parameter on 
Invoke-Command
Alternatively, the scriptblock passed to 
Invoke-Command
can call 
Start-Job
explic-
itly. Let’s see how this works.
Child jobs and nesting
So far we’ve talked about 
Job
objects as atomic—one 
Job
object per job. In practice 
it’s a bit more sophisticated than that. There are scenarios when you need to be able
Generate GUID to 
use for job ID
Start search job 
for each path
Pass -any switch 
to Select-String
Wait for any 
or all jobs
Documents you may be interested
Documents you may be interested