1 (изменено: Phoenixxx_Czar, 2023-08-11 20:34:51)

Тема: AHK: Ускорить получение данных из OpenHardwareMonitorLib

На просторах интернета нашел способ получать температуру процессора, но данный способ довольно долго получает данные (у меня это 170-200мс). Как можно оптимизировать процесс?
Так же у меня нагружается процессор на 1.5-2% от такого способа, что не совсем нормально (без этого способа около 0.1-0.2).


loop
{
	start := A_TickCount
	info := getCPUTemp(A_ScriptDir "\OpenHardwareMonitorLib.dll")

	tooltip, % A_TickCount - start "`n`n" info
}

getCPUTemp(OpenHardwareMonitorLib)
{
	static init := false
	static cSharp
	static asm
	static psCode
	static ps

	if (init == false)
	{
		init := true

		cSharp =
		(
		using System.Text;
		using System.Collections.ObjectModel;
		using System.Management.Automation;
		using System.Management.Automation.Runspaces;

		public class ps
		{
			public string RunScript(string scriptText)
			{
				Runspace runspace = RunspaceFactory.CreateRunspace();
				runspace.Open();

				Pipeline pipeline = runspace.CreatePipeline();
				pipeline.Commands.AddScript(scriptText);
				pipeline.Commands.Add("Out-String");

				Collection<PSObject> results = pipeline.Invoke();

				runspace.Close();
				return results[0].ToString();

				/*
				StringBuilder stringBuilder = new StringBuilder();
				foreach (PSObject obj in results)
				{
					stringBuilder.AppendLine(obj.ToString());
				}

				return stringBuilder.ToString();
				*/
			}
		}
		)

		asm := CLR_CompileC#( cSharp, "System.Core.dll | C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Management.Automation\v4.0_3.0.0.0__31bf3856ad364e35\System.Management.Automation.dll" )
		ps := asm.CreateInstance("ps")
		psCode =
		(
		[Reflection.Assembly]::LoadFile("%OpenHardwareMonitorLib%") | Out-Null
		$Comp = New-Object -TypeName OpenHardwareMonitor.Hardware.Computer
		$Comp.Open()
		$Comp.CPUEnabled = $true
		ForEach ($HW in $Comp.Hardware) {
		$HW.Update()
			If ($hw.HardwareType -eq "CPU"){
				ForEach ($Sensor in $HW.Sensors) {
				If ($Sensor.SensorType -eq "Temperature"){
					$Sensor.Value.ToString()
					break
				}
			}
			}
			# $hw.Sensors
			$hw.SubHardware
		}
		$Comp.Close()
		)
	}

	return ps.RunScript(psCode)
}


; ==========================================================
;                  .NET Framework Interop
;      https://autohotkey.com/boards/viewtopic.php?t=4633
; ==========================================================
;
;   Author:     Lexikos
;   Version:    1.2
;   Requires:	AutoHotkey_L v1.0.96+
;

CLR_LoadLibrary(AssemblyName, AppDomain=0)
{
	if !AppDomain
		AppDomain := CLR_GetDefaultDomain()
	e := ComObjError(0)
	Loop 1 {
		if assembly := AppDomain.Load_2(AssemblyName)
			break
		static null := ComObject(13,0)
		args := ComObjArray(0xC, 1),  args[0] := AssemblyName
		typeofAssembly := AppDomain.GetType().Assembly.GetType()
		if assembly := typeofAssembly.InvokeMember_3("LoadWithPartialName", 0x158, null, null, args)
			break
		if assembly := typeofAssembly.InvokeMember_3("LoadFrom", 0x158, null, null, args)
			break
	}
	ComObjError(e)
	return assembly
}

CLR_CreateObject(Assembly, TypeName, Args*)
{
	if !(argCount := Args.MaxIndex())
		return Assembly.CreateInstance_2(TypeName, true)

	vargs := ComObjArray(0xC, argCount)
	Loop % argCount
		vargs[A_Index-1] := Args[A_Index]

	static Array_Empty := ComObjArray(0xC,0), null := ComObject(13,0)

	return Assembly.CreateInstance_3(TypeName, true, 0, null, vargs, null, Array_Empty)
}

CLR_CompileC#(Code, References="", AppDomain=0, FileName="", CompilerOptions="")
{
	return CLR_CompileAssembly(Code, References, "System", "Microsoft.CSharp.CSharpCodeProvider", AppDomain, FileName, CompilerOptions)
}

CLR_CompileVB(Code, References="", AppDomain=0, FileName="", CompilerOptions="")
{
	return CLR_CompileAssembly(Code, References, "System", "Microsoft.VisualBasic.VBCodeProvider", AppDomain, FileName, CompilerOptions)
}

