it-swarm-ko.tech

파일 확장명을 C #의 현재 실행 파일에 연결하는 방법

파일 확장명을 C #의 현재 실행 파일에 연결하고 싶습니다. 이렇게하면 사용자가 탐색기에서 파일을 클릭하면 주어진 파일을 첫 번째 인수로 사용하여 실행 파일을 실행합니다. 이상적으로는 주어진 파일 확장자의 아이콘을 내 실행 파일의 아이콘으로 설정하는 것이 이상적입니다. 모두 감사합니다.

52
Chris

파일 연결을 직접 관리하기위한 .Net API는 없지만 레지스트리 키를 사용하여 필요한 키를 읽고 쓸 수 있습니다.

HKEY_CLASSES_ROOT 아래에 파일 확장자로 이름이 설정된 키를 만들어야합니다 (예 : ".txt"). 이 키의 기본값을 "Acme.TextFile"과 같은 파일 형식의 고유 한 이름으로 설정하십시오. 그런 다음 이름이 "Acme.TextFile"로 설정된 HKEY_CLASSES_ROOT 아래에 다른 키를 작성하십시오. "DefaultIcon"이라는 하위 키를 추가하고 키의 기본값을이 파일 형식에 사용할 아이콘이 포함 된 파일로 설정하십시오. "쉘"이라는 다른 형제를 추가하십시오. "쉘 (Shell)"키 아래에 탐색기 상황에 맞는 메뉴를 통해 사용하려는 각 작업에 대한 키를 추가하여 각 키의 기본값을 실행 파일 경로로 설정하고 그 뒤에 공백을 표시하고 경로를 나타내는 "% 1"을 설정하십시오. 선택한 파일로.

예를 들어 다음은 .txt 파일과 엠 에디터 간의 연결을 만드는 샘플 레지스트리 파일입니다.

 Windows 레지스트리 편집기 버전 5.00 
 
 [HKEY_CLASSES_ROOT\.txt] 
 @ = "emeditor.txt"
 
 [HKEY_CLASSES_ROOT\emeditor.txt] 
 @ = "텍스트 문서"
 
 [HKEY_CLASSES_ROOT\emeditor.txt\DefaultIcon] 
 @ = "% SystemRoot % \\ SysWow64\\ imageres.dll, -102 "
 
 [HKEY_CLASSES_ROOT\emeditor.txt\Shell] 
 
 [HKEY_CLASSES_ROOT\emeditor.txt\Shell\open] 
 
 [HKEY_CLASSES_ROOT\emeditor.txt\Shell\open\command] 
 @ = "\"C : \\ Program Files \\ EmEditor \\ EMEDITOR.EXE\"\"% 1\""
 
 [HKEY_CLASSES_ROOT\emeditor.txt\Shell\print] 
 
 [HKEY_CLASSES_ROOT\emeditor.txt\Shell\print\command] 
 @ = "\"C : \\ Program Files \\ EmEditor \\ EMEDITOR.EXE\"/ p \"% 1\""
40
X-Cubed

또한 레지스트리를 사용하기로 결정한 경우 현재 사용자 연결은 HKEY_CURRENT_USER\Software\Classes에 있습니다. 로컬 머신 클래스 대신 애플리케이션을 추가하는 것이 좋습니다.

제한된 사용자가 프로그램을 실행하면 CLASSES_ROOT를 수정할 수 없습니다.

25
Ishmaeel

ClickOnce 배포를 사용하는 경우이 작업이 모두 처리됩니다 (적어도 VS2008 SP1에서). 간단히:

  • 프로젝트 속성
  • 게시
  • 옵션
  • 파일 어 소시 아톤
  • (필요한 것을 추가하십시오)

(완전 신뢰, 대상 .NET 3.5 여야하며 오프라인 사용을 위해 설정되어야 함)

MSDN 참조 : 방법 : ClickOnce 응용 프로그램의 파일 연결 만들기

12
Marc Gravell

다음은 완전한 예입니다.

public class FileAssociation
{
    public string Extension { get; set; }
    public string ProgId { get; set; }
    public string FileTypeDescription { get; set; }
    public string ExecutableFilePath { get; set; }
}

