How to use all voices available? - c#

I am using this command to list available voices
private static SpeechSynthesizer sprecher;
...
sprecher = new SpeechSynthesizer();
...
private static List<VoiceInfo> GetInstalledVoices()
{
var listOfVoiceInfo = from voice
in sprecher.GetInstalledVoices()
select voice.VoiceInfo;
return listOfVoiceInfo.ToList<VoiceInfo>();
}
I get only 4 different voices (Hedda, Hazel, David and Zira) yet windows itself shows many more speakers.
Therefore I only get the "-Desktop"-voices. How do I access the other speakers via c#?

Edit 2: OP got it to work by using export instead of command line copying
Export the whole Token Directory of Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCore\Voices to a file. Replace every HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCore\Voices\Tokens with HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens in the file and run the file(I removed the voices I already had before).
On the following thread a MSDN user, A.Kelany, asks a similar question, where he is only getting two voices from the GetInstalledVoices method.
He said he was able to fix this by doing the following :
I managed to get it to work in a test project by doing the following :
I opened the registry and noticed that there is a node :
Quote:
Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices
which contained the voices that appear in the application GetInstalledVoices method
and there is another node :
Quote:
Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCore\Voices
that contained all the voices including the ones don't appear in the aforementioned method,
So I copied one of the voices from the second node to the first node
and it worked!
He also states that he could not build on Any CPU after this change, and had to change the build type to x64

Related

Getting a list of excluded extensions for windows search (SystemIndex)

I want to retrieve a list of the extensions excluded from search indexing. Tried this
using Microsoft.Search.Interop;
CSearchManager csm=new CSearchManager();
ISearchCatalogManager iscm = csm.GetCatalog("SystemIndex")
Microsoft.Search.Interop.IEnumString ies = iscm.EnumerateExcludedExtensions();
but it turns out EnumerateExcludedExtensions is not implemented.
Anyone one know of an alternate route?
Thanks
The following does work, retrieving the excluded extensions with the marked get/set-able bool IExtensions.IncludedExtensions at the apparently false-by-default value.
Curious to see that attempting to set that bool to true to get the included extensions instead gens an accessdenied error, and further running as admin, a notimplemented error. I could not find actual documentation.
This worked on Win 7 and Win 10 in my testing, but will have to ship in a try block regardless of course, and if it breaks down the line, not critical in my case, just becomes a missing feature.
using MSSCTLB; // C:\Windows\System32\mssrch.dll "Microsoft Search CoClasses Type Library"
CGatheringManager gm=new CGatheringManager();
IExtensions iexs = gm.GatherApplications["Windows"].GatherProjects["SystemIndex"].Gather.Extensions;
foreach (IExtension item in iexs) listBox1.Items.Add(item.Extension);
also, the extended interfaces can be seen in
MSSITLB, "Microsoft Search Interface Type Library"
"C:\Windows\System32\mssitlb.dll"

C# Winform Registry set and get functions appear to work, but don't actually change the registry

