I really hope someone can point me in the right direction with this. This code works perfectly when I'm debugging within Visual Studio Express 2010, but give me the mci error 263 - "The specified device is not open nor recognised by mci" when built and deployed.
I've tried tinkering with build settings and what not, but no joy. Surely this must be a config issue rather than the code?
Any help anyone can provide would be greatly appreciated.
----- Code Follows ----
[DllImport("winmm.dll")]
private static extern int mciSendString(string lpstrCommand, string lpstrReturnString, int uReturnLength, int hwndCallback);
[System.Runtime.InteropServices.DllImport("winmm.dll")]
private static extern bool mciGetErrorString(int fdwError, StringBuilder lpszErrorText, int cchErrorText);
///Inside a button function
mciSendString("open new Type waveaudio Alias recsound", "", 0, 0);
mciSendString("record recsound", "", 0, 0);
//Inside another button function
int i = mciSendString(#"save recsound C:/test22/sound", outs, 0, 0);
MessageBox.Show(""+i);
StringBuilder buffer = new StringBuilder(128);
bool returnValue = mciGetErrorString(i, buffer, buffer.Capacity);
string err = buffer.ToString();
MessageBox.Show(buffer.ToString());
Well I got your code to work by actually specifying a file to save it as...
string outs = "";
//Inside another button function
int i = mciSendString(#"save recsound C:/test.wav", ref outs, 0, 0);
I also changed the out parameter to a ref though I doubt that had anything to do with it.
What type of file are you trying to play? And where is it deployed? I recently came upon the same issue; I cannot play .mp3s or .wmas on one of my test machines (I get the same error: 263). I installed Windows Media Player and they worked, so this leads me to believe that a codec is missing. Now I just have to figure out what codec(s) it was.
Related
I know similar questions have been asked before but all the answers have been partial, for example suggesting I use AssocQueryString which I am doing. However I'm still failing to find some exe. For example the code below fails to find outlook.exe or firefox.exe - Typing outlook.exe into Windows Explorer address bar finds these almost instantley.
In the code below the exe fileName can be any local location on the users machine, it may or may not be on the users search path.
How can I improve this to find the files? (this is called from a 32 bit exe)
// for example, get actual full path to outlook.exe
string fullPath = FindPath("outlook.exe");
public static string FindPath(string fileName)
{
uint length = UnsafeMethods.MAX_PATH;
StringBuilder path = new StringBuilder((int)length);
if (Path.GetDirectoryName(fileName) == string.Empty)
{
if (UnsafeMethods.AssocQueryString(UnsafeMethods.AssocF.OpenByExeName, UnsafeMethods.AssocStr.Executable, fileName, null, path, ref length) != 0)
{
IntPtr filePart = IntPtr.Zero;
IntPtr wow64Value = IntPtr.Zero;
// try 64 bit path
UnsafeMethods.Wow64DisableWow64FsRedirection(ref wow64Value);
bool success = UnsafeMethods.SearchPath(null, fileName, null, path.Capacity, path, ref filePart) > 0;
UnsafeMethods.Wow64RevertWow64FsRedirection(wow64Value);
if (!success)
{
// try 32 bit path
success = UnsafeMethods.SearchPath(null, fileName, null, path.Capacity, path, ref filePart) > 0;
}
}
return path.ToString();
}
else
{
return fileName;
}
}
It seems there are many places to look to find the path to an exe. While the original code above works, it is not an exhaustive search and you also need to look in the registry key SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\ and also check the SpecialFolders Windows, System and SystemX86 (https://learn.microsoft.com/en-us/dotnet/api/system.environment.specialfolder?view=netframework-4.7.2)
I have developed a c# code snippet to determine if the virtual (on-screen) keyboard was showing or not.
The code below worked fine in Windows 7, 8 and 8.1, but in Windows 10, the IsKeyboardVisible always returns true...
public static bool IsKeyboardVisible() {
Process keyboardProc;
UInt32 WS_DISABLED = 0x8000000;
UInt32 WS_VISIBLE = 0X94000000;
int GWL_STYLE = -16;
IntPtr keyboardHandle = GetKeyboardWindowHandle();
bool visible = false;
if (keyboardHandle != IntPtr.Zero) {
UInt32 style = GetWindowLong(keyboardHandle, GWL_STYLE);
// in Win10, this always returns "true", i.e. WS_DISABLED is
//
//visible = ((style & WS_DISABLED) != WS_DISABLED);
// UPDATE: I found this code helping here
visible = (style == WS_VISIBLE);
}
return visible;
}
I used a tutorial on SO, but it's a while ago so sorry for not crediting the author.
Does anyone know about a working code snippet for all recent Windows versions, so I don't have to check the actual OS to switch on the version...?
UPDATE
I found the original post here, which allowed me to correct the code. So now my problem is the same old Win10 issue - I can't show the virtual keyboard using
string progFiles = #"C:\Program Files\Common Files\Microsoft Shared\ink";
string keyboardPath = Path.Combine(progFiles, "TabTip.exe");
keyboardProc = Process.Start(keyboardPath);
... Again, is there any "all-platform" code I can use, or what is the suggested approach for Win10?
UPDATE 2
I found out about issues running a 32-bit application on a 64-bit os. That being said, the error occurs whether I try to run osk.exe in the System32 or the "sysWOW64` folder... Is there any other way than making a 64-bit release???
After much digging about TabTip.exe, osk.exe and x86 and x64 compatibility issues, I found a solution by searching the osk.exe on my system and trying to run each of them. I found 4 version the following folders:
C:\Windows\System32
C:\Windows\SysWOW64
C:\Windows\WinSxS\amd64_microsoft...
C:\Windows\WinSxS\wow64_microsoft...
It appears the one in C:\Windows\WinSxS\amd64_microsoft... works fine (not the other three though)...
Given the "amd64_...." folder might not be the same on different machines (I actually checked and they don't match, I didn't search whether this depends on the machine, the windows build or anything else...).
So basically I did a small routine to look into WinSxS folder and returning the very firs occurrence of osk.exe, which works just fine. I also made the code working on a 32-bit OS using a simple OS-architecture test:
string OSKpath64 = getOskPath(#"C:\Windows\WinSxS");
if (string.IsNullOrWhiteSpace(OSKpath64)) {
OSKpath64 = "osk.exe";
}
string OSKpath32 = #"C:\Windows\System32\osk.exe";
if (!File.Exists(OSKpath32)) {
OSKpath32 = #"osk.exe";
}
System.Diagnostics.Process.Start((Environment.Is64BitOperatingSystem) ? OSKpath64 : OSKpath32);
UPDATE:
The confusion with one working and one non-working version within the WinSxS folder made me nervous. It works just fine because the amd_.. folder is alphabetically before wow64_....
I therefore suggest to add a test in the getOskPath method to return the first native 64-bit osk.exe (not the emulated one).
Using the IsWin64Emulator method found here, the method looks like this:
static string getOskPath(string dir) {
string path = Path.Combine(dir, "osk.exe");
if (File.Exists(path)) {
Process p = System.Diagnostics.Process.Start(path);
if (p.IsWin64Emulator()) {
path = string.Empty;
}
p.Kill();
return path;
}
DirectoryInfo di = new DirectoryInfo(dir);
foreach (DirectoryInfo subDir in di.GetDirectories().Reverse()) {
path = getOskPath(Path.Combine(dir, subDir.Name));
if (!string.IsNullOrWhiteSpace(path)) {
return path;
}
}
return string.Empty;
}
Same problem with me, I try all answer here, but it not work.
After finding solution with google, this is is ok.
// Step 1: For Load On-Screen Keyboard
const string Kernel32dll = "Kernel32.Dll";
[DllImport(Kernel32dll, EntryPoint = "Wow64DisableWow64FsRedirection")]
public static extern bool Wow64DisableWow64FsRedirection(ref IntPtr ptr);
[DllImport(Kernel32dll, EntryPoint = "Wow64EnableWow64FsRedirection")]
public static extern bool Wow64EnableWow64FsRedirection(IntPtr ptr);
IntPtr wow64Value;
//---------------------------------------
// Step 2: Function-----
if (Environment.Is64BitOperatingSystem)
{
if (Wow64DisableWow64FsRedirection(ref wow64Value))
{
System.Diagnostics.Process.Start("osk.exe");
Wow64EnableWow64FsRedirection(wow64Value);
}
}
else
{
System.Diagnostics.Process.Start("osk.exe");
}
//----------------
I need an help about the performing of the mp3 player files. I search on internet and i find how to use the winmm.dll libreary only if I need to take an mp3 file from an external directory. I need to modify it for an internal directory of my app.
Let's show the code:
I create the Mp3Player class like that:
class Mp3Player : IDisposable
{
[DllImport("winmm.dll")]
private static extern long mciSendString(string lpstrCommand, StringBuilder lpstrReturnString, int uReturnLength, int hwndCallback);
public void open(string file)
{
const string FORMAT = #"open ""{0}"" type MPEGVideo alias MyMp3";
string command = String.Format(FORMAT, file);
mciSendString(command, null, 0, 0);
}
public void play()
{
string command = "play MyMp3";
mciSendString(command, null, 0, 0);
}
public void stop()
{
string command = "stop MyMp3";
mciSendString(command, null, 0, 0);
}
public void Dispose()
{
string command = "close MyMp3";
mciSendString(command, null, 0, 0);
}
public double Duration()
{
string command = "status MyMp3 length";
double bho = mciSendString(command, null, 0, 0);
return bho;
}
And call for open the internal file here:
var soundfile = "Assets/audio/myaudio.mp3";
private Mp3Player _mp3player = new Mp3Player();
_mp3player.open(soundfile);
_mp3player.play();
This give me an error on the opening of the of the file, so i'm sure that the problem is in the directory path that i send to the class. I tryed some version but no one works and on internet can't find nothing helping me. Some one of you can say me the correct path for making work that function?
Thank you very much to all.
Excuse me for my really bad english.
According to this forum on Windows Mobile, all waveform audio function are implemented in 'coredll.dll'. Use this DLL instead of 'winmm.dll'.
So, I am trying to play mp3 file in C# console application.
class Program
{
[DllImport("winmm.dll")]
static extern Int32 mciSendString(string command,
StringBuilder buffer, int bufferSize, IntPtr hwndCallback);
static void Main(string[] args)
{
string filePath = "1.mp3";
string command = "open \"" + filePath + "\" type mpegvideo alias MyTag";
Int32 err = mciSendString(command, null, 0, IntPtr.Zero);
command = "play MyTag";
err = mciSendString(command, null, 0, IntPtr.Zero);
Console.ReadLine();
}
}
But I'm getting error 266 (MCIERR_CANNOT_LOAD_DRIVER) when try to open file. Intersting thing is that the same code works well if I put it into button callback of GUI app (Windows Forms Application). Also it works if I change code ommitting file open.
string filePath = "1.mp3";
string command = "play " + filePath;
Int32 err = mciSendString(command, null, 0, IntPtr.Zero);
It also works well but I'd like to separate open action.
I'm using Microsoft Visual Studio 2008, .NET 3.5 (tested also on .NET 2.0 with the same results), Windows 7 32-bit.
Any ideas why is it so?
After reading this post on SO I tried to write a small app I need to read and write hidden registry keys/values.
I checked Registry Manipulation using NT Native APIs and Creating "Hidden" Registry Values links.
First one gave me something to work on, but it's written in C++ while second is a Delphi project working well.
I am not able to convert first and I could try to convert second, but I'd need to find some code to read keys/values too. For this reason I'd like to know if there's something "ready" and tested in C#.
I've also downloaded Proces Hacker v1.11 source code and used it to partially convert Delphi example as shown below, but hidden registry key is accessible (while in Delphi it wasn't) and there are not APIs to write values.
static void Main(string[] args)
{
string KeyNameBuffer = #"\Registry\User\S-1-5-21-3979903645-2167650815-2353538381-1001\SOFTWARE";
string NewKeyNameBuffer = "Systems Internals";
string HiddenKeyNameBuffer = "Can't touch me\0";
string HiddenValueNameBuffer = "Hidden Value";
// Apro la chiave di registro
IntPtr SoftwareKeyHandle = CreateKey(KeyNameBuffer, IntPtr.Zero);
if (SoftwareKeyHandle != IntPtr.Zero)
{
IntPtr SysKeyHandle = CreateKey(NewKeyNameBuffer, SoftwareKeyHandle);
if (SysKeyHandle != IntPtr.Zero)
{
// This key shouldn't be accessible, but it is
IntPtr HiddenKeyHandle = CreateKey(HiddenKeyNameBuffer, SysKeyHandle);
if (HiddenKeyHandle != IntPtr.Zero)
{
// I don't have APIs to write values
}
}
}
}
static IntPtr CreateKey(string keyName, IntPtr rootKey)
{
IntPtr res;
KeyCreationDisposition disp;
ObjectAttributes attributes = new ObjectAttributes(keyName,
ObjectFlags.CaseInsensitive,
new NativeHandle(rootKey));
NtStatus st = Win32.NtCreateKey(out res, KeyAccess.All,
ref attributes, 0,
IntPtr.Zero, RegOptions.NonVolatile, out disp);
return st == NtStatus.Success ? res : IntPtr.Zero;
}
Finally: from Vista on, you cannot write \Registry\Machine part if you're not running your app as Administrator, so in the example I used my user registry key. Is there a way to us native APIs to write that part of the registry if I need to store a per-machine value?
If you want it in HKLM and privileges don't let you, it doesn't matter which API layer you're using, Reg* functions of Nt* ones - it won't let you do that with access denied error.