Click을 사용하여 단일 인스턴스 응용 프로그램을 어떻게 구축 할 수 있습니까?

StackOverflow https://stackoverflow.com/questions/248721

  •  05-07-2019
  •  | 
  •  

문제

단일 인스턴스 응용 프로그램이 필요합니다 (이에 따라 대답), 그러나 클릭 한 번 클릭을 통해 배포해야합니다.

문제는 클릭 한 번 클릭이 응용 프로그램이 실행되는 동안 최신 버전을로드하려는 시도를 자동으로 감지하지 않아야한다는 것입니다. 실행중인 경우 다른 인스턴스를 활성화해야합니다. 일반적으로 한 번 클릭 한 번 링크를 선택할 때 가장 먼저하는 것은 업데이트를 찾는 것입니다. 나는 이것을 가로 채고 이미 실행중인 인스턴스를 확인하고 싶습니다. 이전의 일반 업데이트 프로세스를 시작합니다.

배포 시나리오가 한 번 클릭 한 내에 이것이 어떻게 가능한지 아는 사람이 있습니까?

도움이 되었습니까?

해결책

문제를 해결하기 위해 다음 두 가지 기능이있는 프로토 타입 응용 프로그램을 구축했습니다.

  1. 하나의 PC의 여러 인스턴스가 비활성화됩니다. 단일 인스턴스 응용 프로그램은 ClickOnce를 통해 배포됩니다. 사용자가 앱의 두 번째 인스턴스를 시작하려고하면 "다른 인스턴스가 이미 실행 중인다"는 메시지가 나타납니다.

  2. 업데이트를 비동기 적으로 확인하고 업데이트가 존재하는 경우 업데이트를 설치합니다. 사용자가 새 인스턴스를 실행할 때 사용 가능한 업데이트가 있으면 "업데이트 가능"이 팝업됩니다.

데모 응용 프로그램을 구축하는 프로세스는 다음과 같습니다.

1 단계 : MUTEX 클래스를 사용하여 활성 인스턴스 응용 프로그램을 감지합니다.

namespace ClickOnceDemo
{
    static class Program
    {
        /// summary>
        /// The main entry point for the application.
        /// /summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault( false );
            bool ok;
            var m = new System.Threading.Mutex( true, "Application", out ok );
            if ( !ok )
            {
                MessageBox.Show( "Another instance is already running.", ApplicationDeployment.CurrentDeployment.CurrentVersion.ToString() );
                return;
            }
           Application.Run( new UpdateProgress() );
        }
    }
}

2 단계 : 프로그래밍 방식으로 업데이트를 처리합니다

그렇게하기 전에 자동 클릭 업데이트 업데이트 확인을 비활성화해야합니다 (게시 - 업데이트 ... 대화 상자).

그런 다음 UpdateProgress 및 MainForm의 두 가지 형식을 만듭니다. 여기서 업데이트 프로그램은 다운로드 진행 상황을 나타내고 MainForm은 기본 응용 프로그램을 나타냅니다.

사용자가 애플리케이션을 실행하면 업데이트를 확인하여 업데이트를 확인합니다. 업데이트가 완료되면 MainForm이 시작되고 UpdateProgress가 숨겨집니다.

namespace ClickOnceDemo
{
public partial class UpdateProgress : Form
 {
  public UpdateProgress()
        {
            InitializeComponent();
            Text = "Checking for updates...";

            ApplicationDeployment ad = ApplicationDeployment.CurrentDeployment;
            ad.CheckForUpdateCompleted += OnCheckForUpdateCompleted;
            ad.CheckForUpdateProgressChanged += OnCheckForUpdateProgressChanged;

            ad.CheckForUpdateAsync();
       }

        private void OnCheckForUpdateProgressChanged(object sender, DeploymentProgressChangedEventArgs e)
        {
            lblStatus.Text = String.Format( "Downloading: {0}. {1:D}K of {2:D}K downloaded.", GetProgressString( e.State ), e.BytesCompleted / 1024, e.BytesTotal / 1024 );
            progressBar1.Value = e.ProgressPercentage;
        }

        string GetProgressString( DeploymentProgressState state )
        {
            if ( state == DeploymentProgressState.DownloadingApplicationFiles )
            {
                return "application files";
            }
            if ( state == DeploymentProgressState.DownloadingApplicationInformation )
            {
                return "application manifest";
            }
            return "deployment manifest";
        }