CLR_StartDomain(ByRef AppDomain, BaseDirectory="")
{
	static null := ComObject(13,0)
	args := ComObjArray(0xC, 5), args[0] := "", args[2] := BaseDirectory, args[4] := ComObject(0xB,false)
	AppDomain := CLR_GetDefaultDomain().GetType().InvokeMember_3("CreateDomain", 0x158, null, null, args)
	return A_LastError >= 0
}

CLR_StopDomain(ByRef AppDomain)
{	; ICorRuntimeHost::UnloadDomain
	DllCall("SetLastError", "uint", hr := DllCall(NumGet(NumGet(0+RtHst:=CLR_Start())+20*A_PtrSize), "ptr", RtHst, "ptr", ComObjValue(AppDomain))), AppDomain := ""
	return hr >= 0
}

; NOTE: IT IS NOT NECESSARY TO CALL THIS FUNCTION unless you need to load a specific version.
CLR_Start(Version="") ; returns ICorRuntimeHost*
{
	static RtHst := 0
	; The simple method gives no control over versioning, and seems to load .NET v2 even when v4 is present:
	; return RtHst ? RtHst : (RtHst:=COM_CreateObject("CLRMetaData.CorRuntimeHost","{CB2F6722-AB3A-11D2-9C40-00C04FA30A3E}"), DllCall(NumGet(NumGet(RtHst+0)+40),"uint",RtHst))
	if RtHst
		return RtHst
	EnvGet SystemRoot, SystemRoot
	if Version =
		Loop % SystemRoot "\Microsoft.NET\Framework" (A_PtrSize=8?"64":"") "\*", 2
			if (FileExist(A_LoopFileFullPath "\mscorlib.dll") && A_LoopFileName > Version)
				Version := A_LoopFileName
	if DllCall("mscoree\CorBindToRuntimeEx", "wstr", Version, "ptr", 0, "uint", 0
	, "ptr", CLR_GUID(CLSID_CorRuntimeHost, "{CB2F6723-AB3A-11D2-9C40-00C04FA30A3E}")
	, "ptr", CLR_GUID(IID_ICorRuntimeHost,  "{CB2F6722-AB3A-11D2-9C40-00C04FA30A3E}")
	, "ptr*", RtHst) >= 0
		DllCall(NumGet(NumGet(RtHst+0)+10*A_PtrSize), "ptr", RtHst) ; Start
	return RtHst
}

;
; INTERNAL FUNCTIONS
;

CLR_GetDefaultDomain()
{
	static defaultDomain := 0
	if !defaultDomain
	{	; ICorRuntimeHost::GetDefaultDomain
		if DllCall(NumGet(NumGet(0+RtHst:=CLR_Start())+13*A_PtrSize), "ptr", RtHst, "ptr*", p:=0) >= 0
			defaultDomain := ComObject(p), ObjRelease(p)
	}
	return defaultDomain
}

CLR_CompileAssembly(Code, References, ProviderAssembly, ProviderType, AppDomain=0, FileName="", CompilerOptions="")
{
	if !AppDomain
		AppDomain := CLR_GetDefaultDomain()

	if !(asmProvider := CLR_LoadLibrary(ProviderAssembly, AppDomain))
	|| !(codeProvider := asmProvider.CreateInstance(ProviderType))
	|| !(codeCompiler := codeProvider.CreateCompiler())
		return 0

	if !(asmSystem := (ProviderAssembly="System") ? asmProvider : CLR_LoadLibrary("System", AppDomain))
		return 0

	; Convert | delimited list of references into an array.
	StringSplit, Refs, References, |, %A_Space%%A_Tab%
	aRefs := ComObjArray(8, Refs0)
	Loop % Refs0
		aRefs[A_Index-1] := Refs%A_Index%

	; Set parameters for compiler.
	prms := CLR_CreateObject(asmSystem, "System.CodeDom.Compiler.CompilerParameters", aRefs)
	, prms.OutputAssembly          := FileName
	, prms.GenerateInMemory        := FileName=""
	, prms.GenerateExecutable      := SubStr(FileName,-3)=".exe"
	, prms.CompilerOptions         := CompilerOptions
	, prms.IncludeDebugInformation := true

	; Compile!
	compilerRes := codeCompiler.CompileAssemblyFromSource(prms, Code)

	if error_count := (errors := compilerRes.Errors).Count
	{
		error_text := ""
		Loop % error_count
			error_text .= ((e := errors.Item[A_Index-1]).IsWarning ? "Warning " : "Error ") . e.ErrorNumber " on line " e.Line ": " e.ErrorText "`n`n"
		MsgBox, 16, Compilation Failed, %error_text%
		return 0
	}
	; Success. Return Assembly object or path.
	return compilerRes[FileName="" ? "CompiledAssembly" : "PathToAssembly"]
}

