Programming/C#

C# 윈도우 화상 키보드(OSK) 실행 및 종료 방법 (Win32 API 사용)

JeongKyun 2022. 4. 25.
반응형

서론


태블릿 환경에서 개발 중 텍스트박스에서 PasswordChar 속성을 먹였을 경우 패스워드를 입력할 때 키보드 입력창이 안올라오는 현상을 볼 수 있다. 필자는 이 경우 윈도우에 내장되어있는 화상키보드를 실행하여 처리하였다. 실행방법에 대해 알아보자.

 


 

실행 및 종료 방법


실행 방법1 (비추천)

Process p = new Process();
p.StartInfo.FileName = "C:\\Windows\\System32\\osk.exe"; 
p.StartInfo.Arguments = null; 
p.StartInfo.WindowStyle = ProcessWindowStyle.Normal; 
p.Start();
System.ComponentModel.Win32Exception (0x80004005): 지정된 파일을 찾을 수 없습니다.
더보기

************** Exception Text **************
System.ComponentModel.Win32Exception (0x80004005): 
   at System.Diagnostics.Process.StartWithShellExecuteEx(ProcessStartInfo startInfo)
   at System.Diagnostics.Process.Start()
   at System.Diagnostics.Process.Start(ProcessStartInfo startInfo)
   at System.Diagnostics.Process.Start(String fileName)
   at WindowsApplication1.Form1.Timer1_Tick(Object sender, EventArgs e)
   at System.Windows.Forms.Timer.OnTick(EventArgs e)
   at System.Windows.Forms.Timer.TimerNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)


************** Loaded Assemblies **************
mscorlib
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.544 (RTMLDR.030319-5400)
    CodeBase: file:///C:/Windows/Microsoft.NET/Framework/v4.0.30319/mscorlib.dll
----------------------------------------
WindowsApplication1
    Assembly Version: 1.0.0.0
    Win32 Version: 1.0.0.0
    CodeBase: file:///C:/Users/Public/Music/s.exe
----------------------------------------
Microsoft.VisualBasic
    Assembly Version: 10.0.0.0
    Win32 Version: 10.0.30319.1 built by: RTMRel
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/Microsoft.VisualBasic/v4.0_10.0.0.0__b03f5f7f11d50a3a/Microsoft.VisualBasic.dll
----------------------------------------
System
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.544 built by: RTMLDR
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System/v4.0_4.0.0.0__b77a5c561934e089/System.dll
----------------------------------------
System.Core
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.450 built by: RTMLDR
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Core/v4.0_4.0.0.0__b77a5c561934e089/System.Core.dll
----------------------------------------
System.Windows.Forms
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.560 built by: RTMLDR
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Windows.Forms/v4.0_4.0.0.0__b77a5c561934e089/System.Windows.Forms.dll
----------------------------------------
System.Drawing
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.568 built by: RTMLDR
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Drawing/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll
----------------------------------------
System.Runtime.Remoting
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.1 (RTMRel.030319-0100)
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Runtime.Remoting/v4.0_4.0.0.0__b77a5c561934e089/System.Runtime.Remoting.dll
----------------------------------------

************** JIT Debugging **************
To enable just-in-time (JIT) debugging, the .config file for this
application or computer (machine.config) must have the
jitDebugging value set in the system.windows.forms section.
The application must also be compiled with debugging
enabled.

For example:

<configuration>
    <system.windows.forms jitDebugging="true" />
</configuration>

화상키보드를 찾아보면 위와 같이 했을 경우 CMD에서는 잘 실행이 되는 반면 프로그램에서 실행할 경우 위와 같은 에러를 만날 수 있다.

 

이유는 실행 프로젝트가 32비트, 64비트에 따라 해당 경로를 폴더를 변경해줘야 에러를 해결할 수 있다. 이건 프로그램마다 따로 컨트롤을 해줘야하기때문에 이럴 경우 아래의 방법처럼 해결된다.

 


 

실행 방법2 (추천)

//Global Variable
// 화상키보드 실행을 위한 Win32 API 정의
[DllImport("Shell32.dll", CharSet = CharSet.Auto, SetLastError = true)] static extern IntPtr ShellExecute(IntPtr hwnd, string lpOperation, string lpFile, string lpParameters, string lpDirectory, int nShowCmd);
[DllImport("kernel32.dll", SetLastError = true)] static extern bool Wow64DisableWow64FsRedirection(ref IntPtr ptr);
[DllImport("kernel32.dll", SetLastError = true)] static extern bool Wow64RevertWow64FsRedirection(IntPtr ptr);

/// <summary>
/// 화상 키보드 실행
/// </summary>
public static void oskStart()
{
    IntPtr llosng = IntPtr.Zero;
    
    //64 or 32비트 전환을 위한 함수
    Wow64DisableWow64FsRedirection(ref llosng);
    
    //외부 프로그램 실행을 위한 함수
    ShellExecute(This.handle, "open", Environment.SystemDirectory + "\\osk.exe", "", "", 4);
    
    //64 or 32비트 전환을 위한 함수
    Wow64RevertWow64FsRedirection(llosng);
}

 

 

 

Win32 API인 Shell32, Kernel32.Dll을 전역변수에 선언해준 후 화상키보드(OSK)를 실행시킬 부분에 oskStart()의 소스를 넣어주면 화상키보드가 실행되는 것을 확인 할 수 있다.

추가로 아래에선 실행한 osk 프로그램을 종료하는 방법에 대해 정리해보겠다.

 


 

화상프로그램(OSk) 종료 방법

/// <summary>
/// 화상키보드 종료
/// </summary>
public static void oskKill()
{
	System.Diagnostics.Process[] procs = System.Diagnostics.Process.GetProcessesByName("osk");
	for (int i = 0; i < procs.Length; i++)
	{
		procs[i].Kill();
	}
}

위 처럼 종료를 하고싶은 부분에서 해당 메서드를 실행시켜주면 된다.

 


 

실행 결과

위와 같은 화상키보드가 띄어지는 것을 확인할 수 있다.

댓글

💲 많이 본 글