public class FileAssociations
{
    // needed so that Explorer windows get refreshed after the registry is updated
    [System.Runtime.InteropServices.DllImport("Shell32.dll")]
    private static extern int SHChangeNotify(int eventId, int flags, IntPtr item1, IntPtr item2);

    private const int SHCNE_ASSOCCHANGED = 0x8000000;
    private const int SHCNF_FLUSH = 0x1000;

    public static void EnsureAssociationsSet()
    {
        var filePath = Process.GetCurrentProcess().MainModule.FileName;
        EnsureAssociationsSet(
            new FileAssociation
            {
                Extension = ".binlog",
                ProgId = "MSBuildBinaryLog",
                FileTypeDescription = "MSBuild Binary Log",
                ExecutableFilePath = filePath
            },
            new FileAssociation
            {
                Extension = ".buildlog",
                ProgId = "MSBuildStructuredLog",
                FileTypeDescription = "MSBuild Structured Log",
                ExecutableFilePath = filePath
            });
    }

    public static void EnsureAssociationsSet(params FileAssociation[] associations)
    {
        bool madeChanges = false;
        foreach (var association in associations)
        {
            madeChanges |= SetAssociation(
                association.Extension,
                association.ProgId,
                association.FileTypeDescription,
                association.ExecutableFilePath);
        }

        if (madeChanges)
        {
            SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_FLUSH, IntPtr.Zero, IntPtr.Zero);
        }
    }

    public static bool SetAssociation(string extension, string progId, string fileTypeDescription, string applicationFilePath)
    {
        bool madeChanges = false;
        madeChanges |= SetKeyDefaultValue(@"Software\Classes\" + extension, progId);
        madeChanges |= SetKeyDefaultValue(@"Software\Classes\" + progId, fileTypeDescription);
        madeChanges |= SetKeyDefaultValue([email protected]"Software\Classes\{progId}\Shell\open\command", "\"" + applicationFilePath + "\" \"%1\"");
        return madeChanges;
    }

    private static bool SetKeyDefaultValue(string keyPath, string value)
    {
        using (var key = Registry.CurrentUser.CreateSubKey(keyPath))
        {
            if (key.GetValue(null) as string != value)
            {
                key.SetValue(null, value);
                return true;
            }
        }

        return false;
    }
9
Kirill Osenkov

프로젝트에 설치 패키지를 사용하지 않는 특정 이유가있을 수 있지만 설치 패키지는 파일 확장자 등록, 바탕 화면 바로 가기 추가 등과 같은 응용 프로그램 구성 작업을 쉽게 수행 할 수있는 좋은 장소입니다.

기본 제공 Visual Studio 설치 도구를 사용하여 파일 확장자 연결을 만드는 방법은 다음과 같습니다.

  1. 기존 C # 솔루션 내에서 새 프로젝트를 추가하고 프로젝트 유형을 Other Project Types-> Setup and Deployment-> Setup Project (또는 설정 마법사를 사용해보십시오)

  2. 설치 프로그램 구성 (도움이 필요한 경우 많은 기존 문서)

  3. 솔루션 탐색기에서 설정 프로젝트를 마우스 오른쪽 버튼으로 클릭하고 View-> File Types를 입력 한 다음 프로그램과 함께 등록 할 확장명을 추가하여 실행하십시오.

이 방법은 사용자가 응용 프로그램의 제거를 실행할 경우 자체적으로 정리하는 이점이 있습니다.

7
Paul J

"Windows 레지스트리"방식을 구체적으로 지정하려면 다음을 수행하십시오.

HKEY_CURRENT_USER\Software\Classes 아래에 키를 만듭니다 (Ishmaeel이 말한 것처럼)

x-Cubed의 답변을 따르십시오.

샘플 코드는 다음과 같습니다.

private void Create_abc_FileAssociation()
{
    /***********************************/
    /**** Key1: Create ".abc" entry ****/
    /***********************************/
    Microsoft.Win32.RegistryKey key1 = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("Software", true);

    key1.CreateSubKey("Classes");
    key1 = key1.OpenSubKey("Classes", true);

    key1.CreateSubKey(".abc");
    key1 = key1.OpenSubKey(".abc", true);
    key1.SetValue("", "DemoKeyValue"); // Set default key value

    key1.Close();

    /*******************************************************/
    /**** Key2: Create "DemoKeyValue\DefaultIcon" entry ****/
    /*******************************************************/
    Microsoft.Win32.RegistryKey key2 = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("Software", true);

    key2.CreateSubKey("Classes");
    key2 = key2.OpenSubKey("Classes", true);

    key2.CreateSubKey("DemoKeyValue");
    key2 = key2.OpenSubKey("DemoKeyValue", true);

    key2.CreateSubKey("DefaultIcon");
    key2 = key2.OpenSubKey("DefaultIcon", true);
    key2.SetValue("", "\"" + "(The icon path you desire)" + "\""); // Set default key value

    key2.Close();

    /**************************************************************/
    /**** Key3: Create "DemoKeyValue\Shell\open\command" entry ****/
    /**************************************************************/
    Microsoft.Win32.RegistryKey key3 = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("Software", true);

    key3.CreateSubKey("Classes");
    key3 = key3.OpenSubKey("Classes", true);

    key3.CreateSubKey("DemoKeyValue");
    key3 = key3.OpenSubKey("DemoKeyValue", true);

    key3.CreateSubKey("Shell");
    key3 = key3.OpenSubKey("Shell", true);

    key3.CreateSubKey("open");
    key3 = key3.OpenSubKey("open", true);

    key3.CreateSubKey("command");
    key3 = key3.OpenSubKey("command", true);
    key3.SetValue("", "\"" + "(The application path you desire)" + "\"" + " \"%1\""); // Set default key value

    key3.Close();
}

이해하기 쉬운 간단한 데모를 보여주세요. 이러한 키 값을 수정할 수 있으며 모든 것이 좋습니다.

5
Strong

파일 연관은 HKEY_CLASSES_ROOT의 레지스트리에 정의되어 있습니다.

VB.NET 예제가 있습니다. here C #으로 쉽게 이식 할 수 있습니다.

2
Steve Morgan

아래 코드는 작동해야하는 함수이며 Windows 레지스트리에 필요한 값을 추가합니다. 일반적으로 실행 파일에서 SelfCreateAssociation ( ". abc")을 실행합니다. (폼 생성자 또는 onload 또는 onshown) 실행 파일이 실행될 때마다 현재 사용자의 레지스트리 항목을 업데이트합니다. (변경 사항이 있으면 디버깅에 좋습니다). 관련된 레지스트리 키에 대한 자세한 정보가 필요하면이 MSDN 링크를 확인하십시오.

https://msdn.Microsoft.com/en-us/library/windows/desktop/dd758090 (v = vs.85) .aspx

일반 ClassesRoot 레지스트리 키에 대한 자세한 정보를 얻으려면 이 MSDN 기사를 참조하십시오.

https://msdn.Microsoft.com/en-us/library/windows/desktop/ms724475 (v = vs.85) .aspx

public enum KeyHiveSmall
{
    ClassesRoot,
    CurrentUser,
    LocalMachine,
}

/// <summary>
/// Create an associaten for a file extension in the windows registry
/// CreateAssociation(@"vendor.application",".tmf","Tool file",@"C:\Windows\SYSWOW64\notepad.exe",@"%SystemRoot%\SYSWOW64\notepad.exe,0");
/// </summary>
/// <param name="ProgID">e.g. vendor.application</param>
/// <param name="extension">e.g. .tmf</param>
/// <param name="description">e.g. Tool file</param>
/// <param name="application">e.g.  @"C:\Windows\SYSWOW64\notepad.exe"</param>
/// <param name="icon">@"%SystemRoot%\SYSWOW64\notepad.exe,0"</param>
/// <param name="Hive">e.g. The user-specific settings have priority over the computer settings. KeyHive.LocalMachine  need admin rights</param>
public static void CreateAssociation(string ProgID, string extension, string description, string application, string icon, KeyHiveSmall Hive = KeyHiveSmall.CurrentUser)
{
    RegistryKey selectedKey = null;

    switch (Hive)
    {
        case KeyHiveSmall.ClassesRoot:
            Microsoft.Win32.Registry.ClassesRoot.CreateSubKey(extension).SetValue("", ProgID);
            selectedKey = Microsoft.Win32.Registry.ClassesRoot.CreateSubKey(ProgID);
            break;

        case KeyHiveSmall.CurrentUser:
            Microsoft.Win32.Registry.CurrentUser.CreateSubKey(@"Software\Classes\" + extension).SetValue("", ProgID);
            selectedKey = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(@"Software\Classes\" + ProgID);
            break;

        case KeyHiveSmall.LocalMachine:
            Microsoft.Win32.Registry.LocalMachine.CreateSubKey(@"Software\Classes\" + extension).SetValue("", ProgID);
            selectedKey = Microsoft.Win32.Registry.LocalMachine.CreateSubKey(@"Software\Classes\" + ProgID);
            break;
    }

    if (selectedKey != null)
    {
        if (description != null)
        {
            selectedKey.SetValue("", description);
        }
        if (icon != null)
        {
            selectedKey.CreateSubKey("DefaultIcon").SetValue("", icon, RegistryValueKind.ExpandString);
            selectedKey.CreateSubKey(@"Shell\Open").SetValue("icon", icon, RegistryValueKind.ExpandString);
        }
        if (application != null)
        {
            selectedKey.CreateSubKey(@"Shell\Open\command").SetValue("", "\"" + application + "\"" + " \"%1\"", RegistryValueKind.ExpandString);
        }
    }
    selectedKey.Flush();
    selectedKey.Close();
}

 /// <summary>
    /// Creates a association for current running executable
    /// </summary>
    /// <param name="extension">e.g. .tmf</param>
    /// <param name="Hive">e.g. KeyHive.LocalMachine need admin rights</param>
    /// <param name="description">e.g. Tool file. Displayed in Explorer</param>
    public static void SelfCreateAssociation(string extension, KeyHiveSmall Hive = KeyHiveSmall.CurrentUser, string description = "")
    {
        string ProgID = System.Reflection.Assembly.GetExecutingAssembly().EntryPoint.DeclaringType.FullName;
        string FileLocation = System.Reflection.Assembly.GetExecutingAssembly().Location;
        CreateAssociation(ProgID, extension, description, FileLocation, FileLocation + ",0", Hive);
    }
2
Carsten R.

간단한 파일 연결을 쉽게 만들 수 있도록 Windows 7 이후로 사용되었던 두 가지 cmd 도구가 있습니다. assocftype 입니다. 각 명령에 대한 기본 설명은 다음과 같습니다.

  • Assoc -파일 확장자 (예 : '.txt')를 "파일 형식"과 연결합니다.
  • FType -사용자가 지정된 "파일 형식"을 열 때 실행할 실행 파일을 정의합니다.

이들은 cmd 도구이며 실행 파일이 아닙니다 (exe). 이는 cmd 창에서만 또는 "cmd/c assoc"과 함께 ShellExecute를 사용하여 실행할 수 있음을 의미합니다. 링크에서 또는 "assoc /?"를 입력하여 이에 대해 자세히 알아볼 수 있습니다. "ftype /?" cmd 프롬프트에서.

따라서 응용 프로그램을 .bob 확장명과 연결하려면 cmd 창 (WindowKey + R, cmd를 입력하고 Enter 키를 누름)을 열고 다음을 실행하십시오.

assoc .bob=BobFile
ftype BobFile=c:\temp\BobView.exe "%1"

이것은 레지스트리를 망쳐 놓는 것보다 훨씬 간단하며 향후 Windows 버전에서 작동 할 가능성이 큽니다.

정리하면 다음은 파일 연결을 만드는 C # 함수입니다.

public static int setFileAssociation(string[] extensions, string fileType, string openCommandString) {
    int v = execute("cmd", "/c ftype " + fileType + "=" + openCommandString);
    foreach (string ext in extensions) {
        v = execute("cmd", "/c assoc " + ext + "=" + fileType);
        if (v != 0) return v;
    }
    return v;
}
public static int execute(string exeFilename, string arguments) {
    ProcessStartInfo startInfo = new ProcessStartInfo();
    startInfo.CreateNoWindow = false;
    startInfo.UseShellExecute = true;
    startInfo.FileName = exeFilename;
    startInfo.WindowStyle = ProcessWindowStyle.Hidden;
    startInfo.Arguments = arguments;
    try {
        using (Process exeProcess = Process.Start(startInfo)) {
            exeProcess.WaitForExit();
            return exeProcess.ExitCode;
        }
    } catch {
        return 1;
    }
}
0
Mike