CLR_GUID(ByRef GUID, sGUID)
{
	VarSetCapacity(GUID, 16, 0)
	return DllCall("ole32\CLSIDFromString", "wstr", sGUID, "ptr", &GUID) >= 0 ? &GUID : ""
}
Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

2

Re: AHK: Ускорить получение данных из OpenHardwareMonitorLib

По всей видимости надо скомпилировать код. На офф форуме где то есть ветка про машинный код, давно как то пробовал, вроде не сложно.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

3 (изменено: Phoenixxx_Czar, 2023-08-12 13:03:30)

Re: AHK: Ускорить получение данных из OpenHardwareMonitorLib

Какой именно код?
UPD: Я попробовал скомпилировать предоставленный код и он работает довольно быстро (60-80мс, что вполне меня устраивает). Но что меня явно не устраивает - нагрузка на процессор. С опросом каждые 1000мс, я получаю нагрузку 0.6-0.7. Это довольно много.
Ну и потребление 23.5MB оперативной памяти.. тоже как-то многовато)

Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

4

Re: AHK: Ускорить получение данных из OpenHardwareMonitorLib

Phoenixxx_Czar пишет:

Какой именно код?

Код С++ в машинный код.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

5

Re: AHK: Ускорить получение данных из OpenHardwareMonitorLib

Но это только предположение, могу быть не прав.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

6

Re: AHK: Ускорить получение данных из OpenHardwareMonitorLib

Phoenixxx_Czar пишет:

Как можно оптимизировать процесс?

Вынести из цикла то, что требуется делать только один раз. Наверняка там есть такое. Компиляция там какая-то происходит — неужели её нужно выполнять заново каждую итерацию цикла?

7

Re: AHK: Ускорить получение данных из OpenHardwareMonitorLib

Так в последующие вызовы функции выполняется только "ps.RunScript(psCode)", или я не так вас понял?

Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

8

Re: AHK: Ускорить получение данных из OpenHardwareMonitorLib

А, ну тогда не знаю. Что можно сделать с одной командой?

Phoenixxx_Czar пишет:

С опросом каждые 1000мс, я получаю нагрузку 0.6-0.7. Это довольно много.

0,6-0,7% ? Шутите? Вообще-то любой код нагружает процессор, т.к. он его и выполняет.

9

Re: AHK: Ускорить получение данных из OpenHardwareMonitorLib

Да, но не настолько много. Без этого опроса температуры у меня скрипт нагружает где-то 0.1%.

Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

10

Re: AHK: Ускорить получение данных из OpenHardwareMonitorLib

А сколько должен добавлять опрос температуры? И почему именно столько?

11

Re: AHK: Ускорить получение данных из OpenHardwareMonitorLib

У меня есть опрос температур видеокарты, там же оно выдает и нагрузку на видеокарту. Так же опрос нагрузки на процессор и это все в сумме нагружало на 0.1%. Так что я не думаю, что опрос температур процессора должен быть настолько затратным.

Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

12

Re: AHK: Ускорить получение данных из OpenHardwareMonitorLib

Для вызова в цикле весь код повторять не надо.
Достаточно этой части:

		ForEach ($HW in $Comp.Hardware) {
		$HW.Update()
			If ($hw.HardwareType -eq "CPU"){
				ForEach ($Sensor in $HW.Sensors) {
				If ($Sensor.SensorType -eq "Temperature"){
					$Sensor.Value.ToString()
					break
				}
			}
			}
			# $hw.Sensors
			$hw.SubHardware
		}

Как это проделать через c# не знаю, а копаться неинтересно.
Как вариант можно попробовать запускать powershell через com:
https://www.autoitscript.com/forum/topi … com-files/

13

Re: AHK: Ускорить получение данных из OpenHardwareMonitorLib

Ну или запускать OpenHardwareMonitor.exe и через wmi доставать.

14

Re: AHK: Ускорить получение данных из OpenHardwareMonitorLib

Такой вариант выдает результат только при первом вызове, что не так?


