Skip to content

Commit 0054572

Browse files
authored
Merge pull request #2 from rotensyo/feature/use-com-uia
UIAによるメモリ増加問題の根本解決
2 parents debf19b + 9cbb94c commit 0054572

27 files changed

Lines changed: 462 additions & 1475 deletions

README.md

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -64,18 +64,12 @@ VoicepeakProxy は、[VOICEPEAK](https://www.ah-soft.com/voice/)の自動読み
6464
using VoicepeakProxyCore;
6565

6666
var config = new AppConfig();
67-
VoicepeakOneShotSession session = VoicepeakOneShot.Start(config);
68-
try
69-
{
70-
SpeakOnceResult result = session.SpeakOnceWait(
71-
new SpeakOnceRequest { Text = "こんにちは。テストです。" });
7267

73-
Console.WriteLine($"status={result.Status} ok={result.Succeeded} segments={result.SegmentsExecuted}");
74-
}
75-
finally
76-
{
77-
session.Dispose();
78-
}
68+
SpeakOnceResult result = VoicepeakOneShot.SpeakOnceWait(
69+
config,
70+
new SpeakOnceRequest { Text = "こんにちは。テストです。" });
71+
72+
Console.WriteLine($"status={result.Status} ok={result.Succeeded} segments={result.SegmentsExecuted}");
7973
```
8074

8175
### 常駐ランタイムAPI使用例

VoicepeakProxyCore.sln

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{0AB3BF05
99
EndProject
1010
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VoicepeakProxyCore.Tests", "core-dll\tests\auto\VoicepeakProxyCore.Tests.csproj", "{EBCD611C-5532-4CB9-AA6E-2EF787F4DAF8}"
1111
EndProject
12-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VoicepeakProxyCore.UiaProbe", "core-dll\uia-probe\VoicepeakProxyCore.UiaProbe.csproj", "{9A77D528-56A0-46A9-B6C4-23BDAF26B66C}"
13-
EndProject
1412
Global
1513
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1614
Debug|x64 = Debug|x64
@@ -25,17 +23,12 @@ Global
2523
{EBCD611C-5532-4CB9-AA6E-2EF787F4DAF8}.Debug|x64.Build.0 = Debug|Any CPU
2624
{EBCD611C-5532-4CB9-AA6E-2EF787F4DAF8}.Release|x64.ActiveCfg = Release|Any CPU
2725
{EBCD611C-5532-4CB9-AA6E-2EF787F4DAF8}.Release|x64.Build.0 = Release|Any CPU
28-
{9A77D528-56A0-46A9-B6C4-23BDAF26B66C}.Debug|x64.ActiveCfg = Debug|Any CPU
29-
{9A77D528-56A0-46A9-B6C4-23BDAF26B66C}.Debug|x64.Build.0 = Debug|Any CPU
30-
{9A77D528-56A0-46A9-B6C4-23BDAF26B66C}.Release|x64.ActiveCfg = Release|Any CPU
31-
{9A77D528-56A0-46A9-B6C4-23BDAF26B66C}.Release|x64.Build.0 = Release|Any CPU
3226
EndGlobalSection
3327
GlobalSection(SolutionProperties) = preSolution
3428
HideSolutionNode = FALSE
3529
EndGlobalSection
3630
GlobalSection(NestedProjects) = preSolution
3731
{EBCD611C-5532-4CB9-AA6E-2EF787F4DAF8} = {0AB3BF05-4346-4AA6-1389-037BE0695223}
38-
{9A77D528-56A0-46A9-B6C4-23BDAF26B66C} = {0AB3BF05-4346-4AA6-1389-037BE0695223}
3932
EndGlobalSection
4033
GlobalSection(ExtensibilityGlobals) = postSolution
4134
SolutionGuid = {4FDFCDEC-60D2-40AB-8E31-8086BFCA761E}

bouyomichan-plugin/Plugin_VoicepeakProxy/PluginSettingFormData.cs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -642,14 +642,6 @@ public string LogMinimumLevel
642642
set { State.Settings.AppConfig.Debug.LogMinimumLevel = (value ?? string.Empty).Trim().ToLowerInvariant(); }
643643
}
644644

645-
[Category("Debug")]
646-
[DisplayName("03)uiaProbeRecycleIntervalSec")]
647-
[Description("UIAサブプロセスの再起動間隔秒です。1以上を指定します。")]
648-
public int UiaProbeRecycleIntervalSec
649-
{
650-
get { return State.Settings.AppConfig.Debug.UiaProbeRecycleIntervalSec; }
651-
set { State.Settings.AppConfig.Debug.UiaProbeRecycleIntervalSec = value; }
652-
}
653645
}
654646

655647
// ファイル選択エディタ共通基底

bouyomichan-plugin/Plugin_VoicepeakProxy/Plugin_VoicepeakProxy.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ private enum WorkerState
3838

3939
public string Name { get { return "VoicepeakProxy for 棒読みちゃん"; } }
4040

41-
public string Version { get { return "2026/04/25版 (core 1.1.0)"; } }
41+
public string Version { get { return "2026/04/29版 (core 1.2.0)"; } }
4242

4343
public string Caption
4444
{

bouyomichan-plugin/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
- 棒読みちゃんプラグイン本体です。
99
- `VoicepeakProxyWorker/`
1010
- `VoicepeakProxyCore.dll` を動かすための補助プロセスです。
11-
- `VoicepeakOneShotSession.SpeakOnceWait(...)` 経由でVOICEPEAK読み上げを実行します。
11+
- `VoicepeakOneShot.SpeakOnceWait(...)` 経由でVOICEPEAK読み上げを実行します。
1212
- `Shared/`
1313
- PluginとWorkerの共通モデルです。
1414

@@ -38,6 +38,7 @@ msbuild "bouyomichan-plugin/Plugin_VoicepeakProxy/Plugin_VoicepeakProxy.csproj"
3838
- `VoicepeakProxyWorker/VoicepeakProxyCore.deps/`
3939
- `EasyHook*`
4040
- `EasyLoad*`
41+
- `Interop.UIAutomationClient*`
4142
- `NAudio*`
4243

4344
## 仕様

bouyomichan-plugin/Shared/PluginSettingsModels.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,6 @@ public sealed class DebugConfigData
248248
// 旧設定互換のため受理するが無視する
249249
public bool LogTextCandidates { get; set; }
250250
public bool LogModifierHookStats { get; set; }
251-
public int UiaProbeRecycleIntervalSec { get; set; }
252251
public string LogMinimumLevel { get; set; }
253252

254253
// 不足項目を既定値で補完

bouyomichan-plugin/VoicepeakProxyWorker/AppConfigMapper.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,6 @@ public static AppConfig Map(AppConfigData source)
9393
config.Runtime.BootValidation = MapBootValidation(data.Runtime.BootValidation, runtimeDefaults.BootValidation);
9494

9595
config.Debug.LogModifierHookStats = data.Debug.LogModifierHookStats;
96-
config.Debug.UiaProbeRecycleIntervalSec = data.Debug.UiaProbeRecycleIntervalSec > 0
97-
? data.Debug.UiaProbeRecycleIntervalSec
98-
: debugDefaults.UiaProbeRecycleIntervalSec;
9996
config.Debug.LogMinimumLevel = string.IsNullOrWhiteSpace(data.Debug.LogMinimumLevel)
10097
? debugDefaults.LogMinimumLevel
10198
: data.Debug.LogMinimumLevel;
@@ -159,7 +156,6 @@ public static AppConfigData MapFromCoreDefaults(AppConfig source)
159156
data.Runtime.BootValidation = MapBootValidationBack(config.Runtime.BootValidation);
160157

161158
data.Debug.LogModifierHookStats = config.Debug.LogModifierHookStats;
162-
data.Debug.UiaProbeRecycleIntervalSec = config.Debug.UiaProbeRecycleIntervalSec;
163159
data.Debug.LogMinimumLevel = config.Debug.LogMinimumLevel;
164160

165161
data.Normalize();

bouyomichan-plugin/VoicepeakProxyWorker/VoicepeakProxyWorker.csproj

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,8 @@
5252
<WorkerDependencyFiles Include="$(OutputPath)EasyHook*.dll" />
5353
<WorkerDependencyFiles Include="$(OutputPath)EasyLoad*.dll" />
5454
<WorkerDependencyFiles Include="$(OutputPath)NAudio*.dll" />
55-
<ProbeDependencyFiles Include="$(CoreProjectDepsDir)VoicepeakProxyCore.UiaProbe.exe" Condition="Exists('$(CoreProjectDepsDir)VoicepeakProxyCore.UiaProbe.exe')" />
55+
<WorkerDependencyFiles Include="$(OutputPath)Interop.UIAutomationClient*.dll" />
5656
<AllDependencyFiles Include="@(WorkerDependencyFiles)" />
57-
<AllDependencyFiles Include="@(ProbeDependencyFiles)" />
5857
</ItemGroup>
5958

6059
<Copy SourceFiles="@(AllDependencyFiles)" DestinationFolder="$(CoreDepsDir)" Condition="'@(AllDependencyFiles)' != ''" />

bouyomichan-plugin/VoicepeakProxyWorker/WorkerHost.cs

Lines changed: 21 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ internal sealed class WorkerHost
1818
private readonly int _ownerPid;
1919
private readonly WorkerFileLogger _logger;
2020
private readonly WorkerSettingsProvider _settingsProvider;
21-
private VoicepeakOneShotSession _oneShotSession;
2221

2322
private bool _running;
2423
private Thread _ownerWatchThread;
@@ -35,31 +34,22 @@ public WorkerHost(string pipeName, string settingsPath, int ownerPid, WorkerFile
3534
// Worker処理を開始
3635
public bool Run()
3736
{
38-
try
37+
PluginSettingsFile settings = _settingsProvider.GetCurrent();
38+
_logger.SetMinimumLevel(settings.AppConfig.Debug.LogMinimumLevel);
39+
if (!TryRunStartupValidation())
3940
{
40-
PluginSettingsFile settings = _settingsProvider.GetCurrent();
41-
_logger.SetMinimumLevel(settings.AppConfig.Debug.LogMinimumLevel);
42-
_oneShotSession = VoicepeakOneShot.Start(AppConfigMapper.Map(settings.AppConfig), _logger);
43-
if (!TryRunStartupValidation())
44-
{
45-
return false;
46-
}
47-
48-
_running = true;
49-
StartOwnerWatchThread();
41+
return false;
42+
}
5043

51-
while (_running)
52-
{
53-
ServeSingleConnection();
54-
}
44+
_running = true;
45+
StartOwnerWatchThread();
5546

56-
return true;
57-
}
58-
finally
47+
while (_running)
5948
{
60-
_oneShotSession?.Dispose();
61-
_oneShotSession = null;
49+
ServeSingleConnection();
6250
}
51+
52+
return true;
6353
}
6454

6555
// 親プロセス監視スレッドを開始
@@ -217,14 +207,16 @@ private WorkerSpeakResponse ExecuteSpeak(WorkerSpeakRequest request)
217207
{
218208
try
219209
{
220-
ApplyLatestSettings();
210+
PluginSettingsFile settings = _settingsProvider.GetCurrent();
211+
AppConfig config = AppConfigMapper.Map(settings.AppConfig);
212+
_logger.SetMinimumLevel(settings.AppConfig.Debug.LogMinimumLevel);
221213
_logger.Info("speak_start taskId=" + request.TaskId + " length=" + request.Text.Length);
222214

223215
SpeakOnceRequest speakRequest = new SpeakOnceRequest();
224216
speakRequest.Text = request.Text;
225217

226-
SpeakOnceResult result = _oneShotSession.SpeakOnceWait(speakRequest);
227-
ClearInputOnceResult clearResult = _oneShotSession.ClearInputOnce();
218+
SpeakOnceResult result = VoicepeakOneShot.SpeakOnceWait(config, speakRequest, _logger);
219+
ClearInputOnceResult clearResult = VoicepeakOneShot.ClearInputOnce(config, _logger);
228220
if (!clearResult.Succeeded)
229221
{
230222
_logger.Warn("post_speak_clear_failed taskId=" + request.TaskId + " status=" + clearResult.Status + " error=" + clearResult.ErrorMessage);
@@ -280,8 +272,10 @@ private bool TryRunStartupValidation()
280272
{
281273
try
282274
{
283-
ApplyLatestSettings();
284-
ValidateInputOnceResult validate = _oneShotSession.ValidateInputOnce();
275+
PluginSettingsFile settings = _settingsProvider.GetCurrent();
276+
AppConfig config = AppConfigMapper.Map(settings.AppConfig);
277+
_logger.SetMinimumLevel(settings.AppConfig.Debug.LogMinimumLevel);
278+
ValidateInputOnceResult validate = VoicepeakOneShot.ValidateInputOnce(config, _logger);
285279
if (!validate.Succeeded)
286280
{
287281
_logger.Warn("startup_validation_failed status=" + validate.Status + " error=" + validate.ErrorMessage);
@@ -299,12 +293,7 @@ private bool TryRunStartupValidation()
299293
}
300294

301295
// 最新設定をセッションへ反映
302-
private void ApplyLatestSettings()
303-
{
304-
PluginSettingsFile settings = _settingsProvider.GetCurrent();
305-
_logger.SetMinimumLevel(settings.AppConfig.Debug.LogMinimumLevel);
306-
_oneShotSession.UpdateConfig(AppConfigMapper.Map(settings.AppConfig));
307-
}
296+
308297

309298
}
310299

core-dll/VoicepeakProxyCore.csproj

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,17 @@
77
<Prefer32Bit>false</Prefer32Bit>
88
<LangVersion>latest</LangVersion>
99
<Nullable>disable</Nullable>
10-
<Version>1.1.0</Version>
11-
<FileVersion>1.1.0.0</FileVersion>
10+
<Version>1.2.0</Version>
11+
<FileVersion>1.2.0.0</FileVersion>
1212
<AssemblyVersion>1.0.0.0</AssemblyVersion>
13-
<InformationalVersion>1.1.0</InformationalVersion>
13+
<InformationalVersion>1.2.0</InformationalVersion>
1414
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
1515
<SourceRevisionId></SourceRevisionId>
1616
</PropertyGroup>
1717

1818
<ItemGroup>
1919
<PackageReference Include="EasyHook" Version="2.7.7097" />
20+
<PackageReference Include="Interop.UIAutomationClient" Version="10.19041.0" />
2021
<PackageReference Include="NAudio.Wasapi" Version="2.2.1" />
2122
</ItemGroup>
2223

@@ -32,11 +33,7 @@
3233
<Compile Remove="uia-probe\**\*.cs" />
3334
</ItemGroup>
3435

35-
<Target Name="BuildUiaProbe" AfterTargets="Build" Condition="'$(IsUiaProbeBuild)' != 'true'">
36-
<MSBuild Projects="uia-probe\VoicepeakProxyCore.UiaProbe.csproj" Targets="Restore;Build" Properties="Configuration=$(Configuration);Platform=x64;BuildProjectReferences=false;IsUiaProbeBuild=true" />
37-
</Target>
38-
39-
<Target Name="MoveDependenciesToDepsFolder" AfterTargets="Build" DependsOnTargets="BuildUiaProbe" Condition="'$(IsUiaProbeBuild)' != 'true'">
36+
<Target Name="MoveDependenciesToDepsFolder" AfterTargets="Build" Condition="'$(IsUiaProbeBuild)' != 'true'">
4037
<PropertyGroup>
4138
<CoreDepsDir>$(OutputPath)VoicepeakProxyCore.deps\</CoreDepsDir>
4239
</PropertyGroup>
@@ -48,7 +45,7 @@
4845
<CoreDependencyFiles Include="$(OutputPath)EasyHook*.dll" />
4946
<CoreDependencyFiles Include="$(OutputPath)EasyLoad*.dll" />
5047
<CoreDependencyFiles Include="$(OutputPath)NAudio*.dll" />
51-
<CoreDependencyFiles Include="uia-probe\bin\x64\$(Configuration)\$(TargetFramework)\VoicepeakProxyCore.UiaProbe.exe" Condition="Exists('uia-probe\bin\x64\$(Configuration)\$(TargetFramework)\VoicepeakProxyCore.UiaProbe.exe')" />
48+
<CoreDependencyFiles Include="$(OutputPath)Interop.UIAutomationClient*.dll" />
5249
</ItemGroup>
5350

5451
<Copy SourceFiles="@(CoreDependencyFiles)" DestinationFolder="$(CoreDepsDir)" Condition="'@(CoreDependencyFiles)' != ''" />

0 commit comments

Comments
 (0)