Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Powershell 在threadjob中使用SetImage_Powershell - Fatal编程技术网

Powershell 在threadjob中使用SetImage

Powershell 在threadjob中使用SetImage,powershell,Powershell,我有一个将图片插入PPT的功能,包括以下代码: $file = get-item($pic); $img = [System.Drawing.Image]::Fromfile($file); [System.Windows.Forms.Clipboard]::SetImage($img); $slide = $pp1.Slides.Item($targetslide) Start-Sleep -Seconds 5 $shape = $Slide.Shapes.PasteSpecia

我有一个将图片插入PPT的功能,包括以下代码:

$file = get-item($pic);
$img = [System.Drawing.Image]::Fromfile($file);



[System.Windows.Forms.Clipboard]::SetImage($img);


$slide = $pp1.Slides.Item($targetslide)

Start-Sleep -Seconds 5

$shape = $Slide.Shapes.PasteSpecial($ppPasteJPG,$false,$null,$null,$null,$null)
但是,我创建了一个使用此函数的函数,并将其放入threadjob的操作脚本中。现在,当它被激活时,会产生错误:

Exception calling "SetImage" with "1" argument(s): "Current thread must be set to single thread apartment (STA) mode before OLE calls can be made. Ensure that your Main function has STAThreadAttribute marked on it."
At C:\...\PicInsertPPT.ps1:17 char:1
+ [System.Windows.Forms.Clipboard]::SetImage($img);
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ThreadStateException
我可以用什么替换该行,它将作为threadjob中的一个任务与多个并行任务一起工作

我正在考虑申请:

CommandBars.ExecuteMso("PictureInsertFromFile")
但我不完全确定如何控制以这种方式插入的图片

编辑:我的threadjob代码是:

Function ThreadMaster{



param ($folder)




$global:folder = $folder



  # Use the system's temp folder in this example.
  $global:dir = $folder

  # Define the tasks as an array of custom objects that specify the dir.
  # and file name pattern to monitor as well as the action script block to 
  # handle the events.
  $tasks = # array of custom objects to describe the 
    [pscustomobject] @{
      DirToMonitor = $dir
      FileNamePattern = '*.csv'
      Action = {
        $path = $EventArgs.FullPath
        $name = $EventArgs.Name
        $changeType = $EventArgs.ChangeType
        $timeStamp = $EventArgs.TimeGenerated




         Write-Host -NoNewLine "`nINFO: Event 1 raised:`n$($EventArgs | Format-List | Out-String)"



        Import-Module C:\...Report1V1.ps1


       $Actionpath = Split-Path $Path



        write-host $Actionpath " Ready for Report1"



       Report1 $Actionpath

       write-host $Actionpath "Report1 Generated"



        "`nEvent 1 output: " + $EventArgs.Fullpath

}
      }
    },
    [pscustomobject] @{
      DirToMonitor = $dir
      FileNamePattern = '*4.4_10X*'
      Action = {
        $path = $Event.SourceEventArgs.FullPath
        $name = $Event.SourceEventArgs.Name
        $changeType = $Event.SourceEventArgs.ChangeType
        $timeStamp = $Event.TimeGenerated

        Write-Host -NoNewLine "`nINFO: Event 2 raised:`n$($EventArgs | Format-List | Out-String)"


        Import-Module C:\...\Report2V1.ps1





      $Actionpath = Split-Path $Path




      $Actionpath = Split-Path $Actionpath








      write-host $Actionpath " Ready for Report2"



      Report2 $Actionpath


      write-host "Report2 Generated" 



        "`nEvent 2 output: " + $EventArgs.Fullpath


      }  
    } 
}
  # Start a separate thread job for each action task.
  $threadJobs = $tasks | ForEach-Object {

    Start-ThreadJob -ArgumentList $_ {

      param([pscustomobject] $task)

      # Create and initialize a thread-specific watcher.
      # Note: To keep system load low, it's generally better to use a *shared* 
      #       watcher, if feasible. You can define it in the caller's scope
      #       and access here via $using:watcher
      $watcher = [System.IO.FileSystemWatcher] [ordered] @{
        Path   = $task.DirToMonitor
        Filter = $task.FileNamePattern
        IncludeSubdirectories = $true
        EnableRaisingEvents = $true # start watching.
        InternalBufferSize = 65536
      }

      # Subscribe to the watcher's Created events, which returns an event job.
      # This indefinitely running job receives the output from the -Action script
      # block whenever the latter is called after an event fires.
      $eventJob = Register-ObjectEvent -ea stop $watcher Created -Action $task.Action

      Write-Host "`nINFO: Watching $($task.DirToMonitor) for creation of $($task.FileNamePattern) files..."

      # Indefinitely wait for output from the action blocks and relay it.
      try {
        while ($true) {
          Receive-Job $eventJob
          Start-Sleep -Milliseconds 500  # sleep a little
        }
      }
      finally { 
         # !! This doesn't print, presumably because this is killed by the
         # !! *caller* being killed, which then doesn't relay the output anymore.
        Write-Host "Cleaning up thread for task $($task.FileNamePattern)..."
        # Dispose of the watcher.
        $watcher.Dispose()
        # Remove the event job (and with it the event subscription).
        $eventJob | Remove-Job -Force 
      }

    }

  }  


  Write-Host "Starting tasks...`nUse Ctrl-C to stop."

  # Indefinitely wait for and display output from the thread jobs.
  # Use Ctrl+C to stop.
  $dtStart = [datetime]::UtcNow
  while ($true) {

    # Receive thread job output, if any.
    $threadJobs | Receive-Job

    # Sleep a little.
    Write-Host . -NoNewline
    Start-Sleep -Milliseconds 500


  }

}

不确定在使用线程作业时是否可以控制单元状态。您可能需要直接使用运行空间重写。你有包含线程作业的函数代码吗?我不太确定你想要代码的哪一部分。我有一个Threadjob,它有两个操作块,一个用于Report1Generator,另一个用于Report2Generator。在Report2Generator中,它调用函数PicInsertPPT。PicInsertPPT的代码显然与多线程不兼容。请放入包含线程作业的代码并抛出此错误,以便人们可以复制、粘贴和复制。无论如何,您需要做的是用自定义运行空间替换线程作业,并将其单元状态设置为STA。在那里,我添加了它
powershell.exe-STA