getCPUTemp(OpenHardwareMonitorLib)
{
	static init := false
	static cSharp
	static asm
	static psCode
	static ps

	if (init == false)
	{
		init := true

		cSharp =
		(
		using System.Text;
		using System.Collections.ObjectModel;
		using System.Management.Automation;
		using System.Management.Automation.Runspaces;

		public class ps
		{
			public string RunScript(string scriptText)
			{
				Runspace runspace = RunspaceFactory.CreateRunspace();
				runspace.Open();

				Pipeline pipeline = runspace.CreatePipeline();
				pipeline.Commands.AddScript(scriptText);
				pipeline.Commands.Add("Out-String");

				Collection<PSObject> results = pipeline.Invoke();

				runspace.Close();
				return results[0].ToString();

				/*
				StringBuilder stringBuilder = new StringBuilder();
				foreach (PSObject obj in results)
				{
					stringBuilder.AppendLine(obj.ToString());
				}

				return stringBuilder.ToString();
				*/
			}
		}
		)

		asm := CLR_CompileC#( cSharp, "System.Core.dll | " A_WinDir "\Microsoft.NET\assembly\GAC_MSIL\System.Management.Automation\v4.0_3.0.0.0__31bf3856ad364e35\System.Management.Automation.dll" )
		ps := asm.CreateInstance("ps")
		psCode =
		(
		[Reflection.Assembly]::LoadFile("%OpenHardwareMonitorLib%") | Out-Null
		$Comp = New-Object -TypeName OpenHardwareMonitor.Hardware.Computer
		$Comp.Open()
		$Comp.CPUEnabled = $true
		ForEach ($HW in $Comp.Hardware)
		{
			$HW.Update()
			If ($hw.HardwareType -eq "CPU")
			{
				ForEach ($Sensor in $HW.Sensors)
				{
					If ($Sensor.SensorType -eq "Temperature")
					{
						$Sensor.Value.ToString()
						break
					}
				}
			}
			# $hw.Sensors
			$hw.SubHardware
		}
		$Comp.Close()
		)
	}
	else
	{
		psCode =
		(
		ForEach ($HW in $Comp.Hardware)
		{
			$HW.Update()
			If ($hw.HardwareType -eq "CPU")
			{
				ForEach ($Sensor in $HW.Sensors)
				{
					If ($Sensor.SensorType -eq "Temperature")
					{
						$Sensor.Value.ToString()
						break
					}
				}
			}
			# $hw.Sensors
			$hw.SubHardware
		}
		)
	}

	return ps.RunScript(psCode)
}
Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

15

Re: AHK: Ускорить получение данных из OpenHardwareMonitorLib

Во-первых, $Comp.Close() закрывать не надо.
Во-вторых, повершеловские объекты не сохраняются между вызовами.

16

Re: AHK: Ускорить получение данных из OpenHardwareMonitorLib

Так а как тогда сделать это?

Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

17 (изменено: Malcev, 2023-08-12 17:37:52)

Re: AHK: Ускорить получение данных из OpenHardwareMonitorLib

Читайте 12, 13 сообщения.

18

Re: AHK: Ускорить получение данных из OpenHardwareMonitorLib

Ну в остальных вариантах я не смогу разобраться. Увы. Спасибо за помощь.

Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

19 (изменено: Alectric, 2023-08-13 08:41:05)

Re: AHK: Ускорить получение данных из OpenHardwareMonitorLib

Что-то странная библиотека какая-то. https://learn.microsoft.com/ru-ru/dotne … net-latest