I'm trying to use this registry hack I found online:
;Disables F1 key - Help and Support - in Windows 10
;Ramesh Srinivasan, Winhelponline.com
[HKEY_CURRENT_USER\SOFTWARE\Classes\Typelib\{8cec5860-07a1-11d9-b15e-000d56bfe6ee}\1.0\0\win32]
#=""
[HKEY_CURRENT_USER\SOFTWARE\Classes\Typelib\{8cec5860-07a1-11d9-b15e-000d56bfe6ee}\1.0\0\win64]
#=""
When I run it as a .reg command via Windows Explorer and watch the registry with regedit, it works as intended. Removing it is another registry file that simply removes the \0 subkey (and win32 and 64 with it). I'm trying to emulate this function with C# in a Winform using .net CORE:
private void CheckF1()
{
// Registry data from ;Ramesh Srinivasan, Winhelponline.com
RegistryKey F1key = Registry.CurrentUser.OpenSubKey(#"SOFTWARE\Classes\TypeLib\{8cec5860-07a1-11d9-b15e-000d56bfe6ee}\1.0\0");
// EGADS! It's active!
if (F1key == null)
{
fckF1RestoreBtn.Enabled = false;
fckF1KillBtn.Enabled = true;
fckF1Status.Text = "That creepy bugger is waiting and watching.";
}
else
{
fckF1RestoreBtn.Enabled = true;
fckF1KillBtn.Enabled = false;
fckF1Status.Text = "The F1-Help function had been put in it's place.";
}
}
private void fckF1KillBtn_Click(object sender, EventArgs e)
{
Registry.CurrentUser.CreateSubKey(#"SOFTWARE\Classes\Typelib\{8cec5860-07a1-11d9-b15e-000d56bfe6ee}\1.0\0\win32");
Registry.CurrentUser.CreateSubKey(#"SOFTWARE\Classes\Typelib\{8cec5860-07a1-11d9-b15e-000d56bfe6ee}\1.0\0\win64");
CheckF1();
}
private void fckF1RestoreBtn_Click(object sender, EventArgs e)
{
Registry.CurrentUser.DeleteSubKeyTree(#"SOFTWARE\Classes\Typelib\{8cec5860-07a1-11d9-b15e-000d56bfe6ee}\1.0\0");
CheckF1();
}
Weirdly the code "sees" a setting and responds like it should. Even to the point that whichever toggle position it was in on close it remembers when I load the file again. It's almost like it's playing along to screw with me. Regardless, when I watch the registry, none of my code has any actual effect though by all appearances it seems to work otherwise (it doesn't actually of course because the registry change isn't happening).
NOTE: I have already updated my manifest file for the project to include elevated permissions:
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
Here's the breakpoint on the test statement to see if the subkeys are there that shows they are:
Meanwhile the registry location for the exact path shown in the debug doesn't have the 1.0\0 path at all:
I don't know how the code is reading phantom values. Someone closed my previous question pointing to another answer that didn't have any effect (Registry key deleted but still getting value from registry c#):
"Prefer 32 bit" was never checked for my project in the first place
Modifying my code as recommended had no effect
var key = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64)
.OpenSubKey(#"SOFTWARE\WOW6432Node\Classes\TypeLib\{8cec5860-07a1-11d9-b15e-000d56bfe6ee}\1.0\0");
Adding "Wow64Node" to the path makes no difference in execution.
EXPECTED BEHAVIOR
Checking to see if the HKEY_CURRENT_USER\SOFTWARE\Classes\Typelib{8cec5860-07a1-11d9-b15e-000d56bfe6ee}\1.0\0 path is present should return null if the \0 path is not present
Adding and removing the subkeys should show in the registry
So apparently HKEY_CURRENT_USERS is an alias. When the above code runs, it updates in HKEY_USERS under the specific logged in user. There's a question that talks about this behavior here: write registry to hkey_current_user instead of hkey_users
That said, the code appears to work, it's just that the registry doesn't update HKCU like when you run .reg commands. To verify it was working, I'd run the toggle that kills the keys then click them in Regedit and it would say they didn't exist. When I toggled back, I could click on them. So basically, it works (not sure if it required the "using" blocks as others suggested, but I see no reason to take them out).
Now my problem is that it points to the admin user and NOT the regular user because I'm running it and regedit as admin. It took forever to determine this based on running regedit as user in one case and admin in another. Bottom line, this won't work and I'll probably end up running .reg files in the command line instead.

WPF Live-Regions just for Narrator?

I have a textblock (ContentTextBlock) with AutomationProperties.LiveSettings="Assertive". I'm just testing and checking how useful this feature is. And... am disappointed so far.
private void Button_Click(object sender, RoutedEventArgs e)
{
ContentTextBlock.Text += " test";
var peer = UIElementAutomationPeer.FromElement(ContentTextBlock);
if(peer == null)
{
peer = UIElementAutomationPeer.CreatePeerForElement(ContentTextBlock);
peer.RaiseAutomationEvent(AutomationEvents.LiveRegionChanged);
}
peer.RaiseAutomationEvent(AutomationEvents.LiveRegionChanged);
}
When using Narrator, this works as advertised. Whenever clicking the button, Narrator announces the TextBlock text ("test" "test test" "test test test")... But when I use NVDA or JAWS, nothing happens, although the screenreader versions are relatively up-to-date. Did they really not add any support for live-regions or am I just missing an important point?
Whilst I didn't manage to get live regions to work, I found another workaround:
Tolk by Davy Kager
Tolk is a library which can, among oterrs
Detect which supported screen reader, if any, is running
Pass strings to the screen reader's speech engine and braille.
Also has support for SAPI
To include Tolk in your C# project, download it from the link above, then include tolk.cs (from src/dotnet) in your project, and place tolk.dll (it's found in bin) in the folder with your executable (or somewhere in the PATH variable). Make sure that the dll version matches your CPU target (x86/x64). Do the same for the dlls in the lib directory. Then you can use it according to the code found in the examples folder.
PS. Tolk works on Win 7 as well, so that's a bonus. The live-regions of WPF were only supported from Win 8 on.

MSDN OneNote Api: Navigate to never before opened page without opening a OneNote Application Window

My goal is to be able to use C# to programmatically open any .one section file and get all of the section's page ids. In a simple case (one where I have created and recently used the section), this can done with the following code:
using Microsoft.Office.Interop.OneNote;
class Program
{
public static void ProcessOnenoteFile()
{
Application onenoteApp = new Application();
string filepath = #"C:\Users\Admin\Documents\OneNote Notebooks\My Notebook\testsection.one";
string sectionId;
onenoteApp.OpenHierarchy(filepath, null, out sectionId);
string hierarchy;
onenoteApp.GetHierarchy(sectionId, HierarchyScope.hsPages, out hierarchy);
File.WriteAllText(#"C:\hierarchy.txt", hierarchy);
}
}
From here I can parse the xml to find all the pageIds and I am good to go.
The problem, however, is that I want to do this with files I am getting from somebody else and have never opened before. When I run the same code on those files, I cannot find any pageIds in the hierarchy, and therefore, I cannot process any pages. A fix that seems to work is to use the navigateTo method to open the section file in OneNote before trying to get the hierarchy.
...
string sectionId;
onenoteApp.OpenHierarchy(filepath, null, out sectionId);
onenoteApp.NavigateTo(sectionId);
string hierarchy
...
This, however, is quite annoying as I need to open the OneNote application. Since I have many .one section files to process it would be a lot of random information flashing across the screen which is not necessary and might confuse the end users of my program. Is there a way I can achieve the same result of adding pageIds to the hierarchy without needing to open the OneNote Application? At the very least, is there a way I can hide the application?
UPDATE:
I just noticed that using the Publish command also updates the hierarchy with pageIds, however, this solution is still not ideal as it requires me to make anotehr file.
Also, looking more closely at the xml export, I saw that there is a an attribute called "areAllPagesAvailable" which is set to false for me on all the files I have yet to open in OneNote.
WooHoo! After a couple hours of just playing around and Google Searching the different methods, I have found what I am after.
Solution: SyncHierarchy(sectionId);
...
string sectionId;
onenoteApp.OpenHierarchy(onenoteFile, null, out sectionId, CreateFileType.cftSection);
onenoteApp.SyncHierarchy(sectionId);
string hierarchy;
onenoteApp.GetHierarchy(sectionId, HierarchyScope.hsPages, out hierarchy);
...

Cannot add icon in shell extension with C#

I've found a very nice tutorial and i am trying to understand something that is not in this tutorial (because the tut itself works fine)
http://www.codeproject.com/Articles/9163/File-Rating-a-practical-example-of-shell-extension
When you look at applications like WinRar, TortoiseSVN, Antivirus-apps and many more, there is an icon next to the Shell Extension Item.
I would like to know how this is done. (Programmatically with C#)
Adding a separator works, adding a submenu works and click+action also works, but i'm struggling with the icon. This cannot be so hard. Can somebody help me?
And please don't say that Microsoft doesn't longer support this in .NET 4.0, because it is not guaranteed and therefore they don't supply samplecode. If all those other apps can do it, then it is possible.
Please supply me some sample code, some tutorials or maybe even a working piece of code.
Please have a look at the following article, it uses .NET 4.0 it to create Windows Shell Extensions using the SharpShell nuget package.
NET Shell Extensions - Shell Context Menus
Using this library, you can set the image directly while creating the contextmenustrip as shown below
protected override ContextMenuStrip CreateMenu()
{
// Create the menu strip.
var menu = new ContextMenuStrip();
// Create a 'count lines' item.
var itemCountLines = new ToolStripMenuItem
{
Text = "Count Lines...",
Image = Properties.Resources.CountLines
};
// When we click, we'll count the lines.
itemCountLines.Click += (sender, args) => CountLines();
// Add the item to the context menu.
menu.Items.Add(itemCountLines);
// Return the menu.
return menu;
}
You only have to add to the following registry key: HKEY_LOCAL_MACHINE\SOFTWARE\Classes*\shellex\ContextMenuHandlers
and here is the code:
string TimeStamp = DateTime.Now.ToString("dd-MM-yyyy");
string key = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\*\\shellex\\ContextMenuHandlers\\Winrar";
string valueName = "MyWinrar";
Microsoft.Win32.Registry.SetValue(key, valueName, HERE WHAT YOU WANT TO START, Microsoft.Win32.RegistryValueKind.String);
i hope it works for you!
All the apps you listed use COM and unmanaged code to create overlay icon handlers. There is even a special project TortoiseOverlays that provides a common library for drawing icons for TortoiceCSV, TortoiseSVN and TortoiseGIT. You can take a look at it's source code to find out how it is done. If you want to draw similar icons, you should probably just reuse it.
Using .Net for this type of extensions is not recommended, because when multiple extensions, built against different .Net versions would attempt to load in explorer process, they will crash the explorer.

Categories

Resources