答案 0 :(得分:3)
我不清楚是否可以设置IO优先级。 SetProcessInformation()调用将PROCESS_INFORMATION_CLASS作为参数,并且仅定义ProcessMemoryPriority。我遇到的问题是PowerShell脚本用完了任务管理器,内存优先级为2,这让我很伤心。我是PInvoke的新手并且在PowerShell中使用它,所以我可能违反了至少一个最佳做法,但下面的代码解决了我的问题。
通过C#加载函数的Add-Type:
Add-Type @"
using System;
using System.Runtime.InteropServices;
namespace SysWin32
{
public enum PROCESS_INFORMATION_CLASS
{
ProcessMemoryPriority,
ProcessInformationClassMax,
}
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct MEMORY_PRIORITY_INFORMATION
{
public uint MemoryPriority;
}
public partial class NativeMethods {
[System.Runtime.InteropServices.DllImportAttribute("kernel32.dll", EntryPoint="GetCurrentProcess")]
public static extern System.IntPtr GetCurrentProcess();
[System.Runtime.InteropServices.DllImportAttribute("kernel32.dll", EntryPoint="SetProcessInformation")]
public static extern bool SetProcessInformation(System.IntPtr hProcess, PROCESS_INFORMATION_CLASS ProcessInformationClass, System.IntPtr ProcessInformation, uint ProcessInformationSize) ;
}
}
"@
以下是使用函数的示例:
$myProcessHandle = [SysWin32.NativeMethods]::GetCurrentProcess()
$memInfo = New-Object SysWin32.MEMORY_PRIORITY_INFORMATION
$memInfo.MemoryPriority = 5
$memInfoSize = [System.Runtime.Interopservices.Marshal]::SizeOf($memInfo)
$memInfoPtr = [System.Runtime.Interopservices.Marshal]::AllocHGlobal($memInfoSize)
[System.Runtime.Interopservices.Marshal]::StructureToPtr($memInfo, $memInfoPtr, $false)
$result = [SysWin32.NativeMethods]::SetProcessInformation($myProcessHandle, [SysWin32.PROCESS_INFORMATION_CLASS]::ProcessMemoryPriority, $memInfoPtr, $memInfoSize)
$result
使用procexp我能够验证我的powershell脚本现在正在以5的内存优先级运行。
答案 1 :(得分:1)
这是一个用于降低进程优先级的PowerShell单行程序:
(get-process msosync).PriorityClass='BelowNormal'
在此PowerShell上下文中,PriorityClass的有效值可以是以下值之一:Normal,Idle,High,RealTime,BelowNormal,AboveNormal
您可以使用此单行测试结果:
get-process msosync | Select-Object Name,PriorityClass,CPU | Format-Table -AutoSize
答案 2 :(得分:0)
从Peter Friend's answer above开始,我编写了一个powershell脚本,该脚本更新了所涉及的所有3个优先级(CPU,内存和IO)。我将其张贴在这里,因为这是该问题在Google中排名第一的结果。
您可以像这样从Powershell运行它-
.\SetProcessPriority.ps1 -ProcessName sqlservr -CpuPriorityClass Idle -MemoryPriority 1 -IoPriority 0
SetProcessPriority.ps1代码-
[CmdletBinding()]
Param (
[string]$ProcessName = "sqlservr",
[string]$CpuPriorityClass = "Idle",
[int]$MemoryPriority = 1,
[int]$IoPriority = 0
)
# If you can't run, execute this first from an elevated PowerShell Prompt - set-executionpolicy remotesigned
If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))
{
$arguments = "& '" + $myinvocation.mycommand.definition + "'"
Start-Process powershell -Verb runAs -ArgumentList $arguments
Break
}
Add-Type @"
using System;
using System.Runtime.InteropServices;
namespace SysWin32
{
public enum PROCESS_INFORMATION_CLASS
{
ProcessMemoryPriority,
ProcessInformationClassMax,
}
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct PROCESS_INFORMATION
{
public uint Information;
}
public partial class NativeMethods {
[System.Runtime.InteropServices.DllImportAttribute("kernel32.dll", EntryPoint="GetCurrentProcess", SetLastError=true)]
public static extern System.IntPtr GetCurrentProcess();
[System.Runtime.InteropServices.DllImportAttribute("kernel32.dll", EntryPoint="OpenProcess", SetLastError=true)]
public static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle, uint dwProcessId);
[System.Runtime.InteropServices.DllImportAttribute("kernel32.dll", EntryPoint="SetProcessInformation", SetLastError=true)]
public static extern bool SetProcessInformation(System.IntPtr hProcess, PROCESS_INFORMATION_CLASS ProcessInformationClass, System.IntPtr ProcessInformation, uint ProcessInformationSize) ;
}
}
namespace SysWinNT
{
public enum PROCESS_INFORMATION_CLASS
{
ProcessBasicInformation,
ProcessQuotaLimits,
ProcessIoCounters,
ProcessVmCounters,
ProcessTimes,
ProcessBasePriority,
ProcessRaisePriority,
ProcessDebugPort,
ProcessExceptionPort,
ProcessAccessToken,
ProcessLdtInformation,
ProcessLdtSize,
ProcessDefaultHardErrorMode,
ProcessIoPortHandlers, // Note: this is kernel mode only
ProcessPooledUsageAndLimits,
ProcessWorkingSetWatch,
ProcessUserModeIOPL,
ProcessEnableAlignmentFaultFixup,
ProcessPriorityClass,
ProcessWx86Information,
ProcessHandleCount,
ProcessAffinityMask,
ProcessPriorityBoost,
ProcessDeviceMap,
ProcessSessionInformation,
ProcessForegroundInformation,
ProcessWow64Information,
ProcessImageFileName,
ProcessLUIDDeviceMapsEnabled,
ProcessBreakOnTermination,
ProcessDebugObjectHandle,
ProcessDebugFlags,
ProcessHandleTracing,
ProcessIoPriority,
ProcessExecuteFlags,
ProcessTlsInformation,
ProcessCookie,
ProcessImageInformation,
ProcessCycleTime,
ProcessPagePriority,
ProcessInstrumentationCallback,
ProcessThreadStackAllocation,
ProcessWorkingSetWatchEx,
ProcessImageFileNameWin32,
ProcessImageFileMapping,
ProcessAffinityUpdateMode,
ProcessMemoryAllocationMode,
ProcessGroupInformation,
ProcessTokenVirtualizationEnabled,
ProcessConsoleHostProcess,
ProcessWindowInformation,
MaxProcessInfoClass // MaxProcessInfoClass should always be the last enum
}
public partial class NativeMethods {
[System.Runtime.InteropServices.DllImportAttribute("ntdll.dll", EntryPoint="NtSetInformationProcess")]
public static extern int NtSetInformationProcess(System.IntPtr hProcess, PROCESS_INFORMATION_CLASS processInformationClass, System.IntPtr ProcessInformation, uint ProcessInformationSize);
}
}
"@
$OverallResult = 0
$Process = Get-Process $ProcessName
$ProcessId = $Process.id
Try
{
$Process.PriorityClass=$CpuPriorityClass
}
Catch
{
Write-host -BackgroundColor Black -ForegroundColor Red "Error setting process priority - $($_.Exception.Message)"
pause
$OverallResult = 1
exit $OverallResult
}
Write-Host -ForegroundColor Green ("Set CPU piority on {0} ({1}) to be {2}" -f $ProcessName, $ProcessId, $CpuPriorityClass)
# 4096 or 0x1000 = PROCESS_QUERY_LIMITED_INFORMATION
# 1056763 or 0x00101ffb = PROCESS_ALL_ACCESS
$DesiredAccess = 0x00101ffb
$InheritHandle = $false
$hProcess = [SysWin32.NativeMethods]::OpenProcess($DesiredAccess, $InheritHandle, $ProcessId);
$LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()
if ($hProcess -eq 0)
{
Write-Host -BackgroundColor Black -ForegroundColor Red "Failed to open Win32 process. Error: $(([ComponentModel.Win32Exception] $LastError).Message)"
pause
$OverallResult = 2
exit $OverallResult
}
Write-Host -ForegroundColor Green ("Successfully got handle - {0}" -f $hProcess)
$memInfo = New-Object SysWin32.PROCESS_INFORMATION
$memInfo.Information = $MemoryPriority
$memInfoSize = [System.Runtime.Interopservices.Marshal]::SizeOf($memInfo)
$memInfoPtr = [System.Runtime.Interopservices.Marshal]::AllocHGlobal($memInfoSize)
[System.Runtime.Interopservices.Marshal]::StructureToPtr($memInfo, $memInfoPtr, $false)
$result = [SysWin32.NativeMethods]::SetProcessInformation($hProcess, [SysWin32.PROCESS_INFORMATION_CLASS]::ProcessMemoryPriority, $memInfoPtr, $memInfoSize)
$LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()
if (!$result)
{
$OverallResult = 3
Write-Host -BackgroundColor Black -ForegroundColor Red ("Failed to set memory piority on {0} ({1}) to be {2}. Error: {3}" -f $ProcessName, $ProcessId, $MemoryPriority, ([ComponentModel.Win32Exception]$LastError).Message)
}
else
{
Write-Host -ForegroundColor Green ("Set memory piority on {0} ({1}) to be {2}." -f $ProcessName, $ProcessId, $MemoryPriority)
}
$ioInfo = New-Object SysWin32.PROCESS_INFORMATION
$ioInfo.Information = $IoPriority
$ioInfoSize = [System.Runtime.Interopservices.Marshal]::SizeOf($ioInfo)
$ioInfoPtr = [System.Runtime.Interopservices.Marshal]::AllocHGlobal($ioInfoSize)
[System.Runtime.Interopservices.Marshal]::StructureToPtr($ioInfo, $ioInfoPtr, $false)
$result = [SysWinNT.NativeMethods]::NtSetInformationProcess($hProcess, [SysWinNT.PROCESS_INFORMATION_CLASS]::ProcessIoPriority, $ioInfoPtr, $ioInfoSize)
$LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()
if ($result -ne 0)
{
$OverallResult = 4
Write-Host -BackgroundColor Black -ForegroundColor Red ("Failed to set IO piority on {0} ({1}) to be {2}. Result: {3}. Error: {4}" -f $ProcessName, $ProcessId, $IoPriority, $result, ([ComponentModel.Win32Exception]$LastError).Message)
}
else
{
Write-Host -ForegroundColor Green ("Set IO piority on {0} ({1}) to be {2}" -f $ProcessName, $ProcessId, $IoPriority)
}
exit $OverallResult