Этот класс подключается к работающему экземпляру OpenHardwareMonitor и считывает все доступные значения. Это работает только в том случае, если openHardwareMonitor (https://openhardwaremonitor.org/) запущен в данный момент. Хотя средство должно выполняться с повышенными разрешениями, приложение, использующее эту привязку, этого не делает.

У меня код из первого поста показывает только время, температуру не показывает (скачал новую версию - начал показывать). При запуске приложения OptenHWMonitor время уменьшается.
Ещё заметил что в папке со скриптом постоянно создается и удаляется файл OpenHardwareMonitor.sys.

Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

20 (изменено: Alectric, 2023-08-13 09:05:08)

Re: AHK: Ускорить получение данных из OpenHardwareMonitorLib

Попробуй так:

getCPUTemp(OpenHardwareMonitorLib)
{
	static init := false
	static cSharp
	static asm
	static psCode
	static ps

	if (init == false)
	{
		init := true

		cSharp =
		(
		using System.Text;
		using System.Collections.ObjectModel;
		using System.Management.Automation;
		using System.Management.Automation.Runspaces;

		public class ps
		{
			public string RunScript(string scriptText)
			{
				Runspace runspace = RunspaceFactory.CreateRunspace();
				runspace.Open();

				Pipeline pipeline = runspace.CreatePipeline();
				pipeline.Commands.AddScript(scriptText);
				pipeline.Commands.Add("Out-String");

				Collection<PSObject> results = pipeline.Invoke();

				runspace.Close();
				return results[0].ToString();

				/*
				StringBuilder stringBuilder = new StringBuilder();
				foreach (PSObject obj in results)
				{
					stringBuilder.AppendLine(obj.ToString());
				}

				return stringBuilder.ToString();
				*/
			}
		}
		)

		asm := CLR_CompileC#( cSharp, "System.Core.dll | C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Management.Automation\v4.0_3.0.0.0__31bf3856ad364e35\System.Management.Automation.dll" )
		ps := asm.CreateInstance("ps")
		psCode =
		(
if ($Comp.CPUEnabled -ne $true)
{
		[Reflection.Assembly]::LoadFile("%OpenHardwareMonitorLib%") | Out-Null
		$Comp = New-Object -TypeName OpenHardwareMonitor.Hardware.Computer
		$Comp.Open()
		$Comp.CPUEnabled = $true
}
		ForEach ($HW in $Comp.Hardware) {
		$HW.Update()
			If ($hw.HardwareType -eq "CPU"){
				ForEach ($Sensor in $HW.Sensors) {
				If ($Sensor.SensorType -eq "Temperature"){
					$Sensor.Value.ToString()
					break
				}
			}
			}
			# $hw.Sensors
			$hw.SubHardware
		}
		)
	}

	return ps.RunScript(psCode)
}

OFF: У PowerShell вырвиглазный синтаксис.

Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

21

Re: AHK: Ускорить получение данных из OpenHardwareMonitorLib

Нужно еще как-то $Comp.Close() вызывать при закрытии скрипта.

Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

22 (изменено: Alectric, 2023-08-13 09:32:56)

Re: AHK: Ускорить получение данных из OpenHardwareMonitorLib

Итоги тыканья пальцем в небо:



onexit,exit

loop
{
	start := A_TickCount
	info := getCPUTemp(A_ScriptDir "\OpenHardwareMonitorLib.dll")

	tooltip, % A_TickCount - start "`n`n" info
}

exit:
esc::
getCPUTemp(A_ScriptDir "\OpenHardwareMonitorLib.dll",true)
exitapp

getCPUTemp(OpenHardwareMonitorLib, close=false)
{
	static init := false
	static cSharp
	static asm
	static psCode
	static ps

	if (init == false)
	{
		init := true

		cSharp =
		(
		using System.Text;
		using System.Collections.ObjectModel;
		using System.Management.Automation;
		using System.Management.Automation.Runspaces;

		public class ps
		{
			public string RunScript(string scriptText)
			{
				Runspace runspace = RunspaceFactory.CreateRunspace();
				runspace.Open();

				Pipeline pipeline = runspace.CreatePipeline();
				pipeline.Commands.AddScript(scriptText);
				pipeline.Commands.Add("Out-String");

				Collection<PSObject> results = pipeline.Invoke();

				runspace.Close();
				return results[0].ToString();

				/*
				StringBuilder stringBuilder = new StringBuilder();
				foreach (PSObject obj in results)
				{
					stringBuilder.AppendLine(obj.ToString());
				}

				return stringBuilder.ToString();
				*/
			}
		}
		)

		asm := CLR_CompileC#( cSharp, "System.Core.dll | C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Management.Automation\v4.0_3.0.0.0__31bf3856ad364e35\System.Management.Automation.dll" )
		ps := asm.CreateInstance("ps")
		psCode =
		(
if ($Comp.CPUEnabled -ne $true)
{
		[Reflection.Assembly]::LoadFile("%OpenHardwareMonitorLib%") | Out-Null
		$Comp = New-Object -TypeName OpenHardwareMonitor.Hardware.Computer
		$Comp.Open()
		$Comp.CPUEnabled = $true
}
		ForEach ($HW in $Comp.Hardware) {
		$HW.Update()
			If ($hw.HardwareType -eq "CPU"){
				ForEach ($Sensor in $HW.Sensors) {
				If ($Sensor.SensorType -eq "Temperature"){
					$Sensor.Value.ToString()
					break
				}
			}
			}
			# $hw.Sensors
			$hw.SubHardware
		}
		)
	}
if close
{
  psCode .="`n$Comp.Close()"
}
	return ps.RunScript(psCode)
}


; ==========================================================
;                  .NET Framework Interop
;      https://autohotkey.com/boards/viewtopic.php?t=4633
; ==========================================================
;
;   Author:     Lexikos
;   Version:    1.2
;   Requires:	AutoHotkey_L v1.0.96+
;

CLR_LoadLibrary(AssemblyName, AppDomain=0)
{
	if !AppDomain
		AppDomain := CLR_GetDefaultDomain()
	e := ComObjError(0)
	Loop 1 {
		if assembly := AppDomain.Load_2(AssemblyName)
			break
		static null := ComObject(13,0)
		args := ComObjArray(0xC, 1),  args[0] := AssemblyName
		typeofAssembly := AppDomain.GetType().Assembly.GetType()
		if assembly := typeofAssembly.InvokeMember_3("LoadWithPartialName", 0x158, null, null, args)
			break
		if assembly := typeofAssembly.InvokeMember_3("LoadFrom", 0x158, null, null, args)
			break
	}
	ComObjError(e)
	return assembly
}

CLR_CreateObject(Assembly, TypeName, Args*)
{
	if !(argCount := Args.MaxIndex())
		return Assembly.CreateInstance_2(TypeName, true)

	vargs := ComObjArray(0xC, argCount)
	Loop % argCount
		vargs[A_Index-1] := Args[A_Index]

	static Array_Empty := ComObjArray(0xC,0), null := ComObject(13,0)

	return Assembly.CreateInstance_3(TypeName, true, 0, null, vargs, null, Array_Empty)
}

CLR_CompileC#(Code, References="", AppDomain=0, FileName="", CompilerOptions="")
{
	return CLR_CompileAssembly(Code, References, "System", "Microsoft.CSharp.CSharpCodeProvider", AppDomain, FileName, CompilerOptions)
}

CLR_CompileVB(Code, References="", AppDomain=0, FileName="", CompilerOptions="")
{
	return CLR_CompileAssembly(Code, References, "System", "Microsoft.VisualBasic.VBCodeProvider", AppDomain, FileName, CompilerOptions)
}

CLR_StartDomain(ByRef AppDomain, BaseDirectory="")
{
	static null := ComObject(13,0)
	args := ComObjArray(0xC, 5), args[0] := "", args[2] := BaseDirectory, args[4] := ComObject(0xB,false)
	AppDomain := CLR_GetDefaultDomain().GetType().InvokeMember_3("CreateDomain", 0x158, null, null, args)
	return A_LastError >= 0
}

CLR_StopDomain(ByRef AppDomain)
{	; ICorRuntimeHost::UnloadDomain
	DllCall("SetLastError", "uint", hr := DllCall(NumGet(NumGet(0+RtHst:=CLR_Start())+20*A_PtrSize), "ptr", RtHst, "ptr", ComObjValue(AppDomain))), AppDomain := ""
	return hr >= 0
}

; NOTE: IT IS NOT NECESSARY TO CALL THIS FUNCTION unless you need to load a specific version.
CLR_Start(Version="") ; returns ICorRuntimeHost*
{
	static RtHst := 0
	; The simple method gives no control over versioning, and seems to load .NET v2 even when v4 is present:
	; return RtHst ? RtHst : (RtHst:=COM_CreateObject("CLRMetaData.CorRuntimeHost","{CB2F6722-AB3A-11D2-9C40-00C04FA30A3E}"), DllCall(NumGet(NumGet(RtHst+0)+40),"uint",RtHst))
	if RtHst
		return RtHst
	EnvGet SystemRoot, SystemRoot
	if Version =
		Loop % SystemRoot "\Microsoft.NET\Framework" (A_PtrSize=8?"64":"") "\*", 2
			if (FileExist(A_LoopFileFullPath "\mscorlib.dll") && A_LoopFileName > Version)
				Version := A_LoopFileName
	if DllCall("mscoree\CorBindToRuntimeEx", "wstr", Version, "ptr", 0, "uint", 0
	, "ptr", CLR_GUID(CLSID_CorRuntimeHost, "{CB2F6723-AB3A-11D2-9C40-00C04FA30A3E}")
	, "ptr", CLR_GUID(IID_ICorRuntimeHost,  "{CB2F6722-AB3A-11D2-9C40-00C04FA30A3E}")
	, "ptr*", RtHst) >= 0
		DllCall(NumGet(NumGet(RtHst+0)+10*A_PtrSize), "ptr", RtHst) ; Start
	return RtHst
}

;
; INTERNAL FUNCTIONS
;

CLR_GetDefaultDomain()
{
	static defaultDomain := 0
	if !defaultDomain
	{	; ICorRuntimeHost::GetDefaultDomain
		if DllCall(NumGet(NumGet(0+RtHst:=CLR_Start())+13*A_PtrSize), "ptr", RtHst, "ptr*", p:=0) >= 0
			defaultDomain := ComObject(p), ObjRelease(p)
	}
	return defaultDomain
}

CLR_CompileAssembly(Code, References, ProviderAssembly, ProviderType, AppDomain=0, FileName="", CompilerOptions="")
{
	if !AppDomain
		AppDomain := CLR_GetDefaultDomain()

	if !(asmProvider := CLR_LoadLibrary(ProviderAssembly, AppDomain))
	|| !(codeProvider := asmProvider.CreateInstance(ProviderType))
	|| !(codeCompiler := codeProvider.CreateCompiler())
		return 0

	if !(asmSystem := (ProviderAssembly="System") ? asmProvider : CLR_LoadLibrary("System", AppDomain))
		return 0

	; Convert | delimited list of references into an array.
	StringSplit, Refs, References, |, %A_Space%%A_Tab%
	aRefs := ComObjArray(8, Refs0)
	Loop % Refs0
		aRefs[A_Index-1] := Refs%A_Index%

	; Set parameters for compiler.
	prms := CLR_CreateObject(asmSystem, "System.CodeDom.Compiler.CompilerParameters", aRefs)
	, prms.OutputAssembly          := FileName
	, prms.GenerateInMemory        := FileName=""
	, prms.GenerateExecutable      := SubStr(FileName,-3)=".exe"
	, prms.CompilerOptions         := CompilerOptions
	, prms.IncludeDebugInformation := true

	; Compile!
	compilerRes := codeCompiler.CompileAssemblyFromSource(prms, Code)

	if error_count := (errors := compilerRes.Errors).Count
	{
		error_text := ""
		Loop % error_count
			error_text .= ((e := errors.Item[A_Index-1]).IsWarning ? "Warning " : "Error ") . e.ErrorNumber " on line " e.Line ": " e.ErrorText "`n`n"
		MsgBox, 16, Compilation Failed, %error_text%
		return 0
	}
	; Success. Return Assembly object or path.
	return compilerRes[FileName="" ? "CompiledAssembly" : "PathToAssembly"]
}

CLR_GUID(ByRef GUID, sGUID)
{
	VarSetCapacity(GUID, 16, 0)
	return DllCall("ole32\CLSIDFromString", "wstr", sGUID, "ptr", &GUID) >= 0 ? &GUID : ""
}

Разве нельзя эту библиотеку через DllCall использовать?

Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

23

Re: AHK: Ускорить получение данных из OpenHardwareMonitorLib

serzh82saratov пишет:
Phoenixxx_Czar пишет:

Какой именно код?

Код С++ в машинный код.

Упс, проглядел, там же С#.

Alectric пишет:

Разве нельзя эту библиотеку через DllCall использовать?

Резонный вопрос.
А интересно узнать какие Dll в АНК можно, а какие нет?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

24

Re: AHK: Ускорить получение данных из OpenHardwareMonitorLib

Phoenixxx_Czar пишет:

У меня есть опрос температур видеокарты, там же оно выдает и нагрузку на видеокарту. Так же опрос нагрузки на процессор и это все в сумме нагружало на 0.1%. Так что я не думаю, что опрос температур процессора должен быть настолько затратным.

А что за код, не поделитесь.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

25

Re: AHK: Ускорить получение данных из OpenHardwareMonitorLib

Мне кажется теперь появилась утечка памяти, потребляемая оперативка растет и растет. Скорость получения стала меньше (в районе 60ms), а вот с нагрузкой по прежнему нужно что-то думать.

Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

26

Re: AHK: Ускорить получение данных из OpenHardwareMonitorLib

Есть утилита DLL Export Viewer. Те функции, которые видны через неё, можно вызывать с помощью DllCall.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

27

Re: AHK: Ускорить получение данных из OpenHardwareMonitorLib

У меня ею показывает 0 функций, так и должно быть?

Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

28

Re: AHK: Ускорить получение данных из OpenHardwareMonitorLib

Это же дотнетовская библиотека, как я понимаю. У них там по-своему.

29 (изменено: Alectric, 2023-08-13 16:17:49)

Re: AHK: Ускорить получение данных из OpenHardwareMonitorLib

Phoenixxx_Czar пишет:

Мне кажется теперь появилась утечка памяти, потребляемая оперативка растет и растет.

Странно, у меня оперативка скачет туда сюда но не растет... по крайней мере не замечаю.

Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

30 (изменено: Phoenixxx_Czar, 2023-08-13 16:17:21)

Re: AHK: Ускорить получение данных из OpenHardwareMonitorLib

Согласен, все нормально с оперативкой. Наверное из-за того что оно с 16мб начало расти до 22мб постепенно и я не проследил за этим дальше.
Я так понимаю с нагрузкой на процессор ничего нельзя придумать? Я думаю на более слабых процессорах нагрузка будет куда больше.

Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

31 (изменено: Alectric, 2023-08-13 16:45:05)

Re: AHK: Ускорить получение данных из OpenHardwareMonitorLib

Понаблюдал подольше - да действительно растет.
https://forum.script-coding.com/misc.php?action=pun_attachment&amp;item=2367&amp;download=0

OFF: Вечно я тороплюсь с выводами.

Post's attachments

2023.08.13 17.25.39.031.png 70.73 kb, 12 downloads since 2023-08-13 

You don't have the permssions to download the attachments of this post.
Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

32 (изменено: Alectric, 2023-08-13 16:44:08)

Re: AHK: Ускорить получение данных из OpenHardwareMonitorLib

Получается что это условие не выполняется:

if ($Comp.CPUEnabled -ne $true)

И все переменные создаются заново каждый раз, и так как Close не выполняется - память соответственно не очищается.

Тут нужны знания PowerShell. Ну или костыльный метод: вызывать Close каждые n вызовов функции getCPUTemp.

Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

33

Re: AHK: Ускорить получение данных из OpenHardwareMonitorLib

Тут скорее нужны знания c#.
Создаются переменные или нет можно таким кодом:

if ($Comp.CPUEnabled -ne $true)
{
		Add-Type -AssemblyName PresentationCore,PresentationFramework
		$msgBody = "This is a simple message with just the default OK button"
		[System.Windows.MessageBox]::Show($msgBody)
		[Reflection.Assembly]::LoadFile("%OpenHardwareMonitorLib%") | Out-Null
		$Comp = New-Object -TypeName OpenHardwareMonitor.Hardware.Computer
		$Comp.Open()
		$Comp.CPUEnabled = $true
}

34

Re: AHK: Ускорить получение данных из OpenHardwareMonitorLib

Так еще можно пробовать:
https://www.autohotkey.com/boards/viewt … 37#p341237

35 (изменено: Alectric, 2023-08-13 17:38:44)

Re: AHK: Ускорить получение данных из OpenHardwareMonitorLib

Malcev пишет:

Создаются переменные или нет можно таким кодом:

Да создаются каждую итерацию.
about_Variables

Самый оптимальный по скорости вариант это перекомпиляция библиотеки с "COMVISIBLE = true".
https://www.autoitscript.com/forum/topi … m-problem/

Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

36 (изменено: Phoenixxx_Czar, 2023-08-18 20:39:25)

Re: AHK: Ускорить получение данных из OpenHardwareMonitorLib

Я перенес код на C# и процессор так же сильно нагружается. Эх..
UPD: Нагружается только, если собран, если запустить из редактора - все хорошо.

Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

37

Re: AHK: Ускорить получение данных из OpenHardwareMonitorLib

Тестируйте ее форк LibreHardwareMonitorLib.

38 (изменено: Malcev, 2023-08-22 19:45:23)

Re: AHK: Ускорить получение данных из OpenHardwareMonitorLib

Ну и на крайний случай никакой магии в том, что делает LibreHardwareMonitorLib нету.
Она просто через драйвер WinRing0 считывает датчики сенсоров напрямую.
Скомпилированный WinRing0.dll на ahk форуме имеется, осталось покопаться в исходном коде, найти нужные регистры для каждого процессора и можете получать температуру напрямую без каких-либо библиотек.
https://github.com/LibreHardwareMonitor … rdware/Cpu

39

Re: AHK: Ускорить получение данных из OpenHardwareMonitorLib

Как выполнить данный код на ахк?

      driver = new KernelDriver("WinRing0_1_2_0");
      driver.Open();
Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

40

Re: AHK: Ускорить получение данных из OpenHardwareMonitorLib

https://gist.github.com/tmplinshi/d692f … 0-ahk-L297

41

Re: AHK: Ускорить получение данных из OpenHardwareMonitorLib

Malcev пишет:

Тестируйте ее форк LibreHardwareMonitorLib.

Я уже давно нашел и его, но мне он не подходит, он не видит мою видеокарту (хотя в их програмке все видно). А жаль, ведь потестив на нескольких системах, он выдает больше информации.

Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

42

Re: AHK: Ускорить получение данных из OpenHardwareMonitorLib

Для видеокарт есть официальные апи - LibreHardwareMonitorLib не нужен.
Если для себя делать, я бы посмотрел нужные мне регистры в c# исходнике и перевел бы код с c++:
https://www.twblogs.net/a/5b83c8862b71777cb15c0a69
А если для разных процессоров, то только платно и дорого.

43

Re: AHK: Ускорить получение данных из OpenHardwareMonitorLib

Ну в идеале я бы хотел, чтобы работало на различных устройствах, чтобы кто-то мог что-то переделать под себя. Но в целом для себя, да.

Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)