        private void OnCheckForUpdateCompleted(object sender, CheckForUpdateCompletedEventArgs e)
        {
            if ( e.Error != null )
            {
                MessageBox.Show( "ERROR: Could not retrieve new version of the application. Reason: \n" + e.Error.Message + "\nPlease report this error to the system administrator." );
                return;
            }
            if ( e.Cancelled )
            {
                MessageBox.Show( "The update was cancelled." );
            }

            // Ask the user if they would like to update the application now.
            if ( e.UpdateAvailable )
            {
                if ( !e.IsUpdateRequired )
                {
                    long updateSize = e.UpdateSizeBytes;
                    DialogResult dr = MessageBox.Show( string.Format("An update ({0}K) is available. Would you like to update the application now?", updateSize/1024), "Update Available", MessageBoxButtons.OKCancel );
                    if ( DialogResult.OK == dr )
                    {
                        BeginUpdate();
                    }
                }
                else
                {
                    MessageBox.Show( "A mandatory update is available for your application. We will install the update now, after which we will save all of your in-progress data and restart your application." );
                    BeginUpdate();
                }
            }
            else
            {
                ShowMainForm();
            }
        }

        // Show the main application form
        private void ShowMainForm()
        {
            MainForm mainForm = new MainForm ();
            mainForm.Show();
            Hide();
        }

        private void BeginUpdate()
        {
            Text = "Downloading update...";
            ApplicationDeployment ad = ApplicationDeployment.CurrentDeployment;
            ad.UpdateCompleted += ad_UpdateCompleted;
            ad.UpdateProgressChanged += ad_UpdateProgressChanged;

            ad.UpdateAsync();
        }

        void ad_UpdateProgressChanged( object sender, DeploymentProgressChangedEventArgs e )
        {
            String progressText = String.Format( "{0:D}K out of {1:D}K downloaded - {2:D}% complete", e.BytesCompleted / 1024, e.BytesTotal / 1024, e.ProgressPercentage );
            progressBar1.Value = e.ProgressPercentage;
            lblStatus.Text = progressText;
        }

        void ad_UpdateCompleted( object sender, AsyncCompletedEventArgs e )
        {
            if ( e.Cancelled )
            {
                MessageBox.Show( "The update of the application's latest version was cancelled." );
                return;
            }
            if ( e.Error != null )
            {
                MessageBox.Show( "ERROR: Could not install the latest version of the application. Reason: \n" + e.Error.Message + "\nPlease report this error to the system administrator." );
                return;
            }

            DialogResult dr = MessageBox.Show( "The application has been updated. Restart? (If you do not restart now, the new version will not take effect until after you quit and launch the application again.)", "Restart Application", MessageBoxButtons.OKCancel );
            if ( DialogResult.OK == dr )
            {
                Application.Restart();
            }
            else
            {
                ShowMainForm();
            }
        }
    }
}

응용 프로그램은 잘 작동하며 문제에 대한 좋은 해결책이되기를 바랍니다.
특별히 감사함 디모데 월터스 소스 코드를 제공합니다

다른 팁

확신하는 - 자동화를 비활성화 할 수 있습니다. ClickOnce 업데이트 확인 (게시 -> 업데이트 .. 대화 상자). System.Deployment.application 실용적으로 업데이트를 확인하는 네임 스페이스.

체크 아웃 :

업데이트가있는 경우 실제로 업데이트하기 전에 다음을 업데이트하기 전에 단일 인스턴스 응용 프로그램 확인을 수행 할 수 있습니다.

실행하기 전에 수표가 코드 외부에 있기 때문에 이렇게 할 수 있다고 생각하지 않습니다.

그러나 ClickOnce 배포 옵션을 변경하여 코드 실행 중에 업데이트를 확인할 수 있습니다.

더 많은 제어가 필요하면 ApplicationDeployment 업데이트 또는 업데이트를 확인 업데이트 프로세스에 대한 절대적인 방법.

나는 사용했다 http://wpfsingleinstance.codeplex.com/ 내 WPF에서 큰 성공을 거둔 ClickOnce 응용 프로그램. 나는 아무것도 바꿀 필요가 없었습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top